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