stories/organisms/components/filePicker/FilePicker.stories.mdx
import { ArgsTable, Meta, Source, Story, Canvas, Preview, Props } from '@storybook/addon-docs'
import { FilePicker } from 'ui/organisms/filePicker/FilePicker'
import { Typography } from 'ui/atoms/typography/Typography'
import { ThemeProvider } from 'ui/atoms/theme/ThemeProvider'
import { ThemeSwitcher } from 'ui/atoms/theme/ThemeSwitcher'
import { StoreProvider } from 'ui/providers/storeProvider'
import cosmosDark from 'assets/images/cosmos-dark.png'
import cosmosLight from 'assets/images/cosmos-clear.png'
import { useTheme } from 'hook/useTheme'
import { default as storeParameters } from './store'
<Meta
title="Organisms/FilePicker"
component={FilePicker}
decorators={[
Story => (
<ThemeProvider>
<div className="story-theme-switcher">
<ThemeSwitcher />
</div>
<StoreProvider storeParameters={storeParameters}>
<div className="component-story-main filePicker">
<Story />
</div>
</StoreProvider>
</ThemeProvider>
)
]}
/>
# OKP4 File Picker
> Allows the selection, the deselection and the visualization of files.
[![stability-unstable](https://img.shields.io/badge/stability-unstable-yellow.svg)](https://github.com/emersion/stability-badges#unstable)
## Description
FilePicker allows to input files and display them in a list.
It is a combination of the [FileInput](/docs/atoms-fileinput--overview) and the [List](/docs/atoms-list--overview) (with [Listitem](/docs/atoms-listitem--overview)) components.
## Overview
<Story
name="Overview"
argTypes={{
description: {
control: false,
table: {
type: { summary: 'Node' }
}
},
acceptedFormats: {
control: 'object',
table: {
type: { summary: 'string[]' }
}
}
}}
args={{
label: 'Drop your files here, or browse',
multiple: true,
acceptedFormats: ['image/*', '.csv'],
size: 'large',
showClearAll: false
}}
>
{args => {
const { theme } = useTheme()
return (
<div
style={{
display: 'flex',
width: '80%',
margin: 'auto',
backgroundImage: `url(${theme === 'dark' ? cosmosDark : cosmosLight})`,
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat'
}}
>
<FilePicker
{...args}
description={
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<Typography as="div" fontFamily="brand" fontSize="small" fontWeight="xlight">
Supports images like .png, .jpg, .jpeg, etc. and CSV files
</Typography>
</div>
}
/>
</div>
)
}}
</Story>
## Properties
<ArgsTable story="Overview" />
## Show clear all
Need to clear all selected files at once?
We thought it would be handy to offer you a turnkey way to do it!
For that, you only have to pass `showClearAll` to the filePicker and that's it!
The displayed text is themed and internationalized (english and french) and fits harmoniously above the list.
By default the `showClearAll` value is **false**.
<Canvas>
<Story name="Show clear all">
<div
style={{
display: 'flex'
}}
>
<FilePicker
label="Drop your files here, or browse"
showClearAll
description={
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<Typography as="div" fontFamily="brand" fontSize="small" fontWeight="xlight">
Display `Clear all` to remove all the selected files.
</Typography>
</div>
}
/>
</div>
</Story>
</Canvas>
## Usage
To configure the FilePicker, the [@okp4/ui](https://www.npmjs.com/package/@okp4/ui) library provides all the necessary elements. You will just have to follow these two steps:
### 1. Instantiate redux stores
To work, FilePicker uses [redux](https://redux.js.org/) as a state manager and an **eventBus** instance to facilitate communication between the business domains.
To do this, all you have to do is declare the store parameters in a **store.ts** file to be able to import them later into a Provider component that will take care of injecting them into the React context.
**`store.ts`**
```ts
import { List } from 'immutable'
import { FileStoreBuilder } from 'domain/file/store/builder/store.builder'
import { FileContext } from 'context/storeContext/fileContext'
import { createEventBusInstance } from 'eventBus/index'
import type { StoreParameter } from 'ui/providers/storeProvider'
import 'domain/error/index'
/** Init an eventBus instance
* Needed to enable communication and reactivity beetwen business domains
*/
const eventBusInstance = createEventBusInstance()
/**
* Init the redux store
*/
const fileStore = new FileStoreBuilder().withEventBus(eventBusInstance).build()
const fileStoreParameter: StoreParameter = [FileContext, fileStore]
export default List([fileStoreParameter])
```
### 2. Wrap the FilePicker component into a store provider
Finally, it is necessary to wrap the FilePicker in a StoreProvider which will auto-inject into the React context the configuration elements necessary for its proper functioning.
This StoreProvider component is directly provided by the `@okp4/ui` library, you simply have to pass it the parameters exported by the **store.ts** file as properties.
**`app.tsx`**
```tsx
import React from 'react'
import { FilePicker, StoreProvider } from '@okp4/ui'
import * as storeParameters from './store'
export const App: React.FC = () => (
<StoreProvider storeParameters={storeParameters}>
<FilePicker />
</StoreProvider>
)
```
And, that's it!