stories/organisms/components/filePicker/FilePicker.stories.mdx

Summary

Maintainability
Test Coverage
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!