删除原来的 transfer-select

This commit is contained in:
2betop 2020-05-14 11:33:18 +08:00
parent 50b4adcf9d
commit 1f7a20a988
8 changed files with 6 additions and 588 deletions

View File

@ -1,120 +0,0 @@
.#{$ns}TransferSelectControl {
display: flex;
height: px2rem(300px);
.#{$ns}TransferSelect {
&-allOptions,
&-selectedOptions {
height: 100%;
flex: 1;
border: $borderWidth solid $borderColor;
overflow: auto;
.#{$ns}TransferSelect-heading {
position: relative;
height: px2rem(40px);
line-height: px2rem(40px);
padding-left: px2rem(20px);
border-bottom: $TransferSelect-heading-borderBottom;
}
.#{$ns}TransferSelect-body {
table tbody tr td,
ul li {
position: relative;
}
ul {
margin: 0;
padding: 0;
padding-top: px2rem(10px);
}
li {
height: px2rem(30px);
line-height: px2rem(30px);
list-style: none;
padding-left: px2rem(20px);
}
}
.#{$ns}TransferSelect-selectAll,
.#{$ns}TransferSelect-clearAll {
position: absolute;
right: 20px;
cursor: pointer;
color: $primary;
}
.#{$ns}TransferSelect-searchWrapper {
i {
height: px2rem(17px);
line-height: px2rem(17px);
}
}
}
&-allOptions {
&--table {
.#{$ns}TransferSelect-heading {
background-color: $TransferSelect--table-heading-bg;
display: flex;
}
.#{$ns}TransferSelect-searchWrapper {
display: inline-block;
padding: px2rem(3px) px2rem(10px);
flex: 1;
margin-left: px2rem(30px);
}
}
&--normal {
.#{$ns}TransferSelect-heading {
background-color: $TransferSelect--normal-heading-bg;
}
.#{$ns}TransferSelect-searchWrapper {
padding: px2rem(10px) px2rem(20px);
}
}
}
&-selectedOptions {
&--table {
.#{$ns}TransferSelect-heading {
background-color: $TransferSelect--table-heading-bg;
}
}
&--normal {
.#{$ns}TransferSelect-heading {
background-color: $TransferSelect--normal-heading-bg;
}
}
}
&-option-close {
width: px2rem(12px);
height: px2rem(12px);
position: absolute;
right: px2rem(20px);
cursor: pointer;
}
&-action {
padding: 0 px2rem(20px);
.#{$ns}TransferSelect-actionIcon {
display: inline-block;
width: 0;
height: 0;
border-top: px2rem(12px) solid transparent;
border-left: px2rem(12px) solid #b7b7b7;
border-bottom: px2rem(12px) solid transparent;
position: relative;
top: calc(50% - 6px);
}
}
}
}

View File

@ -75,4 +75,8 @@
.#{$ns}TransferControl {
position: relative;
&.is-inline {
display: inline-block;
}
}

View File

@ -573,7 +573,6 @@ $Combo--horizontal-dragger-top: px2rem(5px);
@import '../components/form/tag';
@import '../components/form/rating';
@import '../components/form/transfer';
@import '../components/form/transfer-select';
@import '../components/form/nested-select';
@import '../components/form/icon-picker';
@import '../components/form/form';

View File

