mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-03-02 02:10:53 +01:00
Use forwardRef in FileInput
Committed-by: Rene Pfeuffer <rene.pfeuffer@cloudogu.com>
This commit is contained in:
2
gradle/changelog/fileinput_forwardref.yaml
Normal file
2
gradle/changelog/fileinput_forwardref.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
- type: fixed
|
||||
description: Allow passing a ref through FileInput to one of its children
|
||||
@@ -21,7 +21,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import React, { ChangeEvent, FC, FocusEvent, useState } from "react";
|
||||
import React, { ChangeEvent, FocusEvent, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import classNames from "classnames";
|
||||
import { createAttributesForTesting } from "../devBuild";
|
||||
@@ -39,77 +39,66 @@ type Props = {
|
||||
testId?: string;
|
||||
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
|
||||
onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
|
||||
ref?: React.Ref<HTMLInputElement>;
|
||||
};
|
||||
|
||||
const FileInput: FC<Props> = ({
|
||||
name,
|
||||
filenamePlaceholder,
|
||||
testId,
|
||||
helpText,
|
||||
placeholder,
|
||||
disabled,
|
||||
label,
|
||||
className,
|
||||
ref,
|
||||
onBlur,
|
||||
onChange,
|
||||
}) => {
|
||||
const [t] = useTranslation("commons");
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const FileInput = React.forwardRef<HTMLInputElement, Props>(
|
||||
({ name, filenamePlaceholder, testId, helpText, placeholder, disabled, label, className, onBlur, onChange }, ref) => {
|
||||
const [t] = useTranslation("commons");
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
|
||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const uploadedFile = event?.target?.files![0];
|
||||
// @ts-ignore the uploaded file doesn't match our types
|
||||
setFile(uploadedFile);
|
||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const uploadedFile = event?.target?.files![0];
|
||||
// @ts-ignore the uploaded file doesn't match our types
|
||||
setFile(uploadedFile);
|
||||
|
||||
if (onChange && event.target.files) {
|
||||
onChange(event);
|
||||
}
|
||||
};
|
||||
if (onChange && event.target.files) {
|
||||
onChange(event);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = (event: FocusEvent<HTMLInputElement>) => {
|
||||
if (onBlur && event.target.files) {
|
||||
onBlur(event);
|
||||
}
|
||||
};
|
||||
const handleBlur = (event: FocusEvent<HTMLInputElement>) => {
|
||||
if (onBlur && event.target.files) {
|
||||
onBlur(event);
|
||||
}
|
||||
};
|
||||
|
||||
const id = createA11yId("file-input");
|
||||
const id = createA11yId("file-input");
|
||||
|
||||
return (
|
||||
<div className={classNames("field", className)}>
|
||||
<LabelWithHelpIcon label={label} helpText={helpText} id={id} />
|
||||
<div className="file is-info has-name is-fullwidth">
|
||||
<label className="file-label">
|
||||
<input
|
||||
ref={ref}
|
||||
name={name}
|
||||
className="file-input"
|
||||
type="file"
|
||||
placeholder={placeholder}
|
||||
disabled={disabled}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
aria-describedby={id}
|
||||
{...createAttributesForTesting(testId)}
|
||||
/>
|
||||
<span className="file-cta">
|
||||
<span className="file-icon">
|
||||
<i className="fas fa-arrow-circle-up" />
|
||||
return (
|
||||
<div className={classNames("field", className)}>
|
||||
<LabelWithHelpIcon label={label} helpText={helpText} id={id} />
|
||||
<div className="file is-info has-name is-fullwidth">
|
||||
<label className="file-label">
|
||||
<input
|
||||
ref={ref}
|
||||
name={name}
|
||||
className="file-input"
|
||||
type="file"
|
||||
placeholder={placeholder}
|
||||
disabled={disabled}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
aria-describedby={id}
|
||||
{...createAttributesForTesting(testId)}
|
||||
/>
|
||||
<span className="file-cta">
|
||||
<span className="file-icon">
|
||||
<i className="fas fa-arrow-circle-up" />
|
||||
</span>
|
||||
<span className="file-label has-text-weight-bold">{t("fileInput.label")}</span>
|
||||
</span>
|
||||
<span className="file-label has-text-weight-bold">{t("fileInput.label")}</span>
|
||||
</span>
|
||||
{file?.name ? (
|
||||
<span className="file-name">{file?.name}</span>
|
||||
) : (
|
||||
<span className="file-name has-text-weight-light has-text-secondary">
|
||||
{filenamePlaceholder || t("fileInput.noFileChosen")}
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
{file?.name ? (
|
||||
<span className="file-name">{file?.name}</span>
|
||||
) : (
|
||||
<span className="file-name has-text-weight-light has-text-secondary">
|
||||
{filenamePlaceholder || t("fileInput.noFileChosen")}
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default FileInput;
|
||||
|
||||
Reference in New Issue
Block a user