github.com/pluralsh/plural-cli@v0.9.5/pkg/ui/web/src/routes/installer/ConfigurationFileInput.tsx (about) 1 import { FileInput } from 'grommet' 2 import { ThemeContext } from 'grommet/contexts' 3 import { Span } from 'honorable' 4 import { ComponentProps, useCallback, useState } from 'react' 5 import { useTheme } from 'styled-components' 6 7 import { fileInputTheme } from '../../grommet/fileInputTheme' 8 9 export default function ConfigurationFileInput({ 10 value, 11 onChange, ...props 12 }: { onChange: (f:{file: File | null, text: string}) => void; value: string } & Omit< 13 ComponentProps<typeof FileInput>, 'onChange' 14 >) { 15 const [fileSelected, setFileSelected] = useState<boolean>(!!value) 16 const theme = useTheme() 17 18 const readFile = useCallback(async (files: FileList | undefined | null) => { 19 setFileSelected(false) 20 21 const file = files?.item(0) ?? null 22 const text = await file?.text() ?? '' 23 24 setFileSelected(!!file) 25 onChange({ text, file }) 26 }, 27 [onChange]) 28 29 const messages = value ? { dropPrompt: '********', browse: 'Choose a different file' } : { 30 dropPrompt: 'Drop your file here', 31 browse: 'Select file', 32 } 33 34 return ( 35 <ThemeContext.Extend value={fileInputTheme({ selected: fileSelected, theme })}> 36 <FileInput 37 messages={messages} 38 multiple={false} 39 onChange={event => readFile(event?.target?.files)} 40 renderFile={file => ( 41 <Span 42 margin="small" 43 color="text-light" 44 > 45 {file.name} 46 </Span> 47 )} 48 {...props} 49 /> 50 </ThemeContext.Extend> 51 ) 52 }