extract component

This commit is contained in:
Pig Fang 2020-03-10 15:57:57 +08:00
parent cd2f977bff
commit 59f8f33df7
5 changed files with 79 additions and 40 deletions

View File

@ -0,0 +1,46 @@
import React, { useRef } from 'react'
import { t } from '@/scripts/i18n'
import styles from './FileInput.module.scss'
interface Props {
file: File | null
accept?: string
onChange(event: React.ChangeEvent<HTMLInputElement>): void
}
const FileInput: React.FC<Props> = props => {
const ref = useRef<HTMLInputElement>(null)
const handleClick = () => {
ref.current!.click()
}
return (
<div className="form-group">
<label htmlFor="select-file">{t('skinlib.upload.select-file')}</label>
<div className="input-group">
<div className="custom-file">
<input
type="file"
className="custom-file-input"
id="select-file"
accept={props.accept}
title={t('skinlib.upload.select-file')}
ref={ref}
onChange={props.onChange}
/>
<label className={`custom-file-label ${styles.label}`}>
{props.file?.name}
</label>
</div>
<div className="input-group-append">
<button className="btn btn-default" onClick={handleClick}>
{t('skinlib.upload.select-file')}
</button>
</div>
</div>
</div>
)
}
export default FileInput

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useRef } from 'react'
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
import { hot } from 'react-hot-loader/root'
import { t } from '@/scripts/i18n'
@ -7,8 +7,8 @@ import * as fetch from '@/scripts/net'
import { showModal, toast } from '@/scripts/notify'
import { isAlex } from '@/scripts/textureUtils'
import { TextureType } from '@/scripts/types'
import FileInput from '@/components/FileInput'
import ViewerSkeleton from '@/components/ViewerSkeleton'
import styles from './styles.module.scss'
const Previewer = React.lazy(() => import('@/components/Viewer'))
@ -21,7 +21,6 @@ const Upload: React.FC = () => {
const [isUploading, setIsUploading] = useState(false)
const [file, setFile] = useState<File | null>(null)
const [texture, setTexture] = useState('')
const fileInput = useRef<HTMLInputElement>(null)
const nameRule = useBlessingExtra<string>('rule')
const contentPolicy = useBlessingExtra<string>('contentPolicy')
const privacyNotice = useBlessingExtra<string>('privacyNotice')
@ -51,11 +50,7 @@ const Upload: React.FC = () => {
setIsPrivate(event.target.checked)
}
const invokeSelectFile = () => {
fileInput.current!.click()
}
const handleSelectFile = async (
const handleFileChange = async (
event: React.ChangeEvent<HTMLInputElement>,
) => {
const files = event.target.files!
@ -177,32 +172,11 @@ const Upload: React.FC = () => {
{t('general.cape')}
</label>
</div>
<div className="form-group">
<label htmlFor="select-file">
{t('skinlib.upload.select-file')}
</label>
<div className="input-group">
<div className="custom-file">
<input
type="file"
className="custom-file-input"
id="select-file"
accept="image/png, image/x-png"
title={t('skinlib.upload.select-file')}
ref={fileInput}
onChange={handleSelectFile}
/>
<label className={`custom-file-label ${styles.label}`}>
{file?.name}
</label>
</div>
<div className="input-group-append">
<button className="btn btn-default" onClick={invokeSelectFile}>
{t('skinlib.upload.select-file')}
</button>
</div>
</div>
</div>
<FileInput
file={file}
accept="image/png, image/x-png"
onChange={handleFileChange}
/>
{contentPolicy && (
<div

View File

@ -0,0 +1,25 @@
import React from 'react'
import { render, fireEvent } from '@testing-library/react'
import { t } from '@/scripts/i18n'
import FileInput from '@/components/FileInput'
test('click to select file', () => {
const { getAllByText } = render(<FileInput file={null} onChange={() => {}} />)
fireEvent.click(getAllByText(t('skinlib.upload.select-file'))[1])
})
test('display file name', () => {
const file = new File([], 'f.txt')
const { queryByText } = render(<FileInput file={file} onChange={() => {}} />)
expect(queryByText('f.txt')).toBeInTheDocument()
})
test('input file', () => {
const mock = jest.fn()
const { getByLabelText } = render(<FileInput file={null} onChange={mock} />)
fireEvent.change(getByLabelText(t('skinlib.upload.select-file')))
expect(mock).toBeCalled()
})

View File

@ -60,12 +60,6 @@ test('award notice', () => {
).not.toBeInTheDocument()
})
test('invoke selecting file', () => {
const { getAllByText } = render(<Upload />)
fireEvent.click(getAllByText(t('skinlib.upload.select-file'))[1])
})
describe('input file', () => {
it('cancelled', () => {
const { getByTitle } = render(<Upload />)