import { css, cx } from '@emotion/css'; import React, { FC, FormEvent, useCallback, useState } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { stylesFactory, useTheme2 } from '../../themes'; import { ComponentSize } from '../../types/size'; import { trimFileName } from '../../utils/file'; import { getButtonStyles } from '../Button'; import { Icon } from '../index'; export interface Props { /** Callback function to handle uploaded file */ onFileUpload: (event: FormEvent) => void; /** Accepted file extensions */ accept?: string; /** Overwrite or add to style */ className?: string; /** Button size */ size?: ComponentSize; } export const FileUpload: FC = ({ onFileUpload, className, children = 'Upload file', accept = '*', size = 'md', }) => { const theme = useTheme2(); const style = getStyles(theme, size); const [fileName, setFileName] = useState(''); const onChange = useCallback( (event: FormEvent) => { const file = event.currentTarget?.files?.[0]; if (file) { setFileName(file.name ?? ''); } onFileUpload(event); }, [onFileUpload] ); return ( <> {fileName && ( {trimFileName(fileName)} )} ); }; const getStyles = stylesFactory((theme: GrafanaTheme2, size: ComponentSize) => { const buttonStyles = getButtonStyles({ theme, variant: 'primary', size, iconOnly: false }); return { fileUpload: css` display: none; `, button: buttonStyles.button, icon: buttonStyles.icon, fileName: css` margin-left: ${theme.spacing(0.5)}; `, }; });