All checks were successful
continuous-integration/drone/push Build is passing
78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
import AttachFileIcon from "@mui/icons-material/AttachFile";
|
|
import ClearIcon from "@mui/icons-material/Clear";
|
|
import {
|
|
IconButton,
|
|
InputAdornment,
|
|
OutlinedInputProps,
|
|
TextField,
|
|
TextFieldSlotsAndSlotProps,
|
|
Tooltip,
|
|
} from "@mui/material";
|
|
import { filesize } from "filesize";
|
|
import React from "react";
|
|
|
|
export function FileInput(
|
|
p: {
|
|
label?: string;
|
|
value: File | null;
|
|
onChange: (file: File | null) => void;
|
|
style?: React.CSSProperties;
|
|
} & TextFieldSlotsAndSlotProps<OutlinedInputProps>
|
|
): React.ReactElement {
|
|
const fileInput = React.useRef<HTMLInputElement>(null);
|
|
|
|
return (
|
|
<TextField
|
|
onClick={() => fileInput.current?.click()}
|
|
{...p}
|
|
value={""}
|
|
onChange={console.log}
|
|
type="file"
|
|
slotProps={{
|
|
input: {
|
|
startAdornment: (
|
|
<>
|
|
<InputAdornment position="start">
|
|
<AttachFileIcon />
|
|
|
|
{p.value ? p.value.name : "Insert a file"}
|
|
</InputAdornment>
|
|
</>
|
|
),
|
|
endAdornment: p.value ? (
|
|
<InputAdornment position="end">
|
|
{filesize(p.value.size)}
|
|
<Tooltip
|
|
title="Remove attached file"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
}}
|
|
>
|
|
<IconButton
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
p.onChange(null);
|
|
}}
|
|
>
|
|
<ClearIcon />
|
|
</IconButton>
|
|
</Tooltip>
|
|
</InputAdornment>
|
|
) : undefined,
|
|
|
|
onChange: (e) => {
|
|
const files = (e.target as any).files;
|
|
p.onChange(files.length > 0 ? files[0] : null);
|
|
},
|
|
},
|
|
htmlInput: {
|
|
ref: fileInput,
|
|
style: { opacity: 0 },
|
|
},
|
|
}}
|
|
placeholder={"Insert a file"}
|
|
variant="outlined"
|
|
/>
|
|
);
|
|
}
|