|
|
@ -4,6 +4,7 @@ import classNames from 'classnames'; |
|
|
import { useMergedState } from 'rc-util'; |
|
|
import { useMergedState } from 'rc-util'; |
|
|
import React, { type FC, useState } from 'react'; |
|
|
import React, { type FC, useState } from 'react'; |
|
|
import useStyles from './index.style'; |
|
|
import useStyles from './index.style'; |
|
|
|
|
|
|
|
|
const { CheckableTag } = Tag; |
|
|
const { CheckableTag } = Tag; |
|
|
export interface TagSelectOptionProps { |
|
|
export interface TagSelectOptionProps { |
|
|
value: string | number; |
|
|
value: string | number; |
|
|
@ -26,7 +27,10 @@ const TagSelectOption: React.FC<TagSelectOptionProps> & { |
|
|
|
|
|
|
|
|
TagSelectOption.isTagSelectOption = true; |
|
|
TagSelectOption.isTagSelectOption = true; |
|
|
|
|
|
|
|
|
type TagSelectOptionElement = React.ReactElement<TagSelectOptionProps, typeof TagSelectOption>; |
|
|
type TagSelectOptionElement = React.ReactElement< |
|
|
|
|
|
TagSelectOptionProps, |
|
|
|
|
|
typeof TagSelectOption |
|
|
|
|
|
>; |
|
|
|
|
|
|
|
|
export interface TagSelectProps { |
|
|
export interface TagSelectProps { |
|
|
onChange?: (value: (string | number)[]) => void; |
|
|
onChange?: (value: (string | number)[]) => void; |
|
|
@ -48,20 +52,33 @@ const TagSelect: FC<TagSelectProps> & { |
|
|
Option: typeof TagSelectOption; |
|
|
Option: typeof TagSelectOption; |
|
|
} = (props) => { |
|
|
} = (props) => { |
|
|
const { styles } = useStyles(); |
|
|
const { styles } = useStyles(); |
|
|
const { children, hideCheckAll = false, className, style, expandable, actionsText = {} } = props; |
|
|
const { |
|
|
|
|
|
children, |
|
|
|
|
|
hideCheckAll = false, |
|
|
|
|
|
className, |
|
|
|
|
|
style, |
|
|
|
|
|
expandable, |
|
|
|
|
|
actionsText = {}, |
|
|
|
|
|
} = props; |
|
|
const [expand, setExpand] = useState<boolean>(false); |
|
|
const [expand, setExpand] = useState<boolean>(false); |
|
|
|
|
|
|
|
|
const [value, setValue] = useMergedState<(string | number)[]>(props.defaultValue || [], { |
|
|
const [value, setValue] = useMergedState<(string | number)[]>( |
|
|
|
|
|
props.defaultValue || [], |
|
|
|
|
|
{ |
|
|
value: props.value, |
|
|
value: props.value, |
|
|
defaultValue: props.defaultValue, |
|
|
defaultValue: props.defaultValue, |
|
|
onChange: props.onChange, |
|
|
onChange: props.onChange, |
|
|
}); |
|
|
}, |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
const isTagSelectOption = (node: TagSelectOptionElement) => |
|
|
const isTagSelectOption = (node: TagSelectOptionElement) => |
|
|
node?.type && |
|
|
node?.type && |
|
|
(node.type.isTagSelectOption || node.type.displayName === 'TagSelectOption'); |
|
|
(node.type.isTagSelectOption || |
|
|
|
|
|
node.type.displayName === 'TagSelectOption'); |
|
|
const getAllTags = () => { |
|
|
const getAllTags = () => { |
|
|
const childrenArray = React.Children.toArray(children) as TagSelectOptionElement[]; |
|
|
const childrenArray = React.Children.toArray( |
|
|
|
|
|
children, |
|
|
|
|
|
) as TagSelectOptionElement[]; |
|
|
const checkedTags = childrenArray |
|
|
const checkedTags = childrenArray |
|
|
.filter((child) => isTagSelectOption(child)) |
|
|
.filter((child) => isTagSelectOption(child)) |
|
|
.map((child) => child.props.value); |
|
|
.map((child) => child.props.value); |
|
|
@ -85,7 +102,11 @@ const TagSelect: FC<TagSelectProps> & { |
|
|
setValue(checkedTags); |
|
|
setValue(checkedTags); |
|
|
}; |
|
|
}; |
|
|
const checkedAll = getAllTags().length === value?.length; |
|
|
const checkedAll = getAllTags().length === value?.length; |
|
|
const { expandText = '展开', collapseText = '收起', selectAllText = '全部' } = actionsText; |
|
|
const { |
|
|
|
|
|
expandText = '展开', |
|
|
|
|
|
collapseText = '收起', |
|
|
|
|
|
selectAllText = '全部', |
|
|
|
|
|
} = actionsText; |
|
|
const cls = classNames(styles.tagSelect, className, { |
|
|
const cls = classNames(styles.tagSelect, className, { |
|
|
[styles.hasExpandTag]: expandable, |
|
|
[styles.hasExpandTag]: expandable, |
|
|
[styles.expanded]: expand, |
|
|
[styles.expanded]: expand, |
|
|
@ -93,7 +114,11 @@ const TagSelect: FC<TagSelectProps> & { |
|
|
return ( |
|
|
return ( |
|
|
<div className={cls} style={style}> |
|
|
<div className={cls} style={style}> |
|
|
{hideCheckAll ? null : ( |
|
|
{hideCheckAll ? null : ( |
|
|
<CheckableTag checked={checkedAll} key="tag-select-__all__" onChange={onSelectAll}> |
|
|
<CheckableTag |
|
|
|
|
|
checked={checkedAll} |
|
|
|
|
|
key="tag-select-__all__" |
|
|
|
|
|
onChange={onSelectAll} |
|
|
|
|
|
> |
|
|
{selectAllText} |
|
|
{selectAllText} |
|
|
</CheckableTag> |
|
|
</CheckableTag> |
|
|
)} |
|
|
)} |
|
|
|