/* * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import type { PropsWithDataCypressId } from '../../utils/cypress-attribute' import { cypressId } from '../../utils/cypress-attribute' import { Logger } from '../../utils/logger' import type { MutableRefObject } from 'react' import React, { useCallback, useEffect, useRef } from 'react' const log = new Logger('UploadInput') export interface UploadInputProps extends PropsWithDataCypressId { onLoad: (file: File) => Promise | void allowedFileTypes: string onClickRef: MutableRefObject<(() => void) | undefined> } /** * Renders an input field to upload something. * * @param onLoad The callback to load the file. * @param allowedFileTypes A string indicating mime-types or file extensions. * @param onClickRef A reference for the onClick handler of the input. * @param props Additional props given to the input. */ export const UploadInput: React.FC = ({ onLoad, allowedFileTypes, onClickRef, ...props }) => { const fileInputReference = useRef(null) const onClick = useCallback(() => { fileInputReference.current?.click() }, []) const onChange = useCallback>( async (event) => { const fileInput = event.currentTarget if (!fileInput.files || fileInput.files.length < 1) { return } const file = fileInput.files[0] try { const loadResult = onLoad(file) if (loadResult instanceof Promise) { await loadResult } } catch (error) { log.error('Error while uploading file', error) } finally { fileInput.value = '' } }, [onLoad] ) useEffect(() => { onClickRef.current = onClick }) return ( ) }