@ -236,7 +236,6 @@ pre {
@import '../components/form/tag';
@import '../components/form/rating';
@import '../components/form/transfer';
@import '../components/form/transfer-select';
@import '../components/form/nested-select';
@import '../components/form/icon-picker';
@import '../components/form/form';

View File

@ -101,7 +101,6 @@ $Form-input-borderColor: #cfdadd;
@import '../components/form/tag';
@import '../components/form/rating';
@import '../components/form/transfer';
@import '../components/form/transfer-select';
@import '../components/form/nested-select';
@import '../components/form/icon-picker';
@import '../components/form/form';

View File

@ -87,7 +87,6 @@ import './renderers/Form/Color';
import './renderers/Form/ChainedSelect';
import './renderers/Form/NestedSelect';
import './renderers/Form/Transfer';
import './renderers/Form/TransferSelect';
import './renderers/Form/Service';
import './renderers/Form/Table';
import './renderers/Form/Picker';

View File

@ -138,6 +138,7 @@ export class TransferRenderer extends React.Component<TransferProps> {
render() {
const {
className,
classnames: cx,
options,
selectedOptions,
@ -150,7 +151,7 @@ export class TransferRenderer extends React.Component<TransferProps> {
} = this.props;
return (
<div className={cx('TransferControl')}>
<div className={cx('TransferControl', className)}>
<Transfer
value={selectedOptions}
options={options}

View File

@ -1,463 +0,0 @@
import React from 'react';
import {OptionsControl, OptionsControlProps, Option} from './Options';
import {xorBy, find} from 'lodash';
import Checkbox from '../../components/Checkbox';
import {closeIcon, Icon} from '../../components/icons';
import {Spinner} from '../../components';
export interface TransferSelectProps extends OptionsControlProps {
viewMode?: 'table' | 'normal';
labelField: string;
valueField: string;
searchField: string;
searchPlaceholder: string;
columns: Array<any>;
allTitle: string;
selectedTitle: string;
searchable: boolean;
}
export interface TransferSelectState {
filteredOptions: Array<Option>;
keyword: string;
}
export class TransferSelect extends React.Component<
TransferSelectProps,
TransferSelectState
> {
static defaultProps = {
viewMode: 'normal',
multiple: true,
labelField: 'label',
valueField: 'value',
searchField: 'label',
searchPlaceholder: '请输入关键字',
allTitle: '全部',
selectedTitle: '已选',
columns: [],
searchable: true
};
constructor(props: TransferSelectProps) {
super(props);
this.state = {
filteredOptions: [],
keyword: ''
};
this.handleCheckAll = this.handleCheckAll.bind(this);
this.handleClear = this.handleClear.bind(this);
this.handleSearch = this.handleSearch.bind(this);
}
componentDidMount() {
const {options} = this.props;
if (options && Array.isArray(options)) {
this.setState({
filteredOptions: options
});
}
}
componentDidUpdate(prevProps: TransferSelectProps) {
const {options} = this.props;
if (options && prevProps.options !== options) {
this.setState({
filteredOptions: options,
keyword: ''
});
}
}
handleCheck(checkedItem: Option | any) {
const {
selectedOptions,
onChange,
joinValues,
extractValue,
delimiter,
valueField
} = this.props;
let newValue: any =
selectedOptions.length === 0
? [checkedItem]
: xorBy(selectedOptions.concat(), [checkedItem], valueField || 'value');
if (joinValues) {
newValue = newValue
.map((item: any) => item[valueField || 'value'])
.join(delimiter || ',');
} else if (extractValue) {
newValue = newValue.map((item: any) => item[valueField || 'value']);
}
onChange(newValue);
}
handleCheckAll() {
const {filteredOptions} = this.state;
const {
selectedOptions,
onChange,
joinValues,
extractValue,
delimiter,
valueField
} = this.props;
let newValue;
if (selectedOptions.length === filteredOptions.length) {
newValue = '';
} else {
newValue = joinValues
? filteredOptions
.map((item: any) => item[valueField || 'value'])
.join(delimiter || '')
: extractValue
? filteredOptions.map((item: any) => item[valueField || 'value'])
: filteredOptions;
}
onChange(newValue);
}
handleClear() {
this.props.onChange('');
}
handleSearch(e: React.ChangeEvent<HTMLInputElement>) {
const {viewMode, searchField, options} = this.props;
let newOptions = [];
const keyword = e.target.value.toLowerCase();
if (keyword === '') {
newOptions = options;
} else {
newOptions = options.filter((option: Option) => {
return (
(option[viewMode === 'table' ? searchField : 'label'] as string)
.toLowerCase()
.indexOf(keyword) > -1
);
});
}
this.setState({
filteredOptions: newOptions,
keyword
});
}
reload() {
const reload = this.props.reloadOptions;
reload && reload();
}
renderTable() {
const {filteredOptions} = this.state;
const {
classnames: cx,
classPrefix: ns,
selectedOptions,
columns,
allTitle,
searchable,
searchPlaceholder,
valueField
} = this.props;
return (
<div
className={cx(
'TransferSelect-allOptions',
'TransferSelect-allOptions--table'
)}
>
<div className={cx('TransferSelect-heading')}>
<span>{`${allTitle}${selectedOptions.length}/${
filteredOptions.length
}`}</span>
{searchable ? (
<div className={cx('TransferSelect-searchWrapper')}>
<div className={cx('TextControl-input')}>
<input
placeholder={searchPlaceholder}
autoComplete="off"
size={10}
value={this.state.keyword}
onChange={this.handleSearch}
/>
<i className="fa fa-search" />
</div>
</div>
) : null}
</div>
<div className={cx('TransferSelect-body')}>
<table className={cx('Table-table')}>
<thead>
<tr>
<th className={cx('Table-checkCell')}>
<Checkbox
classPrefix={ns}
partial={selectedOptions.length !== filteredOptions.length}
checked={selectedOptions.length > 0}
onChange={this.handleCheckAll}
/>
</th>
{columns.map((column: any, columnIndex: number) => (
<th key={columnIndex}>{column.label}</th>
))}
</tr>
</thead>
<tbody>
{filteredOptions.map((option, optionIndex) => (
<tr
className={cx({
[`${ns}Table-tr--odd`]: optionIndex % 2 === 0,
[`${ns}Table-tr--even`]: optionIndex % 2 === 1
})}
key={optionIndex}
>
<td>
<Checkbox
classPrefix={ns}
value={false}
checked={find(selectedOptions, (selectedOption: any) => {
return (
selectedOption[valueField || 'value'] ===
option[valueField || 'value']
);
})}
onChange={this.handleCheck.bind(this, option)}
/>
</td>
{columns.map((column: any, columnIndex: number) => {
let text = option[column.name] + '';
return <td key={columnIndex}>{text}</td>;
})}
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}
renderNormal() {
const {filteredOptions} = this.state;
const {
classnames: cx,
classPrefix: ns,
selectedOptions,
allTitle,
searchable,
searchPlaceholder,
labelField,
valueField
} = this.props;
return (
<div
className={cx(
'TransferSelect-allOptions',
'TransferSelect-allOptions--normal'
)}
>
<div className={cx('TransferSelect-heading')}>
<span>{`${allTitle}${selectedOptions.length}/${
filteredOptions.length
}`}</span>
{selectedOptions.length < filteredOptions.length ? (
<span
onClick={this.handleCheckAll}
className={cx('TransferSelect-selectAll')}
>
</span>
) : null}
</div>
<div className={cx('TransferSelect-body')}>
{searchable ? (
<div className={cx('TransferSelect-searchWrapper')}>
<div className={cx('TextControl-input')}>
<input
placeholder={searchPlaceholder}
autoComplete="off"
size={10}
onChange={this.handleSearch}
/>
<i className="fa fa-search" />
</div>
</div>
) : null}
<ul>
{filteredOptions.length > 0 ? (
filteredOptions.map((option: any, optionIndex: number) => (
<li key={optionIndex}>
<Checkbox
classPrefix={ns}
checked={
!!find(selectedOptions, (selectedOption: any) => {
return (
selectedOption[valueField || 'value'] ===
option[valueField || 'value']
);
})
}
onChange={this.handleCheck.bind(this, option)}
>
{option[labelField || 'label']}
</Checkbox>
</li>
))
) : (
<li></li>
)}
</ul>
</div>
</div>
);
}
renderAction() {
const {classnames: cx} = this.props;
return (
<div className={cx('TransferSelect-action')}>
<span className={cx('TransferSelect-actionIcon')} />
</div>
);
}
renderTableSelectedOptions() {
const {
classnames: cx,
selectedOptions,
selectedTitle,
labelField,
columns
} = this.props;
return (
<div
className={cx(
'TransferSelect-selectedOptions',
'TransferSelect-selectedOptions--table'
)}
>
<div className={cx('TransferSelect-heading')}>
<span>{`${selectedTitle}${selectedOptions.length}`}</span>
{selectedOptions.length > 0 ? (
<span
onClick={this.handleClear}
className={cx('TransferSelect-clearAll')}
>
</span>
) : null}
</div>
<div className={cx('TransferSelect-body')}>
<table className={cx('Table-table')}>
<thead>
<tr>
<th>
{find(columns, column => column.name === labelField).label}
</th>
</tr>
</thead>
<tbody>
{selectedOptions.map((option: Option, optionIndex: number) => (
<tr className={cx('Table-tr--odd')} key={optionIndex}>
<td>
{option[labelField || 'label']}
<a
onClick={this.handleCheck.bind(this, option)}
className={cx('TransferSelect-option-close')}
>
<Icon icon="close" className="icon" />
</a>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}
renderNormalSelectedOptions() {
const {
classnames: cx,
selectedOptions,
selectedTitle,
labelField
} = this.props;
return (
<div
className={cx(
'TransferSelect-selectedOptions',
'TransferSelect-selectedOptions--normal'
)}
>
<div className={cx('TransferSelect-heading')}>
<span>{`${selectedTitle}${selectedOptions.length}`}</span>
{selectedOptions.length > 0 ? (
<span
onClick={this.handleClear}
className={cx('TransferSelect-clearAll')}
>
</span>
) : null}
</div>
<div className={cx('TransferSelect-body')}>
<ul>
{selectedOptions.map((option: any, optionIndex: number) => (
<li key={optionIndex}>
{option[labelField || 'label']}
<a
onClick={this.handleCheck.bind(this, option)}
className={cx('TransferSelect-option-close')}
>
{closeIcon}
</a>
</li>
))}
</ul>
</div>
</div>
);
}
render() {
const {className, classnames: cx, render, viewMode, loading} = this.props;
return (
<div className={cx('TransferSelectControl', className)}>
{viewMode === 'table' ? this.renderTable() : this.renderNormal()}
{this.renderAction()}
{viewMode === 'table'
? this.renderTableSelectedOptions()
: this.renderNormalSelectedOptions()}
<Spinner size="lg" overlay key="info" show={loading} />
</div>
);
}
}
@OptionsControl({
type: 'transfer-select'
})
export class TransferSelectControlRenderer extends TransferSelect {}