fix: select组件table选择模式下无法点选问题 (#4477)

This commit is contained in:
RUNZE LU 2022-05-27 18:30:59 +08:00 committed by GitHub
parent 5d5b671bc4
commit a193938bbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 98 additions and 58 deletions

View File

@ -214,4 +214,4 @@ test('EventAction:drawer', async () => {
expect(container.querySelector('[role="dialog"]')).not.toBeInTheDocument(); expect(container.querySelector('[role="dialog"]')).not.toBeInTheDocument();
}); });
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();
}); }, 7000);

View File

@ -959,11 +959,40 @@ exports[`Renderer:select table with labelField & valueField 1`] = `
style="position: relative;" style="position: relative;"
tabindex="-1" tabindex="-1"
> >
<span <div
class="cxd-ResultBox-placeholder" class="cxd-ResultBox-value"
> >
请选择 <span
</span> class="cxd-ResultBox-valueLabel"
>
诸葛亮
</span>
<a
data-index="0"
>
<icon-mock
classname="icon icon-close"
icon="close"
/>
</a>
</div>
<div
class="cxd-ResultBox-value"
>
<span
class="cxd-ResultBox-valueLabel"
>
李白
</span>
<a
data-index="1"
>
<icon-mock
classname="icon icon-close"
icon="close"
/>
</a>
</div>
<span <span
class="cxd-TransferDropDown-icon" class="cxd-TransferDropDown-icon"
> >
@ -1038,7 +1067,7 @@ exports[`Renderer:select table with labelField & valueField 1`] = `
class="cxd-Table-checkCell" class="cxd-Table-checkCell"
> >
<label <label
class="cxd-Checkbox cxd-Checkbox--checkbox cxd-Checkbox--full cxd-Checkbox--sm" class="cxd-Checkbox cxd-Checkbox--checkbox cxd-Checkbox--sm"
> >
<input <input
type="checkbox" type="checkbox"
@ -1059,7 +1088,7 @@ exports[`Renderer:select table with labelField & valueField 1`] = `
</thead> </thead>
<tbody> <tbody>
<tr <tr
class="" class="is-active"
> >
<td <td
class="cxd-Table-checkCell" class="cxd-Table-checkCell"
@ -1146,7 +1175,7 @@ exports[`Renderer:select table with labelField & valueField 1`] = `
</td> </td>
</tr> </tr>
<tr <tr
class="" class="is-active"
> >
<td <td
class="cxd-Table-checkCell" class="cxd-Table-checkCell"
@ -1340,7 +1369,11 @@ exports[`Renderer:select table with labelField & valueField 1`] = `
</div> </div>
`; `;
exports[`Renderer:select table with labelField & valueField 2`] = `Object {}`; exports[`Renderer:select table with labelField & valueField 2`] = `
Object {
"a": "zhugeliang,libai",
}
`;
exports[`Renderer:select tree 1`] = ` exports[`Renderer:select tree 1`] = `
<div> <div>

View File

@ -46,7 +46,6 @@
user-select: none; user-select: none;
padding: var(--gap-xs) 0; padding: var(--gap-xs) 0;
&-group > &-itemLabel { &-group > &-itemLabel {
padding: var(--gap-xs) var(--gap-base); padding: var(--gap-xs) var(--gap-base);
color: var(--FileControl-icon-color); color: var(--FileControl-icon-color);
@ -78,10 +77,10 @@
&:hover { &:hover {
background: var(--Tree-item-onHover-bg); background: var(--Tree-item-onHover-bg);
i { i {
border: 1px solid var(--menu-active-color); border: 1px solid var(--menu-active-color);
} }
} }
&.is-disabled { &.is-disabled {
@ -117,6 +116,10 @@
border-top: var(--Table-borderWidth) solid var(--Table-borderColor); border-top: var(--Table-borderWidth) solid var(--Table-borderColor);
} }
.#{$ns}Table-table > tbody > tr {
cursor: pointer;
}
.#{$ns}Table-table > thead > tr > th, .#{$ns}Table-table > thead > tr > th,
.#{$ns}Table-table > tbody > tr > td { .#{$ns}Table-table > tbody > tr > td {
font-size: var(--fontSizeSm); font-size: var(--fontSizeSm);
@ -347,4 +350,4 @@
float: right; float: right;
cursor: pointer; cursor: pointer;
} }
} }

View File

@ -124,8 +124,6 @@
} }
} }
.#{$ns}Toast { .#{$ns}Toast {
.#{$ns}Toast-icon { .#{$ns}Toast-icon {
margin-right: #{px2rem(8px)}; margin-right: #{px2rem(8px)};

View File

@ -43,7 +43,10 @@ export interface ResultTableSelectionState {
searchTableOptions: Options; searchTableOptions: Options;
} }
export class BaseResultTableSelection extends BaseSelection<ResultTableSelectionProps, ResultTableSelectionState> { export class BaseResultTableSelection extends BaseSelection<
ResultTableSelectionProps,
ResultTableSelectionState
> {
static defaultProps = { static defaultProps = {
...BaseSelection.defaultProps, ...BaseSelection.defaultProps,
cellRender: ( cellRender: (
@ -55,25 +58,21 @@ export class BaseResultTableSelection extends BaseSelection<ResultTableSelection
option: Option, option: Option,
colIndex: number, colIndex: number,
rowIndex: number rowIndex: number
) => <span>{resolveVariable(column.name, option)}</span>, ) => <span>{resolveVariable(column.name, option)}</span>
}; };
state: ResultTableSelectionState = { state: ResultTableSelectionState = {
tableOptions: [], tableOptions: [],
searching: false, searching: false,
searchTableOptions: [] searchTableOptions: []
} };
static getDerivedStateFromProps(props: ResultTableSelectionProps) { static getDerivedStateFromProps(props: ResultTableSelectionProps) {
const { const {options, value, option2value} = props;
options,
value,
option2value,
} = props;
const valueArray = BaseSelection.value2array(value, options, option2value); const valueArray = BaseSelection.value2array(value, options, option2value);
return { return {
tableOptions: valueArray tableOptions: valueArray
} };
} }
@autobind @autobind
@ -117,15 +116,16 @@ export class BaseResultTableSelection extends BaseSelection<ResultTableSelection
} }
const {value, onSearch} = this.props; const {value, onSearch} = this.props;
const searchOptions = ((value || []) as Options) const searchOptions = ((value || []) as Options).filter(item =>
.filter(item => onSearch?.(inputValue, item)); onSearch?.(inputValue, item)
);
this.setState({ this.setState({
searching: true, searching: true,
searchTableOptions: searchOptions searchTableOptions: searchOptions
}); });
} }
@autobind @autobind
clearSearch() { clearSearch() {
this.setState({ this.setState({
@ -152,9 +152,7 @@ export class BaseResultTableSelection extends BaseSelection<ResultTableSelection
return ( return (
<div className={cx('ResultTableList', className)}> <div className={cx('ResultTableList', className)}>
{ {Array.isArray(value) && value.length ? (
Array.isArray(value) && value.length ?
(
<TableSelection <TableSelection
columns={columns} columns={columns}
options={!searching ? tableOptions : searchTableOptions} options={!searching ? tableOptions : searchTableOptions}
@ -163,6 +161,7 @@ export class BaseResultTableSelection extends BaseSelection<ResultTableSelection
option2value={option2value} option2value={option2value}
onChange={onChange} onChange={onChange}
multiple={false} multiple={false}
resultMode={true}
cellRender={( cellRender={(
column: { column: {
name: string; name: string;
@ -176,27 +175,28 @@ export class BaseResultTableSelection extends BaseSelection<ResultTableSelection
const raw = cellRender(column, option, colIndex, rowIndex); const raw = cellRender(column, option, colIndex, rowIndex);
if (colIndex === columns.length - 1) { if (colIndex === columns.length - 1) {
return ( return (
<> <>
{raw} {raw}
{ {
<span <span
className={cx('ResultTableList-close-btn')} className={cx('ResultTableList-close-btn')}
onClick={(e: React.SyntheticEvent<HTMLElement>) => { onClick={(e: React.SyntheticEvent<HTMLElement>) => {
e.stopPropagation(); e.stopPropagation();
this.handleCloseItem(option); this.handleCloseItem(option);
}} }}
> >
<CloseIcon /> <CloseIcon />
</span> </span>
} }
</>) </>
);
} }
return raw; return raw;
}} }}
/> />
) ) : (
: (<div className={cx('Selections-placeholder')}>{__(placeholder)}</div>) <div className={cx('Selections-placeholder')}>{__(placeholder)}</div>
} )}
</div> </div>
); );
} }
@ -211,7 +211,6 @@ export class BaseResultTableSelection extends BaseSelection<ResultTableSelection
placeholder = __('Transfer.searchKeyword') placeholder = __('Transfer.searchKeyword')
} = this.props; } = this.props;
return ( return (
<div className={cx('Selections', className)}> <div className={cx('Selections', className)}>
{title ? <div className={cx('Selections-title')}>{title}</div> : null} {title ? <div className={cx('Selections-title')}>{title}</div> : null}

View File

@ -5,9 +5,12 @@ import {uncontrollable} from 'uncontrollable';
import Checkbox from './Checkbox'; import Checkbox from './Checkbox';
import {Option} from './Select'; import {Option} from './Select';
import {resolveVariable} from '../utils/tpl-builtin'; import {resolveVariable} from '../utils/tpl-builtin';
import {noop} from '../utils/helper';
import {localeable} from '../locale'; import {localeable} from '../locale';
export interface TableSelectionProps extends BaseSelectionProps { export interface TableSelectionProps extends BaseSelectionProps {
/** 是否为结果渲染列表 */
resultMode?: boolean;
columns: Array<{ columns: Array<{
name: string; name: string;
label: string; label: string;
@ -108,7 +111,8 @@ export class TableSelection extends BaseSelection<TableSelectionProps> {
multiple, multiple,
option2value, option2value,
translate: __, translate: __,
itemClassName itemClassName,
resultMode
} = this.props; } = this.props;
const columns = this.getColumns(); const columns = this.getColumns();
let valueArray = BaseSelection.value2array(value, options, option2value); let valueArray = BaseSelection.value2array(value, options, option2value);
@ -122,6 +126,12 @@ export class TableSelection extends BaseSelection<TableSelectionProps> {
return ( return (
<tr <tr
key={rowIndex} key={rowIndex}
/** 被ResultTableList引用如果设置click事件会导致错误删除结果列表的内容先加一个开关判断 */
onClick={
resultMode
? noop
: e => e.defaultPrevented || this.toggleOption(option)
}
className={cx( className={cx(
itemClassName, itemClassName,
option.className, option.className,
@ -130,18 +140,15 @@ export class TableSelection extends BaseSelection<TableSelectionProps> {
)} )}
> >
{multiple ? ( {multiple ? (
<td className={cx('Table-checkCell')} <td
className={cx('Table-checkCell')}
key="checkbox" key="checkbox"
onClick={e => { onClick={e => {
e.stopPropagation(); e.stopPropagation();
this.toggleOption(option); this.toggleOption(option);
}} }}
> >
<Checkbox <Checkbox size="sm" checked={checked} disabled={disabled} />
size="sm"
checked={checked}
disabled={disabled}
/>
</td> </td>
) : null} ) : null}
{columns.map((column, colIndex) => ( {columns.map((column, colIndex) => (
@ -183,4 +190,4 @@ export default themeable(
value: 'onChange' value: 'onChange'
}) })
) )
); );