@ant-design/icons#CaretDownFilled TypeScript Examples
The following examples show how to use
@ant-design/icons#CaretDownFilled.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.tsx From dashboard with Apache License 2.0 | 4 votes |
DepartmentSelectionModal: React.FC<DepartmentSelectionProps> = (props) => {
const {visible, setVisible, defaultCheckedDepartments, onFinish, allDepartments} = props;
const [departments, setDepartments] = useState<DepartmentOption[]>([]);
const [departmentNodes, setDepartmentNodes] = useState<TreeNode[]>([]); // 一维的节点
const [departmentTree, setDepartmentTree] = useState<TreeNode[]>([]); // 多维的树节点
const [selectedDepartments, setSelectedDepartments] = useState<DepartmentOption[]>(
_.filter<DepartmentOption>(defaultCheckedDepartments) || [],
);
const [keyword, setKeyword] = useState<string>('');
const [checkAll, setCheckAll] = useState<boolean>(false);
const [expandAll, setExpandAll] = useState<boolean>(false);
const [checkedNodeKeys, setCheckedNodeKeys] = useState<string[]>([]);
const [expandedNodeKeys, setExpandedNodeKeys] = useState<string[]>(['1']);
const allDepartmentMap = _.keyBy(allDepartments, 'ext_id');
const onCheckAllChange = (e: CheckboxChangeEvent) => {
let items: DepartmentOption[];
if (e.target.checked) {
items = _.uniqWith<DepartmentOption>(
[...departments, ...selectedDepartments],
(a, b) => a.ext_id === b.ext_id,
);
} else {
items = _.differenceWith(selectedDepartments, departments, (a, b) => a.ext_id === b.ext_id);
}
setSelectedDepartments(items);
setCheckAll(e.target.checked);
};
const onNodesCheck = (checked: { checked: string[]; halfChecked: string[] }) => {
const checkedExtDepartmentIDs: number[] = [];
let selectedExtDepartmentIDs = selectedDepartments.map((item) => item.ext_id);
let checkedKeys = [...checked.checked];
// 找出本次uncheck的key,根据这些key的ext_id去删除相关checkedKey
const uncheckedKeys = _.difference(checkedNodeKeys, checkedKeys);
_.forEach<string>(uncheckedKeys, (key: string) => {
// @ts-ignore
checkedKeys = checkedKeys.filter<string>((checkedKey) => {
return !checkedKey.includes(key);
});
});
// 记录当前所有checked的key
checkedKeys.forEach((key) => {
checkedExtDepartmentIDs.push(Number(key));
selectedExtDepartmentIDs.push(Number(key));
});
// 计算需要删除的extDepartmentID
// @ts-ignore
const shouldDeleteExtDepartmentIDs = _.difference(
_.map(departments, 'ext_id'),
checkedExtDepartmentIDs,
);
selectedExtDepartmentIDs = _.difference(
_.uniq(selectedExtDepartmentIDs),
_.uniq(shouldDeleteExtDepartmentIDs),
);
const items = selectedExtDepartmentIDs.map((selectedExtDepartmentID) => {
return allDepartmentMap[selectedExtDepartmentID];
});
setCheckAll(departments.length === items.length);
setSelectedDepartments(items);
};
const nodeRender = (node: DataNode): ReactNode => {
return (
<>
<FolderFilled
style={{
color: '#47a7ff',
fontSize: 20,
marginRight: 6,
verticalAlign: -6,
}}
/>
{node.title}
</>
);
};
useEffect(() => {
setSelectedDepartments(_.filter<DepartmentOption>(defaultCheckedDepartments) || []);
setKeyword('');
}, [defaultCheckedDepartments, visible]);
// 监听选中部门变化,计算checked的树节点
useEffect(() => {
const allDepartmentNodeKeys = _.map(departmentNodes, 'key');
// 计算当前选中的部门,命中的key
const matchedKeys: string[] = [];
allDepartmentNodeKeys.forEach((key: string) => {
selectedDepartments.forEach((department) => {
if (key === `${department.ext_id}`) {
matchedKeys.push(key);
}
});
});
setCheckedNodeKeys(matchedKeys);
}, [selectedDepartments]);
// 关键词变化的时候
useEffect(() => {
let filteredDepartments: DepartmentOption[] = [];
allDepartments.forEach((item) => {
if (keyword.trim() === '' || item.label.includes(keyword.trim())) {
filteredDepartments.push(item);
}
})
// 把搜索结果的父级节点放进结果集,方便构造树
const pushParentDepartment = (item: DepartmentOption) => {
if (item.ext_parent_id === 0) {
filteredDepartments.push(item);
return;
}
const parent = allDepartmentMap[item.ext_parent_id];
// eslint-disable-next-line @typescript-eslint/no-unused-vars
filteredDepartments.push(parent);
pushParentDepartment(parent);
};
filteredDepartments.forEach((item) => {
pushParentDepartment(item);
})
filteredDepartments = _.uniq<DepartmentOption>(filteredDepartments);
setDepartments(filteredDepartments);
const {nodes, tree} = buildDepartmentTree(filteredDepartments);
// 这里同步更新node节点和选中key值
let checkedKeys: string[] = [];
nodes.forEach((node) => {
selectedDepartments.forEach((department) => {
if (node.key === `${department.ext_id}`) {
checkedKeys.push(node.key);
}
});
});
checkedKeys = _.uniq<string>(checkedKeys);
setCheckedNodeKeys(checkedKeys);
setCheckAll(false);
setDepartmentNodes(nodes);
setDepartmentTree(tree);
}, [allDepartments, keyword]);
// @ts-ignore
return (
<Modal
width={665}
className={'dialog from-item-label-100w'}
visible={visible}
zIndex={1001}
onCancel={() => setVisible(false)}
onOk={() => {
if (onFinish) {
onFinish(selectedDepartments);
}
setVisible(false);
}}
>
<h2 className="dialog-title"> 选择部门 </h2>
<div className={styles.addDepartmentDialogContent}>
<div className={styles.container}>
<div className={styles.left}>
<p className={styles.toolTop} style={{marginBottom: 0}}>
<Search
className={styles.searchInput}
enterButton={'搜索'}
prefix={<SearchOutlined/>}
placeholder="请输入部门名称"
allowClear
value={keyword}
onChange={(e) => {
setKeyword(e.target.value);
}}
/>
</p>
<p style={{marginBottom: 0}}>
<Checkbox checked={checkAll} onChange={onCheckAllChange}>
全部部门({departments.length}):
</Checkbox>
<Button
type={'link'}
onClick={() => {
const currentStatus = !expandAll;
if (currentStatus) {
setExpandedNodeKeys(_.map(departmentNodes, 'key'));
} else {
setExpandedNodeKeys(['0']);
}
setExpandAll(currentStatus);
}}
style={{marginRight: 30}}
>
{!expandAll ? '展开全部' : '收起全部'}
</Button>
</p>
<div className={styles.allDepartment}>
{departmentTree.length === 0 && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>}
<Tree
className={styles.departmentTree}
autoExpandParent={false}
checkStrictly={true}
checkedKeys={checkedNodeKeys}
defaultExpandedKeys={checkedNodeKeys}
expandedKeys={expandedNodeKeys}
// @ts-ignore
onExpand={(expandedKeys: string[]) => {
setExpandedNodeKeys(expandedKeys);
}}
height={300}
switcherIcon={<CaretDownFilled style={{color: '#47a7ff'}}/>}
checkable={true}
multiple={true}
treeData={departmentTree}
// @ts-ignore
onCheck={onNodesCheck}
titleRender={nodeRender}
/>
</div>
</div>
<div className={styles.right}>
<p>
已选部门({selectedDepartments.length}):
<Button
type={'link'}
onClick={() => {
setSelectedDepartments([]);
setCheckAll(false);
}}
>
清空
</Button>
</p>
<ul className={styles.allDepartmentList}>
{selectedDepartments.map((department) => {
if (!department) {
return <></>
}
return (
<li
key={department.ext_id}
onClick={() => {
setSelectedDepartments(
selectedDepartments.filter((item) => item.ext_id !== department.ext_id),
);
}}
>
<div className={styles.avatarAndName}>
<div className="flex-col align-left">
<FolderFilled
style={{
color: '#47a7ff',
fontSize: 20,
marginRight: 6,
verticalAlign: -6,
}}
/>
{department.name}
</div>
</div>
<CloseOutlined/>
</li>
);
})}
</ul>
</div>
</div>
</div>
</Modal>
);
}
Example #2
Source File: index.tsx From dashboard with Apache License 2.0 | 4 votes |
StaffTreeSelectionModal: React.FC<StaffSelectionProps> = (props) => {
const { visible, setVisible, defaultCheckedStaffs, onFinish, allStaffs } = props;
const [staffs, setStaffs] = useState<StaffOption[]>([]);
const [staffNodes, setStaffNodes] = useState<TreeNode[]>([]); // 一维的节点
const [staffTree, setStaffTree] = useState<TreeNode[]>([]); // 多维的树节点
const [selectedStaffs, setSelectedStaffs] = useState<StaffOption[]>(defaultCheckedStaffs || []);
const [keyword, setKeyword] = useState<string>('');
const [checkAll, setCheckAll] = useState<boolean>(false);
const [expandAll, setExpandAll] = useState<boolean>(false);
const [checkedNodeKeys, setCheckedNodeKeys] = useState<string[]>([]);
const [expandedNodeKeys, setExpandedNodeKeys] = useState<string[]>([rootNode]);
const allStaffMap = _.keyBy(allStaffs, 'ext_id');
const onCheckAllChange = (e: CheckboxChangeEvent) => {
let items: StaffOption[];
if (e.target.checked) {
items = _.uniqWith<StaffOption>(
[...staffs, ...selectedStaffs],
(a, b) => a.ext_id === b.ext_id,
);
} else {
// @ts-ignore
items = _.differenceWith<StaffParam>(selectedStaffs, staffs, (a, b) => a.ext_id === b.ext_id);
}
setSelectedStaffs(items);
setCheckAll(e.target.checked);
};
const onNodesCheck = (checked: string[]) => {
const checkedExtStaffIDs: string[] = [];
let selectedExtStaffIDs = _.map(selectedStaffs, 'ext_id');
let checkedKeys = [...checked];
// 找出本次uncheck的key,根据这些key的ext_id去删除相关checkedKey
const uncheckedKeys = _.difference(checkedNodeKeys, checkedKeys);
_.forEach<string>(uncheckedKeys, (key: string) => {
const [, , nodeID] = key.split(separator);
// eslint-disable-next-line no-param-reassign
// @ts-ignore
checkedKeys = checkedKeys.filter<string>((checkedKey) => {
return !checkedKey.includes(`${separator}${nodeID}`);
});
});
// 记录当前所有checked的key
checkedKeys.forEach((key) => {
const [nodeType, , nodeID] = key.split(separator);
if (nodeType === 'node') {
checkedExtStaffIDs.push(nodeID);
selectedExtStaffIDs.push(nodeID);
}
});
// 计算需要删除的extStaffID
// @ts-ignore
const shouldDeleteExtStaffIDs = _.difference(_.map(staffs, 'ext_id'), checkedExtStaffIDs);
selectedExtStaffIDs = _.difference(
_.uniq(selectedExtStaffIDs),
_.uniq(shouldDeleteExtStaffIDs),
);
const items = selectedExtStaffIDs.map((selectedExtStaffID) => {
return allStaffMap[selectedExtStaffID];
});
setCheckAll(staffs.length === items.length);
setSelectedStaffs(items);
};
const nodeRender = (node: DataNode): ReactNode => {
const [nodeType, , extStaffID] = node.key.toString().split(separator);
if (nodeType === 'node') {
const staff = allStaffMap[extStaffID];
if (staff) {
return (
<div className={styles.staffTitleNode}>
<img src={FormatWeWorkAvatar(staff?.avatar_url, 60)} className={styles.avatar} />
<div className={styles.text}>
<span className={styles.title}>{staff?.name}</span>
<em
style={{
color: RoleColorMap[staff?.role_type],
borderColor: RoleColorMap[staff?.role_type],
}}
>
{RoleMap[staff?.role_type] || '普通员工'}
</em>
</div>
</div>
);
}
}
return (
<>
<FolderFilled
style={{
color: '#47a7ff',
fontSize: 20,
marginRight: 6,
verticalAlign: -3,
}}
/>
{node.title}
</>
);
};
useEffect(() => {
setSelectedStaffs(defaultCheckedStaffs || []);
setKeyword('');
}, [defaultCheckedStaffs, visible]);
// 监听选中员工变化,计算checked的树节点
useEffect(() => {
const allStaffNodeKeys = _.map(staffNodes, 'key');
// 计算当前选中的员工,命中的key
const matchedKeys: string[] = [];
allStaffNodeKeys.forEach((key: string) => {
selectedStaffs.forEach((staff) => {
if (key.includes(`${separator}${staff?.ext_id}`)) {
matchedKeys.push(key);
}
});
});
setCheckedNodeKeys(matchedKeys);
}, [selectedStaffs, staffNodes]);
// 关键词变化的时候
useEffect(() => {
const filteredStaffs = allStaffs.filter((item) => {
// 搜索部门名称
let isDepartmentMatch = false;
item?.departments?.forEach((department) => {
if (department.name.includes(keyword)) {
isDepartmentMatch = true;
}
});
return keyword === '' || isDepartmentMatch || item.label.includes(keyword);
});
setStaffs(filteredStaffs);
const { nodes, tree } = buildStaffTree(filteredStaffs);
// 这里同步更新node节点和选中key值
let checkedKeys: string[] = [];
nodes.forEach((node) => {
selectedStaffs.forEach((staff) => {
if (node.nodeKey.includes(`${separator}${staff?.ext_id}`)) {
checkedKeys.push(node.key);
}
});
});
checkedKeys = _.uniq<string>(checkedKeys);
setCheckedNodeKeys(checkedKeys);
setCheckAll(false);
setStaffNodes(nodes);
setStaffTree(tree);
}, [allStaffs, keyword]);
// @ts-ignore
return (
<Modal
width={665}
className={'dialog from-item-label-100w'}
visible={visible}
zIndex={1001}
onCancel={() => setVisible(false)}
onOk={() => {
if (onFinish) {
onFinish(selectedStaffs);
}
setVisible(false);
}}
>
<h2 className='dialog-title'> 选择员工 </h2>
<div className={styles.addStaffDialogContent}>
<div className={styles.container}>
<div className={styles.left}>
<p className={styles.toolTop} style={{ marginBottom: 0 }}>
<Search
className={styles.searchInput}
enterButton={'搜索'}
prefix={<SearchOutlined />}
placeholder='请输入员工昵称'
allowClear
value={keyword}
onChange={(e) => {
setKeyword(e.target.value);
}}
/>
</p>
<p style={{ marginBottom: 0 }}>
<Checkbox checked={checkAll} onChange={onCheckAllChange}>
全部成员({staffs.length}):
</Checkbox>
<Button
type={'link'}
onClick={() => {
const currentStatus = !expandAll;
if (currentStatus) {
setExpandedNodeKeys(
_.map(
staffNodes.filter((staffNode) => staffNode.type === 'group'),
'key',
),
);
} else {
setExpandedNodeKeys([rootNode]);
}
setExpandAll(currentStatus);
}}
style={{ marginRight: 30 }}
>
{!expandAll ? '展开部门' : '收起部门'}
</Button>
</p>
<div className={styles.allStaff}>
{staffTree.length === 0 && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
<Tree
className={styles.staffTree}
autoExpandParent={true}
checkedKeys={checkedNodeKeys}
defaultExpandedKeys={checkedNodeKeys}
expandedKeys={expandedNodeKeys}
// @ts-ignore
onExpand={(expandedKeys: string[]) => {
setExpandedNodeKeys(expandedKeys);
}}
height={300}
switcherIcon={<CaretDownFilled style={{ color: '#47a7ff' }} />}
checkable={true}
multiple={true}
treeData={staffTree}
// @ts-ignore
onCheck={onNodesCheck}
titleRender={nodeRender}
/>
</div>
</div>
<div className={styles.right}>
<p>
已选成员({selectedStaffs.length}):
<Button
type={'link'}
onClick={() => {
setSelectedStaffs([]);
setCheckAll(false);
}}
>
清空
</Button>
</p>
<ul className={styles.allStaffList}>
{selectedStaffs.map((staff) => {
if (!staff?.ext_id) {
return '';
}
return (
<li
key={staff?.ext_id}
onClick={() => {
setSelectedStaffs(
selectedStaffs.filter((item) => item?.ext_id !== staff?.ext_id),
);
}}
>
<div className={styles.avatarAndName}>
<img src={staff?.avatar_url} className={styles.avatar} />
<div className='flex-col align-left'>
<span>{staff?.name}</span>
</div>
</div>
<CloseOutlined />
</li>
);
})}
</ul>
</div>
</div>
</div>
</Modal>
);
}
Example #3
Source File: DepartmentTree.tsx From dashboard with Apache License 2.0 | 4 votes |
DepartMentTreeComp = ({ callback }: { callback: (selectedkey: string) => void }) => {
const [allDepartments, setAllDepartments] = useState<DepartmentList.Item[]>([]);
const [departments, setDepartments] = useState<DepartmentOption[]>([]);
const [departmentNodes, setDepartmentNodes] = useState<TreeNode[]>([]); // 一维的节点
const [departmentTree, setDepartmentTree] = useState<TreeNode[]>([]); // 多维的树节点
const [selectedDepartments, setSelectedDepartments] = useState<DepartmentOption[]>([]);
const [keyword] = useState<string>('');
const [expandAll, setExpandAll] = useState<boolean>(false);
const [checkedNodeKeys, setCheckedNodeKeys] = useState<string[]>([]);
const [expandedNodeKeys, setExpandedNodeKeys] = useState<string[]>(['1']);
const allDepartmentMap = _.keyBy(allDepartments, 'ext_id');
useEffect(() => {
QueryDepartmentList({ page_size: 5000 })
.then((res: any) => {
if (res?.code === 0 && res?.data && res?.data.items) {
setAllDepartments(res?.data.items);
setExpandedNodeKeys(['1']);
}
})
.catch((err) => {
message.error(err);
});
}, []);
const onNodesCheck = (checked: { checked: string[]; halfChecked: string[] }) => {
const checkedExtDepartmentIDs: number[] = [];
let selectedExtDepartmentIDs = selectedDepartments.map((item) => item.ext_id);
let checkedKeys = [...checked.checked];
// 找出本次uncheck的key,根据这些key的ext_id去删除相关checkedKey
const uncheckedKeys = _.difference(checkedNodeKeys, checkedKeys);
_.forEach<string>(uncheckedKeys, (key: string) => {
// @ts-ignore
checkedKeys = checkedKeys.filter<string>((checkedKey) => {
return !checkedKey.includes(key);
});
});
// 记录当前所有checked的key
checkedKeys.forEach((key) => {
checkedExtDepartmentIDs.push(Number(key));
selectedExtDepartmentIDs.push(Number(key));
});
// 计算需要删除的extDepartmentID
// @ts-ignore
const shouldDeleteExtDepartmentIDs = _.difference(
_.map(departments, 'ext_id'),
checkedExtDepartmentIDs,
);
selectedExtDepartmentIDs = _.difference(
_.uniq(selectedExtDepartmentIDs),
_.uniq(shouldDeleteExtDepartmentIDs),
);
const items = selectedExtDepartmentIDs.map((selectedExtDepartmentID) => {
return allDepartmentMap[selectedExtDepartmentID];
});
// @ts-ignore
setSelectedDepartments(items);
};
const nodeRender = (node: DataNode): ReactNode => {
return (
<div
onClick={() => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
callback && callback(String(node.key))
}}
style={{ padding: '4px 6px', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow:'ellipsis'}}
>
<FolderFilled
style={{
color: '#47a7ff',
fontSize: 20,
marginRight: 6,
verticalAlign: -6,
}}
/>
<span>
{/* node.title */}
{
// @ts-ignore
node.title.length>14? <span>{node.title.slice(0,13)}...</span>:<span>{node.title}</span>
}
({node.staff_num})
</span>
</div>
);
};
// 监听选中部门变化,计算checked的树节点
useEffect(() => {
const allDepartmentNodeKeys = _.map(departmentNodes, 'key');
// 计算当前选中的部门,命中的key
const matchedKeys: string[] = [];
allDepartmentNodeKeys.forEach((key: string) => {
selectedDepartments.forEach((department) => {
if (key === `${department.ext_id}`) {
matchedKeys.push(key);
}
});
});
setCheckedNodeKeys(matchedKeys);
}, [selectedDepartments]);
// 关键词变化的时候
useEffect(() => {
const filteredDepartments = allDepartments.filter((item) => {
return keyword === '' || item.label.includes(keyword);
});
// @ts-ignore
setDepartments(filteredDepartments);
const { nodes, tree } = buildDepartmentTree(filteredDepartments);
// 这里同步更新node节点和选中key值
let checkedKeys: string[] = [];
nodes.forEach((node) => {
selectedDepartments.forEach((department) => {
if (node.key === `${department.ext_id}`) {
checkedKeys.push(node.key);
}
});
});
checkedKeys = _.uniq<string>(checkedKeys);
setCheckedNodeKeys(checkedKeys);
setDepartmentNodes(nodes);
setDepartmentTree(tree);
}, [allDepartments, keyword]);
return (
<div >
<div className={styles.header}>
<span className={styles.departmentTitle}>部门信息</span>
<a
type={'link'}
onClick={() => {
const currentStatus = !expandAll;
if (currentStatus) {
setExpandedNodeKeys(_.map(departmentNodes, 'key'));
} else {
setExpandedNodeKeys(['0']);
}
setExpandAll(currentStatus);
}}
>
{!expandAll ? '展开全部' : '收起全部'}
</a>
</div>
<div className={styles.treeContainer}>
<Tree
autoExpandParent={false}
checkStrictly={true}
checkedKeys={checkedNodeKeys}
expandedKeys={expandedNodeKeys}
// @ts-ignore
onExpand={(expandedKeys: string[]) => {
setExpandedNodeKeys(expandedKeys);
}}
height={300}
switcherIcon={<CaretDownFilled style={{ color: '#47a7ff' }} />}
multiple={true}
treeData={departmentTree}
// @ts-ignore
onCheck={onNodesCheck}
titleRender={nodeRender}
/>
</div>
</div>
);
}