link-stack/packages/ui/components/MultiValueField.tsx
2024-04-29 17:27:25 +02:00

127 lines
3.3 KiB
TypeScript

import { FC, useState } from "react";
import {
TextField as InternalTextField,
Grid,
Box,
IconButton,
} from "@mui/material";
import {
AddCircle as AddCircleIcon,
RemoveCircle as RemoveCircleIcon,
} from "@mui/icons-material";
import { colors, typography } from "../styles/theme";
const TextField: FC<any> = (props) => {
return (
<InternalTextField
fullWidth
size="small"
InputProps={{
sx: {
backgroundColor: "#fff",
},
}}
{...props}
/>
);
};
type MultiValueFieldProps = {
name: string;
label: string;
formState: Record<string, any>;
helperText?: string;
};
export const MultiValueField: FC<MultiValueFieldProps> = ({
name,
label,
formState,
helperText,
}) => {
const { darkMediumGray, mediumBlue, brightRed } = colors;
const { body } = typography;
const value = formState.values[name] || {};
const [fields, setFields] = useState<any[]>(Object.entries(value));
const addField = () => {
setFields([...fields, ["", ""]]);
};
const removeField = (index: number) => {
const newFields = [...fields];
newFields.splice(index, 1);
setFields(newFields);
};
const updateField = (index: number, position: number, value: any) => {
const newFields = [...fields];
newFields[index][position] = value;
setFields(newFields);
// formState.values[name] = Object.fromEntries(newFields);
// console.log(formState.values);
};
return (
<Box component="fieldset" sx={{ border: `1px solid ${darkMediumGray}` }}>
<Box
component="input"
name={name}
value={JSON.stringify(Object.fromEntries(fields))}
readOnly
hidden
/>
<Box
component="legend"
sx={{ ...body, color: darkMediumGray, fontSize: 14 }}
>
{label}
</Box>
<Grid container direction="column" spacing={2}>
<Grid
item
container
xs={12}
direction="row"
justifyContent="space-between"
alignItems="center"
>
<Grid item xs={10}>
<Box sx={{ ...body, color: darkMediumGray }}> {helperText}</Box>
</Grid>
<Grid item>
<IconButton sx={{ color: mediumBlue }} onClick={addField}>
<AddCircleIcon />
</IconButton>
</Grid>
</Grid>
{fields.map(([key, value], index) => (
<Grid key={index} item container direction="row" xs={12} spacing={2}>
<Grid item xs={5}>
<TextField
label="Key"
defaultValue={key}
onChange={(e: any) => updateField(index, 0, e.target.value)}
/>
</Grid>
<Grid item xs={6}>
<TextField
label="Value"
defaultValue={value}
onChange={(e: any) => updateField(index, 1, e.target.value)}
/>
</Grid>
<Grid item xs={1} sx={{ textAlign: "right" }}>
<IconButton
sx={{ color: brightRed }}
onClick={() => removeField(index)}
>
<RemoveCircleIcon />
</IconButton>
</Grid>
</Grid>
))}
</Grid>
</Box>
);
};