Commit a04fa626 authored by chenshouchao's avatar chenshouchao

feat: 新增多选下拉框组件

parent 577fbd69
......@@ -12,6 +12,14 @@ type IFullScreenDrawerProps = {
const FullScreenDrawer = (props: IFullScreenDrawerProps) => {
const { children, handleClose } = props;
const [closeing, setCloseing] = useState(false);
const handleReadyToClose = () => {
setCloseing(true);
setTimeout(() => {
setCloseing(false);
handleClose();
}, 1000);
};
return (
<div
className={classNames({
......@@ -27,13 +35,7 @@ const FullScreenDrawer = (props: IFullScreenDrawerProps) => {
>
<CloseOutlinedIcon
className={style.closeiIcon}
onClick={() => {
setCloseing(true);
setTimeout(() => {
setCloseing(false);
handleClose();
}, 1000);
}}
onClick={() => handleReadyToClose()}
/>
</div>
<div
......
......@@ -11,85 +11,92 @@ import FormGroup, { FormGroupProps } from "@mui/material/FormGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import Checkbox from "@mui/material/Checkbox";
import FormControl from "@mui/material/FormControl";
import FormHelperText from '@mui/material/FormHelperText';
import FormHelperText from "@mui/material/FormHelperText";
import _ from "lodash";
interface IMyCheckBoxProps extends FormGroupProps{
value: Array<any>;
options: Array<ICheckBoxOption>;
onChange: any; // 直接返回选中项的数组
variant?: "standard" | "outlined" | "filled";
error?: boolean;
helperText?: string;
};
interface IMyCheckBoxProps extends FormGroupProps {
value: Array<any>;
options: Array<ICheckBoxOption>;
onChange: any; // 直接返回选中项的数组
variant?: "standard" | "outlined" | "filled";
error?: boolean;
helperText?: string;
}
type ICheckBoxOption = {
value: any;
label?: string;
disabled?: boolean;
value: any;
label?: string;
disabled?: boolean;
};
export const optionsTransform = (
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
arr: Array<any>,
labelKey: string = "label",
valueKey: string = "value",
disabledKey: string = "disabled"
): Array<ICheckBoxOption> => {
return arr.map((item: any) => {
return {
value: item[valueKey],
label: item[labelKey],
disabled: item[disabledKey] || false,
};
});
return arr.map((item: any) => {
return {
value: item[valueKey],
label: item[labelKey],
disabled: item[disabledKey] || false,
};
});
};
export default function MyCheckBox(props: IMyCheckBoxProps) {
const { value, options, onChange, error = false, helperText, variant } = props;
const {
value,
options,
onChange,
error = false,
helperText,
variant,
} = props;
const getCheckedStatus = (
checkBoxItemValue: any,
valueArr: Array<any>
): boolean => {
const result = valueArr.indexOf(checkBoxItemValue);
return result === -1 ? false : true;
};
const getCheckedStatus = (
checkBoxItemValue: any,
valueArr: Array<any>
): boolean => {
const result = valueArr.indexOf(checkBoxItemValue);
return result === -1 ? false : true;
};
const handleMyCheckBoxOnChange = (e: any) => {
const resultArr = _.cloneDeep(value);
const clickValue = e.target.name;
const clickValueIndex = value.indexOf(clickValue);
if (clickValueIndex === -1) {
resultArr.push(clickValue);
onChange && onChange(resultArr);
} else {
resultArr.splice(clickValueIndex, 1);
onChange && onChange(resultArr);
}
};
const handleMyCheckBoxOnChange = (e: any) => {
const resultArr = _.cloneDeep(value);
const clickValue = e.target.name;
const clickValueIndex = value.indexOf(clickValue);
if (clickValueIndex === -1) {
resultArr.push(clickValue);
onChange && onChange(resultArr);
} else {
resultArr.splice(clickValueIndex, 1);
onChange && onChange(resultArr);
}
};
return (
<FormControl fullWidth variant={variant} error={error}>
<FormGroup {...props} row>
{options.map((option) => {
return (
<FormControlLabel
key={option.value}
control={
<Checkbox
checked={getCheckedStatus(option.value, value)}
value={option.value}
/>
}
label={option.label}
name={option.value}
onChange={handleMyCheckBoxOnChange}
disabled={option.disabled}
/>
);
})}
</FormGroup>
{helperText && error && <FormHelperText>{helperText}</FormHelperText>}
</FormControl>
);
return (
<FormControl fullWidth variant={variant} error={error}>
<FormGroup {...props} row>
{options.map((option) => {
return (
<FormControlLabel
key={option.value}
control={
<Checkbox
checked={getCheckedStatus(option.value, value)}
value={option.value}
/>
}
label={option.label}
name={option.value}
onChange={handleMyCheckBoxOnChange}
disabled={option.disabled}
/>
);
})}
</FormGroup>
{helperText && error && <FormHelperText>{helperText}</FormHelperText>}
</FormControl>
);
}
// 单选下拉框, 是input还是text还是其他由children决定
import * as React from "react";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
......@@ -42,6 +44,13 @@ const theme = createTheme({
},
},
},
MuiList: {
styleOverrides: {
root: {
maxHeight: "268px",
},
},
},
MuiSvgIcon: {
styleOverrides: {
root: {
......
// 多选下拉框, 是input还是text还是其他由children决定
import * as React from "react";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import Checkbox from "@mui/material/Checkbox";
import { ThemeProvider, createTheme } from "@mui/material/styles";
import _ from "lodash";
const theme = createTheme({
components: {
MuiMenu: {
styleOverrides: {
root: {
overflowY: "scroll",
},
},
},
MuiMenuItem: {
styleOverrides: {
root: {
fontSize: "14px",
lineHeight: "36px",
display: "flex",
justifyContent: "flex-start",
paddingTop: 0,
paddingBottom: 0,
paddingRight: "32px",
paddingLeft: "4px",
":hover": {
color: "rgba(30, 38, 51, 1)",
background: "rgba(240, 242, 245, 1)",
},
},
},
},
MuiList: {
styleOverrides: {
root: {
maxHeight: "268px",
},
},
},
MuiSvgIcon: {
styleOverrides: {
root: {
width: "22px",
height: "22px",
},
},
},
MuiButtonBase: {
styleOverrides: {
root: {},
},
},
MuiCheckbox: {
styleOverrides: {
root: {
color: "rgba(209, 214, 222, 1)",
"&.Mui-checked": {
color: "rgba(19, 112, 255, 1)",
},
},
},
},
},
});
export type IOption = {
label: string;
value: string;
};
type IMyMultipleMenuProps = {
children: React.ReactNode;
options: Array<IOption>; // 选项
value: Array<string>; // 选中的项values
setValue?: any; // 设置选中的项values
showSelectAll?: boolean; // 是否显示全选
selectAllText?: string; // 全选的文字
};
const MyMultipleMenu = (props: IMyMultipleMenuProps) => {
const {
children,
options,
value,
setValue,
showSelectAll = false,
selectAllText = "全部",
} = props;
// 下拉框展示的相对位置参考元素
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
// 展示/隐藏下拉框切换
const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
setAnchorEl(event.currentTarget);
};
// 隐藏下拉框
const handleClose = (value: string) => {
setAnchorEl(null);
};
// 选择/取消选择
const handleMenuClick = (clickValue: string) => {
const resultArr = _.cloneDeep(value);
const valueIndex = value.indexOf(clickValue);
if (valueIndex === -1) {
resultArr.push(clickValue);
setValue && setValue(resultArr);
} else {
resultArr.splice(valueIndex, 1);
setValue && setValue(resultArr);
}
};
// 全选
const handleMenuAllClick = () => {
if (value.length === options.length) {
setValue([]);
} else {
setValue(options.map((option) => option.value));
}
};
// 是否选中
const getCheckedStatus = (
checkBoxItemValue: any,
valueArr: Array<any>
): boolean => {
const result = valueArr.indexOf(checkBoxItemValue);
return result === -1 ? false : true;
};
return (
<ThemeProvider theme={theme}>
<div>
<div onClick={handleClick}>{children}</div>
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "basic-button",
}}
>
{showSelectAll && (
<MenuItem onClick={() => handleMenuAllClick()} key="indeterminate">
<Checkbox
checked={value.length === options.length}
indeterminate={value.length !== options.length}
/>
<span>{selectAllText}</span>
</MenuItem>
)}
{options.map((option, index) => {
return (
<MenuItem
onClick={() => handleMenuClick(option.value)}
key={index}
>
<Checkbox
checked={getCheckedStatus(option.value, value)}
value={option.value}
/>
<span>{option.label}</span>
</MenuItem>
);
})}
</Menu>
</div>
</ThemeProvider>
);
};
export default MyMultipleMenu;
import FullScreenDrawer from "@/components/CommonComponents/FullScreenDrawer";
import { useState } from "react";
import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfButtonStyle";
import MyMultipleMenu, { IOption } from "@/components/mui/MyMultipleMenu";
import style from "./index.module.css";
type ISeeDatasetProps = {
handleClose: any;
};
const dataTypesMock = [
{
label: "123",
value: "1234",
},
{
label: "1232",
value: "12342",
},
{
label: "1233",
value: "12344",
},
];
const SeeDataset = (props: ISeeDatasetProps) => {
const [graphicDimension, setGraphicDimension] = useState("2D"); // 分子结构图是2D还是3D
const [showDataTypes, setShowDataTypes] = useState<Array<string>>([]); //显示的数据类型
const [dataTypes, setdataTypes] = useState<Array<IOption>>(dataTypesMock); // 可选的数据类型
return (
<FullScreenDrawer handleClose={props.handleClose}>
<h2>数据集title</h2>
<div className={style.screens}>
<div className={style.screensLeft}>
<RadioGroupOfButtonStyle
handleRadio={setGraphicDimension}
value={graphicDimension}
radioOptions={[
{
value: "2D",
label: "2D",
},
{
value: "3D",
label: "3D",
},
]}
RadiosBoxStyle={{ width: "132px" }}
></RadioGroupOfButtonStyle>
<MyMultipleMenu
value={showDataTypes}
options={dataTypes}
setValue={setShowDataTypes}
showSelectAll={true}
>
选择显示数据({showDataTypes.length})
</MyMultipleMenu>
</div>
<div className={style.screensRight}></div>
</div>
SeeDataset
</FullScreenDrawer>
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment