mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-01 11:28:30 +08:00
优化 checkboxes
This commit is contained in:
parent
25075b2298
commit
9100907de2
@ -2,6 +2,7 @@
|
|||||||
margin: 0 $gap-sm 0 0;
|
margin: 0 $gap-sm 0 0;
|
||||||
font-weight: $fontWeightNormal;
|
font-weight: $fontWeightNormal;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@ -20,8 +21,10 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
pointer-events: all;
|
||||||
|
|
||||||
+ span {
|
+ span {
|
||||||
|
pointer-events: all;
|
||||||
margin-left: $Checkbox-gap;
|
margin-left: $Checkbox-gap;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@ -230,6 +233,7 @@
|
|||||||
color: $text--muted-color;
|
color: $text--muted-color;
|
||||||
margin-left: $Checkbox-gap;
|
margin-left: $Checkbox-gap;
|
||||||
margin-top: $gap-xs;
|
margin-top: $gap-xs;
|
||||||
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +278,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.#{$ns}Checkboxes {
|
.#{$ns}Checkboxes {
|
||||||
|
> .#{$ns}Checkbox {
|
||||||
|
display: block;
|
||||||
|
height: $Form-input-height;
|
||||||
|
line-height: $Form-input-lineHeight;
|
||||||
|
font-size: $Form-input-fontSize;
|
||||||
|
padding: (
|
||||||
|
$Form-input-height - $Form-input-lineHeight * $Form-input-fontSize
|
||||||
|
)/2 $gap-sm
|
||||||
|
($Form-input-height - $Form-input-lineHeight * $Form-input-fontSize)/2
|
||||||
|
($gap-sm + $Checkbox-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--inline > .#{$ns}Checkbox {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
&-addBtn {
|
&-addBtn {
|
||||||
display: block;
|
display: block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -27,8 +27,6 @@
|
|||||||
|
|
||||||
&-items {
|
&-items {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
height: 0;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-item {
|
&-item {
|
||||||
|
@ -8,117 +8,111 @@ import React from 'react';
|
|||||||
import uncontrollable from 'uncontrollable';
|
import uncontrollable from 'uncontrollable';
|
||||||
import Checkbox from './Checkbox';
|
import Checkbox from './Checkbox';
|
||||||
import chunk from 'lodash/chunk';
|
import chunk from 'lodash/chunk';
|
||||||
import {ClassNamesFn, themeable} from '../theme';
|
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
|
||||||
import {Option, OptionProps, value2array} from './Select';
|
import {Option, value2array, Options} from './Select';
|
||||||
|
import find from 'lodash/find';
|
||||||
// import isPlainObject from 'lodash/isPlainObject';
|
// import isPlainObject from 'lodash/isPlainObject';
|
||||||
|
|
||||||
interface CheckboxesProps extends OptionProps {
|
interface CheckboxesProps extends ThemeProps {
|
||||||
id?: string;
|
options: Options;
|
||||||
key?: string;
|
|
||||||
className?: string;
|
className?: string;
|
||||||
type: string;
|
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
disabled?: boolean;
|
value?: Array<any>;
|
||||||
value?: string;
|
onChange?: (value: Array<Option>) => void;
|
||||||
onChange?: Function;
|
|
||||||
inline?: boolean;
|
inline?: boolean;
|
||||||
checked?: boolean;
|
|
||||||
labelClassName?: string;
|
labelClassName?: string;
|
||||||
classPrefix: string;
|
option2value?: (option: Option) => any;
|
||||||
classnames: ClassNamesFn;
|
itemClassName?: string;
|
||||||
|
itemRender: (option: Option) => JSX.Element;
|
||||||
|
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Checkboxes extends React.PureComponent<CheckboxesProps, any> {
|
export class Checkboxes extends React.Component<CheckboxesProps, any> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
joinValues: true,
|
placeholder: '暂无选项',
|
||||||
extractValue: false,
|
itemRender: (option: Option) => <span>{option.label}</span>
|
||||||
inline: false,
|
|
||||||
delimiter: ',',
|
|
||||||
columnsCount: 1 // 一行显示一个
|
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleOption(option: Option) {
|
static value2array(
|
||||||
const {
|
value: any,
|
||||||
value,
|
options: Options,
|
||||||
onChange,
|
option2value: (option: Option) => any = (option: Option) => option
|
||||||
delimiter,
|
): Options {
|
||||||
valueField,
|
if (value === void 0) {
|
||||||
options,
|
return [];
|
||||||
simpleValue
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
let valueArray = value2array(value, {
|
|
||||||
multiple: true,
|
|
||||||
valueField,
|
|
||||||
delimiter,
|
|
||||||
options
|
|
||||||
});
|
|
||||||
let idx = valueArray.indexOf(option);
|
|
||||||
|
|
||||||
if (!~idx) {
|
|
||||||
option =
|
|
||||||
value2array(option[valueField || 'value'], {
|
|
||||||
multiple: true,
|
|
||||||
valueField,
|
|
||||||
delimiter,
|
|
||||||
options
|
|
||||||
})[0] || option;
|
|
||||||
idx = valueArray.indexOf(option);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
value = [value];
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
.map((value: any) => {
|
||||||
|
const option = find(options, option => option2value(option) === value);
|
||||||
|
return option;
|
||||||
|
})
|
||||||
|
.filter((item: any) => item);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleOption(option: Option) {
|
||||||
|
const {value, onChange, option2value, options} = this.props;
|
||||||
|
|
||||||
|
let valueArray = Checkboxes.value2array(value, options, option2value);
|
||||||
|
let idx = valueArray.indexOf(option);
|
||||||
|
|
||||||
if (~idx) {
|
if (~idx) {
|
||||||
valueArray.splice(idx, 1);
|
valueArray.splice(idx, 1);
|
||||||
} else {
|
} else {
|
||||||
valueArray.push(option);
|
valueArray.push(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
let newValue: string | Array<Option> = simpleValue
|
let newValue: string | Array<Option> = option2value
|
||||||
? valueArray.map(item => item[valueField || 'value'])
|
? valueArray.map(item => option2value(item))
|
||||||
: valueArray;
|
: valueArray;
|
||||||
|
|
||||||
onChange && onChange(newValue);
|
onChange?.(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
value,
|
value,
|
||||||
valueField,
|
|
||||||
delimiter,
|
|
||||||
options,
|
options,
|
||||||
className,
|
className,
|
||||||
placeholder,
|
placeholder,
|
||||||
disabled,
|
|
||||||
inline,
|
inline,
|
||||||
labelClassName
|
labelClassName,
|
||||||
|
disabled,
|
||||||
|
classnames: cx,
|
||||||
|
option2value,
|
||||||
|
itemClassName,
|
||||||
|
itemRender
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let valueArray = value2array(value, {
|
let valueArray = Checkboxes.value2array(value, options, option2value);
|
||||||
multiple: true,
|
|
||||||
valueField,
|
|
||||||
delimiter,
|
|
||||||
options
|
|
||||||
});
|
|
||||||
let body: Array<React.ReactNode> = [];
|
let body: Array<React.ReactNode> = [];
|
||||||
|
|
||||||
if (options) {
|
if (Array.isArray(options) && options.length) {
|
||||||
body = options.map((option, key) => (
|
body = options.map((option, key) => (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
className={cx(itemClassName, option.className)}
|
||||||
key={key}
|
key={key}
|
||||||
onChange={() => this.toggleOption(option)}
|
onChange={() => this.toggleOption(option)}
|
||||||
checked={!!~valueArray.indexOf(option)}
|
checked={!!~valueArray.indexOf(option)}
|
||||||
disabled={disabled || option.disabled}
|
disabled={disabled || option.disabled}
|
||||||
inline={inline}
|
|
||||||
labelClassName={labelClassName}
|
labelClassName={labelClassName}
|
||||||
description={option.description}
|
description={option.description}
|
||||||
>
|
>
|
||||||
{option.label}
|
{itemRender(option)}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={cx('Checkboxes', className, inline ? 'Checkboxes--inline' : '')}>
|
||||||
{body && body.length ? body : placeholder}
|
{body && body.length ? body : (
|
||||||
|
<div>{placeholder}</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -47,16 +47,14 @@ export interface OptionProps {
|
|||||||
delimiter?: string;
|
delimiter?: string;
|
||||||
clearable?: boolean;
|
clearable?: boolean;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
autoFill?: {[propName: string]: any};
|
disabled?: boolean;
|
||||||
creatable?: boolean;
|
creatable?: boolean;
|
||||||
onAdd?: (
|
onAdd?: (
|
||||||
idx?: number | Array<number>,
|
idx?: number | Array<number>,
|
||||||
value?: any,
|
value?: any,
|
||||||
skipForm?: boolean
|
skipForm?: boolean
|
||||||
) => void;
|
) => void;
|
||||||
addControls?: Array<any>;
|
|
||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
editControls?: Array<any>;
|
|
||||||
onEdit?: (value: Option, origin?: Option, skipForm?: boolean) => void;
|
onEdit?: (value: Option, origin?: Option, skipForm?: boolean) => void;
|
||||||
removable?: boolean;
|
removable?: boolean;
|
||||||
onDelete?: (value: Option) => void;
|
onDelete?: (value: Option) => void;
|
||||||
|
@ -17,14 +17,14 @@ export interface SelectionsProps extends ThemeProps {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
title?: string;
|
title?: string;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
optionRender: (option: Option) => JSX.Element;
|
itemRender: (option: Option) => JSX.Element;
|
||||||
itemClassName?: string;
|
itemClassName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Selections extends React.Component<SelectionsProps> {
|
export class Selections extends React.Component<SelectionsProps> {
|
||||||
static defaultProps: Pick<SelectionsProps, 'placeholder' | 'optionRender'> = {
|
static defaultProps: Pick<SelectionsProps, 'placeholder' | 'itemRender'> = {
|
||||||
placeholder: '请先选择数据',
|
placeholder: '请先选择数据',
|
||||||
optionRender: (option: Option) => <span>{option.label}</span>
|
itemRender: (option: Option) => <span>{option.label}</span>
|
||||||
};
|
};
|
||||||
|
|
||||||
id = guid();
|
id = guid();
|
||||||
@ -115,7 +115,7 @@ export class Selections extends React.Component<SelectionsProps> {
|
|||||||
className,
|
className,
|
||||||
value,
|
value,
|
||||||
placeholder,
|
placeholder,
|
||||||
optionRender,
|
itemRender,
|
||||||
disabled,
|
disabled,
|
||||||
title,
|
title,
|
||||||
itemClassName,
|
itemClassName,
|
||||||
@ -130,11 +130,11 @@ export class Selections extends React.Component<SelectionsProps> {
|
|||||||
<div className={cx('Selections-items')}>
|
<div className={cx('Selections-items')}>
|
||||||
{value.map((option, index) => (
|
{value.map((option, index) => (
|
||||||
<div className={cx('Selections-item', itemClassName, option?.className)} key={index}>
|
<div className={cx('Selections-item', itemClassName, option?.className)} key={index}>
|
||||||
{sortable && !disabled ? (
|
{sortable && !disabled && value.length > 1 ? (
|
||||||
<Icon className={cx('Selections-dragbar')} icon="combo-dragger"/>
|
<Icon className={cx('Selections-dragbar')} icon="combo-dragger"/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<label>{optionRender(option)}</label>
|
<label>{itemRender(option)}</label>
|
||||||
|
|
||||||
{!disabled ? (
|
{!disabled ? (
|
||||||
<a
|
<a
|
||||||
|
Loading…
Reference in New Issue
Block a user