Skip to content

Commit 8e8d608

Browse files
Merge pull request #325 from dd3tech/fix/input-file-name
Fix(InputFile): Added the props fileName and isLoading
2 parents c0a94a5 + 9e12ea7 commit 8e8d608

1 file changed

Lines changed: 108 additions & 54 deletions

File tree

src/components/Form/Input/InputFile.tsx

Lines changed: 108 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { composeClasses } from 'lib/classes'
1515
import { Flex } from 'components/Layout'
1616
import Tooltip from 'components/Tooltip'
1717
import { Button } from 'components/Buttons'
18+
import Skeleton from 'components/Skeleton'
19+
import Spinner from 'components/Spinner'
1820
import ProgressBar from '../../ProgressBar/ProgressBar'
1921
import Text from '../../Typography/Text'
2022

@@ -31,6 +33,11 @@ export interface InputFileProps extends React.HTMLProps<HTMLInputElement> {
3133
onView?: (e: React.MouseEvent<HTMLButtonElement>) => void
3234
onDownload?: (e: React.MouseEvent<HTMLButtonElement>) => void
3335
onDelete?: (e: React.MouseEvent<HTMLButtonElement>) => void
36+
fileName?: string
37+
isLoading?: boolean
38+
isLoadingDelete?: boolean
39+
isLoadingDownload?: boolean
40+
isLoadingView?: boolean
3441
}
3542

