Skip to content

Commit c539f84

Browse files
feat(file-upload)!: replace FileUpload with React Aria FileTrigger
Fixes issues with Midas FileUpload that was reporting `onSelect`. List of files is removed to keep the component stateless, set it up in the ui instead. BREAKING CHANGE: FileUpload is removed and replaced by FileTrigger. Aligns API exactly with React Aria
1 parent e267f19 commit c539f84

File tree

11 files changed

+293
-400
lines changed

11 files changed

+293
-400
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: FileTrigger
3+
description: Åtkomst till filsystemet
4+
---
5+
6+
import { Button } from '@midas-ds/components'
7+
import { FileTrigger } from 'react-aria-components'
8+
import { ComponentHeader } from '@site/src/components/getComponentMetaData'
9+
import { Example, DropZoneExample } from '@site/src/components/examples/file-upload/FileUploadExamples'
10+
import { PropTable } from '@site/src/components/PropsTable'
11+
12+
<ComponentHeader
13+
name='FileTrigger'
14+
friendlyName='Filuppladdning, filväljare'
15+
overrideHeadlessLink='https://react-spectrum.adobe.com/react-aria/FileTrigger.html'
16+
/>
17+
18+
[FileTrigger](https://react-spectrum.adobe.com/react-aria/FileTrigger.html) från React Aria gör det möjligt för en användare
19+
att komma åt filsystemet via valfri tryckbar React Aria-komponent, som till exempel [Button](/components/button).
20+
Se [API](#api) eller [officiell dokumentation](https://react-spectrum.adobe.com/react-aria/FileTrigger.html) för hur den kan användas.
21+
FileTrigger är en komponent utan utseende och går att använda direkt från React Aria eller importeras från Midas. DropZone
22+
har en enkelt stylad yta men med samma beteende som React Aria.
23+
24+
```tsx
25+
26+
import { Button } from '@midas-ds/components'
27+
import { FileTrigger } from 'react-aria-components'
28+
import React from 'react'
29+
30+
export const Example = () => {
31+
let [file, setFile] = React.useState(null);
32+
33+
return (
34+
<>
35+
<FileTrigger
36+
onSelect={(e) => {
37+
let files = e ? Array.from(e) : [];
38+
let filenames = files.map((file) => file.name);
39+
setFile(filenames);
40+
}}>
41+
<Button>Välj fil</Button>
42+
</FileTrigger>
43+
{file && file}
44+
</>
45+
)
46+
}
47+
```
48+
<div className={'card'}>
49+
<Example/>
50+
</div>
51+
52+
## Varianter
53+
54+
Se [API](#api) samt [React Aria](https://react-spectrum.adobe.com/react-aria/FileTrigger.html) för samtliga
55+
möjligheter.
56+
57+
### Drag & drop
58+
59+
Använd FileTrigger tillsammans med [DropZone](https://react-spectrum.adobe.com/react-aria/DropZone.html)
60+
för att tillåta val av filer via drag & drop.
61+
62+
```tsx
63+
export const DropZoneExample = () => {
64+
let [files, setFiles] = React.useState(null);
65+
return (
66+
<>
67+
<DropZone
68+
onDrop={(e) => {
69+
let files = e.items.filter((file) =>
70+
file.kind === 'file'
71+
) as FileDropItem[];
72+
let filenames = files.map((file) => file.name);
73+
setFiles(filenames.join(', '));
74+
}}
75+
>
76+
<FileTrigger
77+
allowsMultiple
78+
onSelect={(e) => {
79+
let files = Array.from(e);
80+
let filenames = files.map((file) => file.name);
81+
setFiles(filenames.join(', '));
82+
}}
83+
>
84+
<Button>Select files</Button>
85+
</FileTrigger>
86+
<Text slot="label" style={{ display: 'block' }}>
87+
{files || 'Drop files here'}
88+
</Text>
89+
</DropZone>
90+
</>
91+
)
92+
}
93+
```
94+
95+
<DropZoneExample/>
96+
97+
### Alternativ
98+
99+
För att tillåta användaren att ladda upp flera filer på samma gång, använd attributet `allowsMultiple`, för att
100+
begränsa valbara filtyper, använd `acceptedFileTypes`.
101+
102+
### Media Capture
103+
104+
På mobila enheter kan användaren använda enhetens kamera för att välja media. `defaultCamera` väljer vilken kamera som
105+
används.
106+
107+
```tsx
108+
<FileTrigger defaultCamera={'environment'}>
109+
<Button>Öppna kameran</Button>
110+
</FileTrigger>
111+
```
112+
113+
<div className='card'>
114+
<FileTrigger defaultCamera={'environment'}>
115+
<Button>Öppna kameran</Button>
116+
</FileTrigger>
117+
</div>
118+
119+
120+
121+
## API
122+
123+
### FileTrigger
124+
<PropTable name='FileTrigger' />
125+
126+
### DropZone
127+
<PropTable name='DropZone' />
128+
129+

apps/docs/docs/components/fileupload.mdx

Lines changed: 0 additions & 92 deletions
This file was deleted.
Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,52 @@
1-
import { FileUpload } from '@midas-ds/components'
1+
import { Button, DropZone, FileTrigger, Text } from '@midas-ds/components'
22
import React from 'react'
3+
import { DropEvent } from 'react-aria'
34

4-
export const ControlledExample = () => {
5+
export const Example = () => {
56
const [files, setFiles] = React.useState<string[]>([])
67

78
return (
89
<>
9-
<FileUpload
10-
allowsMultiple
11-
label='Välj filer att ladda upp'
12-
description='Du kan välja flera filer'
13-
onSelect={e => {
14-
if (e) {
15-
const files = Array.from(e)
16-
const filenames = files.map(file => file.name)
17-
setFiles(filenames)
18-
}
10+
<FileTrigger
11+
onSelect={(e: FileList | null) => {
12+
const selectedFiles = e ? Array.from(e) : []
13+
const filenames = selectedFiles.map(file => file.name)
14+
setFiles(filenames)
1915
}}
20-
/>
21-
Valda filer: {files.join(', ')}
16+
>
17+
<Button>Välj fil</Button>
18+
</FileTrigger>
19+
{files.length > 0 && <Text>{files.join(', ')}</Text>}
2220
</>
2321
)
2422
}
23+
24+
export const DropZoneExample = () => {
25+
const [files, setFiles] = React.useState<string[]>([])
26+
27+
const handleDrop = async (e: DropEvent) => {
28+
const fileItems = e.items.filter(item => item.kind === 'file')
29+
const droppedFiles: File[] = await Promise.all(
30+
fileItems.map(item => item.getFile()),
31+
)
32+
const filenames = droppedFiles.map(file => file.name)
33+
setFiles(prev => [...prev, ...filenames])
34+
}
35+
36+
const handleSelect = (e: FileList | null) => {
37+
const selectedFiles = e ? Array.from(e) : []
38+
const filenames = selectedFiles.map(file => file.name)
39+
setFiles(prev => [...prev, ...filenames])
40+
}
41+
42+
return (
43+
<DropZone onDrop={handleDrop}>
44+
<FileTrigger allowsMultiple onSelect={handleSelect}>
45+
<Button>Select files</Button>
46+
</FileTrigger>
47+
<Text slot="label" style={{ display: 'block' }}>
48+
{files.length > 0 ? files.join(', ') : 'Drop files here'}
49+
</Text>
50+
</DropZone>
51+
)
52+
}

apps/docs/src/components/mvdsExports.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
LinkButton,
1414
SearchField,
1515
Tabs,
16-
FileUpload,
1716
Flex,
1817
FlexItem,
1918
Grid,
@@ -40,7 +39,6 @@ export {
4039
CheckboxGroup,
4140
Logo,
4241
TextField,
43-
FileUpload,
4442
Radio,
4543
RadioGroup,
4644
Breadcrumbs,

0 commit comments

Comments
 (0)