mirror of
https://github.com/certimate-go/certimate.git
synced 2026-06-22 21:05:48 +08:00
57 lines
2.0 KiB
TypeScript
57 lines
2.0 KiB
TypeScript
import { type ChangeEvent, useContext, useRef } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { IconFileImport } from "@tabler/icons-react";
|
|
import { Button, type ButtonProps, Input, type UploadProps } from "antd";
|
|
import DisabledContext from "antd/es/config-provider/DisabledContext";
|
|
import { type TextAreaProps } from "antd/es/input/TextArea";
|
|
|
|
import { readFileAsText } from "@/utils/file";
|
|
|
|
export interface TextFileInputProps extends Omit<TextAreaProps, "onChange"> {
|
|
accept?: UploadProps["accept"];
|
|
uploadButtonProps?: Omit<ButtonProps, "disabled" | "onClick">;
|
|
uploadText?: string;
|
|
onChange?: (value: string) => void;
|
|
}
|
|
|
|
const TextFileInput = ({ className, style, accept, disabled, readOnly, uploadText, uploadButtonProps, onChange, ...props }: TextFileInputProps) => {
|
|
const { t } = useTranslation();
|
|
|
|
const injectedDisabled = useContext(DisabledContext);
|
|
const mergedDisabled = disabled ?? injectedDisabled;
|
|
|
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
|
|
const handleButtonClick = () => {
|
|
if (fileInputRef.current) {
|
|
fileInputRef.current.click();
|
|
}
|
|
};
|
|
|
|
const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
|
|
const { files } = e.target as HTMLInputElement;
|
|
if (files?.length) {
|
|
const value = await readFileAsText(files[0]);
|
|
onChange?.(value);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className={className} style={style}>
|
|
<div className="flex flex-col items-center gap-2">
|
|
<Input.TextArea {...props} disabled={mergedDisabled} readOnly={readOnly} onChange={(e) => onChange?.(e.target.value)} />
|
|
{!readOnly && (
|
|
<>
|
|
<Button {...uploadButtonProps} block disabled={mergedDisabled} icon={<IconFileImport size="1.25em" />} onClick={handleButtonClick}>
|
|
{uploadText ?? t("common.text.import_from_file")}
|
|
</Button>
|
|
<input ref={fileInputRef} type="file" style={{ display: "none" }} accept={accept} onChange={handleFileChange} />
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default TextFileInput;
|