3643
export function InputFile({
@@ -93,22 +100,51 @@ export function InputFile({
93100
* is a function that works to delete the file
94101
*/
95102
onDelete,
103+
/**
104+
* is a file that works to set the value of the file
105+
*/
106+
fileName,
107+
/**
108+
* is a boolean that works to indicate if the file is loading
109+
*/
110+
isLoading,
111+
/**
112+
* is a boolean that works to indicate if the file is loading
113+
*/
114+
isLoadingDelete,
115+
/**
116+
* is a boolean that works to indicate if the file is loading
117+
*/
118+
isLoadingDownload,
119+
/**
120+
* is a boolean that works to indicate if the file is loading
121+
*/
122+
isLoadingView,
96123
...otherProps
97124
}: InputFileProps) {
98125
const [isDrag, setIsDrag] = useState<boolean>(false)
99-
const [file, setFile] = useState<FileList | null>(null)
126+
const [fileList, setFileList] = useState<FileList | null>(null)
127+
100128
const disabled = otherProps.disabled || false
101129

102130
const handleChange = useCallback(
103131
(event: ChangeEvent<HTMLInputElement>) => {
104132
if (disabled) return
105133
setIsDrag(false)
106-
setFile(event.target.files)
134+
setFileList(event.target.files)
107135
onChange && onChange(event)
108136
},
109137
[isDrag, onChange]
110138
)
111139

140+
const handleDelete = useCallback(
141+
(e: React.MouseEvent<HTMLButtonElement>) => {
142+
setFileList(null)
143+
onDelete && onDelete(e)
144+
},
145+
[onDelete]
146+
)
147+
112148
return (
113149
<label
114150
role={roleContainer}
@@ -129,7 +165,7 @@ export function InputFile({
129165
</Tooltip>
130166
)}
131167
</Flex>
132-
{!(singleFile && file?.length) && (
168+
{!(singleFile && fileList?.length) && !!(singleFile && !fileName) && (
133169
<Flex alignItems="center" gap="2">
134170
<UploadIcon className="w-4 h-4 text-blue-700" />
135171
<Text variant="small" className="text-blue-700">
@@ -158,6 +194,7 @@ export function InputFile({
158194
if (disabled) return
159195
setIsDrag(true)
160196
}}
197+
multiple={!singleFile}
161198
disabled={progressIndicator >= 1 || disabled}
162199
className={composeClasses(
163200
'opacity-0 absolute top-0 left-0 bottom-0 right-0',
@@ -179,7 +216,7 @@ export function InputFile({
179216
<UploadIcon className="w-4 h-4 text-gray-400 flex-shrink-0" />
180217
<Flex className="w-full flex-col" gap="1">
181218
<Text textMuted500 style={{ fontSize: '10px' }}>
182-
{file?.item(0)?.name}
219+
{fileList?.item(0)?.name}
183220
</Text>
184221
<ProgressBar
185222
value={progressIndicator}
@@ -190,57 +227,74 @@ export function InputFile({
190227
</Flex>
191228
</Flex>
192229
)}
193-
{singleFile && file?.length === 1 && !error?.show && (
194-
<Flex
195-
justifyContent="between"
196-
alignItems="center"
197-
gap="2"
198-
className="w-full z-10"
199-
onClick={(e) => {
200-
e.preventDefault()
201-
e.stopPropagation()
202-
}}
203-
>
204-
<Flex alignItems="center" gap="2">
205-
<PaperClipIcon className="w-4 h-4 text-gray-400 flex-shrink-0" />
206-
<Text size="xs" className="whitespace-nowrap">
207-
{file.item(0)?.name}
208-
</Text>
230+
{isLoading && <Skeleton className="w-full h-5 rounded-full" />}
231+
{singleFile &&
232+
(fileList?.length === 1 || fileName) &&
233+
!error?.show &&
234+
!isLoading &&
235+
!progressIndicator && (
236+
<Flex
237+
justifyContent="between"
238+
alignItems="center"
239+
gap="2"
240+
className="w-full z-10"
241+
onClick={(e) => {
242+
e.preventDefault()
243+
e.stopPropagation()
244+
}}
245+
>
246+
<Flex alignItems="center" gap="2">
247+
<PaperClipIcon className="w-4 h-4 text-gray-400 flex-shrink-0" />
248+
<Text size="xs" className="whitespace-nowrap">
249+
{fileList?.item(0)?.name || fileName}
250+
</Text>
251+
</Flex>
252+
<Flex alignItems="center" gap="2">
253+
{onView && (
254+
<Button
255+
variant="ghost"
256+
padding="0.5"
257+
className="rounded-full"
258+
onClick={onView}
259+
>
260+
{isLoadingView ? (
261+
<Spinner width="18px" height="18px" color="#1D4ED8" />
262+
) : (
263+
<EyeIcon className="w-4 h-4 text-gray-400 flex-shrink-0 cursor-pointer" />
264+
)}
265+
</Button>
266+
)}
267+
{onDownload && (
268+
<Button
269+
variant="ghost"
270+
padding="0.5"
271+
className="rounded-full"
272+
onClick={onDownload}
273+
>
274+
{isLoadingDownload ? (
275+
<Spinner width="18px" height="18px" color="#1D4ED8" />
276+
) : (
277+
<DownloadIcon className="w-4 h-4 text-gray-400 flex-shrink-0" />
278+
)}
279+
</Button>
280+
)}
281+
{onDelete && (
282+
<Button
283+
variant="ghost"
284+
padding="0.5"
285+
className="rounded-full"
286+
onClick={handleDelete}
287+
>
288+
{isLoadingDelete ? (
289+
<Spinner width="18px" height="18px" color="#DC2626" />
290+
) : (
291+
<TrashIcon className="w-4 h-4 text-red-500 flex-shrink-0" />
292+
)}
293+
</Button>
294+
)}
295+
</Flex>
209296
</Flex>
210-
<Flex alignItems="center" gap="2">
211-
{onView && (
212-
<Button
213-
variant="ghost"
214-
padding="0.5"
215-
className="rounded-full"
216-
onClick={onView}
217-
>
218-
<EyeIcon className="w-4 h-4 text-gray-400 flex-shrink-0 cursor-pointer" />
219-
</Button>
220-
)}
221-
{onDownload && (
222-
<Button
223-
variant="ghost"
224-
padding="0.5"
225-
className="rounded-full"
226-
onClick={onDownload}
227-
>
228-
<DownloadIcon className="w-4 h-4 text-gray-400 flex-shrink-0" />
229-
</Button>
230-
)}
231-
{onDelete && (
232-
<Button
233-
variant="ghost"
234-
padding="0.5"
235-
className="rounded-full"
236-
onClick={onDelete}
237-
>
238-
<TrashIcon className="w-4 h-4 text-red-500 flex-shrink-0" />
239-
</Button>
240-
)}
241-
</Flex>
242-
</Flex>
243-
)}
297+
)}
244298
</div>
245299
</label>
246300
)

0 commit comments

Comments
 (0)