npm package: @paprika/list-box-browser
Description: ListBox Browser component is a two column layout that allows users to select one or multiple options. It is similar to the experience of browsing a file manager in any operating system.
Author: @paprika
Latest version: 4.0.4

<!-- start: Autogenerated - do not modify -->

# @paprika/list-box-browser

## Description

ListBox Browser component is a two column layout that allows users to select one or multiple options. It is similar to the experience of browsing a file manager in any operating system.

## Installation

```
yarn add @paprika/list-box-browser
```

or with npm:

```
npm install @paprika/list-box-browser
```

## Props

### ListBoxBrowser

| Prop                   | Type   | required | default     | Description                                                                                                                                                                                                                                                              |
| ---------------------- | ------ | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| data                   | any    | true     | -           | An array of javascript objects holding the data structure for the ListBoxBrowser. The object shape must have at least a string label property and an array options property in one of the objects. Also can hold any other kind of data for your own use.                |
| isMulti                | bool   | false    | true        | Indicates if the user can select multiple options                                                                                                                                                                                                                        |
| height                 | number | false    | 220         | Set the height for the ListBoxBrowser                                                                                                                                                                                                                                    |
| onChange               | func   | false    | () => {}    | Callback function receiving an array of selected options by the component                                                                                                                                                                                                |
| isParentSelectable     | bool   | false    | null        | Allows the user to select the parent options                                                                                                                                                                                                                             |
| rootTitle              | node   | false    | ""          | Content title for the left column                                                                                                                                                                                                                                        |
| browserTitle           | node   | false    | ""          | Content title for the right column                                                                                                                                                                                                                                       |
| children               | node   | false    | null        | You can pass <ListBoxBrowser.OptionSelected /> as a children                                                                                                                                                                                                             |
| hasBreadcrumb          | bool   | false    | true        | Indicates if the right column should display a breadcrumb                                                                                                                                                                                                                |
| hasError               | bool   | false    | false       | Set a border red color around the component indicating that has an error                                                                                                                                                                                                 |
| onFetch                | func   | false    | null        | When declaring the array options empty, this will be executed to retrieve the data, useful if you want to do a lazy load.                                                                                                                                                |
| defaultSelectedOptions | func   | false    | () => false | A function that sets an option selected returning true or false you can use to compare your data structure and decide if the option is initially selected or not.                                                                                                        |
| defaultSelectedView    | func   | false    | null        | A function that sets the initial view for the right columns (Browser) of the ListBoxBrowser the option selected to be the initial view should have options to be valid, by default the ListBoxBrowser picked the first option which has options to be the initial value. |
| hasLeftColumn          | bool   | false    | true        | In the case you want to use the ListBoxBrowser with one column you can hide the root column                                                                                                                                                                              |

### CustomListBox

| Prop            | Type            | required | default  | Description |
| --------------- | --------------- | -------- | -------- | ----------- |
| hasOnUp         | bool            | false    | false    |             |
| id              | [string,number] | false    | "root"   |             |
| isLoading       | bool            | false    | false    |             |
| onChange        | func            | true     | -        |             |
| onClickNavigate | func            | true     | -        |             |
| onUp            | func            | false    | () => {} |             |
| options         | arrayOf         | true     | -        |             |

### Title

| Prop              | Type            | required | default | Description |
| ----------------- | --------------- | -------- | ------- | ----------- |
| rootTitle         | node            | true     | -       |             |
| browserTitle      | node            | true     | -       |             |
| data              | arrayOf         | false    | -       |             |
| browserKey        | [string,number] | true     | -       |             |
| onClickBreadcrumb | func            | true     | -       |             |
| hasLeftColumn     | bool            | true     | -       |             |

<!-- end: Autogenerated - do not modify -->
<!-- content -->

## Usage

The `<ListBoxBrowser />` is primarily an uncontrolled component which receives a `data` prop which allows the consumer to set the initial state.

It has two functions to set defaults. One for selected options and another for a default selected view for the browser column.

The `onChange` prop receives a parameter with an array of the selected options.

### Data prop

The most important prop for the `<ListBoxBrowser />` is the `data` prop, which initializes the state for the component.

The `data` prop is an array of objects where each object requires to have at least a `label` attribute on it and at least one of those items should include an `options` property.

### Data prop shape

```js
[{ label: "One" }, { label: "Two", options: [{ label: "Three" }] }];
```

```js
{
	label: "require attribute",
	options: [{}{}{}], // more object with the same shape
}
```

The **object** can have an options attribute, which is an array of the same kind of objects.

A data prop with **options** looks like:

```js
const data = [
   {
        label: "NBA",
        options: [{ label: "Toronto Raptors"}, {...}]
   },
   {
        label: "NHL",
        options: [{ label: "Vancouver Canucks"}, {...}]
   },
   {
        label: "MLS",
        options: [{ label: "Vancouver Whitecaps"}, {...}]
   },
]
```

Recursively the component runs over all the options on the array and assembles the UI for the user.

**NOTE** You can add extra properties to the objects; those are and pass to you back on the `onChange` function or when using `defaultSelectedOptions`, `defaultSelectedView` functions.

---

#### Basic example

```jsx
import ListBoxBrowser from "@paprika/list-box-browser";

export default function App() {
   const data = [{...}...{...}]; // your data;
   return <ListBoxBrowser data={data} />
}
```

---

#### ListBoxBrowser.SelectedOptions

By default, the `<ListBoxBrowser />` does not display a list of the selected options.
But you can activate this feature to display multiple options using the `<ListBoxBrowser.SelectedOptions />` subcomponent.

```jsx
<ListBoxBrowser data={data}>
  <ListBoxBrowser.SelectedOptions />
</ListBoxBrowser>
```

#### defaultSelectedOptions

The `defaultSelectedOptions` receives a function to be executed to determine if an option should start as selected or not. This function is called as options are passed down on the data prop.

Ex.

```jsx
const data = [{ key: 1, label: "one", options: [...] }, { key: 2, label: "two" }, { key: 3, label: "three" }]

<ListBoxBrowser data={data} defaultSelectedOptions={(option) => {
  return option.key === 2 or option.key === 3
}} />
```

```jsx
const data = [
	{ key: 1, label: "one", options: [{...}]},
	{ key: 2, label: "two", options: [{...}]},
	...
]

<ListBoxBrowser
	data={data}
	defaultSelectedView={(option) =>  (option.key === 1)}  />

/** The previous result on option with `key 1` to be selected */
```

#### defaultSelectedView

This prop works exactly like the `defaultSelectedOptions`. It receives a function which you can use to compare and decide what option should be the one as initial view.

**Note**: Be sure to select an `option` property with `options`. Otherwise, this function doesn't work and falls back to the default behaviour, which selects the first option with options.

### Lazy loading

This component provides a way to load async options. To achieve this, you can declare the `options` array property empty `[]`. This indicates to the component to fire the `onFetch={option => ()}` prop when the user interacts with it.

```js
<ListBoxBrowser
  data={[{ label: "lazy", options: [] }]}
  onFetch={option => {
    logic;
  }}
>
  <ListBoxBrowser.Browser isLoading={isBrowserLoading} />
</ListBoxBrowser>
```

#### Lazy loading example

To help you to sync your data with the newest options, the ListBoxBrowser provides you with some tools to make it easier:

A Subcomponent `<ListBoxBrowser.Browser isLoading />` which lets you set the right column into a pending state.
A `ListBoxBrowser.findOption(data, fn)` which helps you in finding an option in your data so you can modify it.

```js
export default function App(props) {
  const [isBrowserLoading, setIsBrowserLoading] = React.useState(false);
  const [data, setData] = React.useState(props.defaultData);

  async function handleFetch(option) {
    setIsBrowserLoading(() => true);
    const key = option.key;
    const response = await fakeFetch({ key });

    setData(data => {
      const cloneData = data.splice(0);
      const o = ListBoxBrowser.findOption(cloneData, option => option.key === key);
      o.options = response;

      return cloneData;
    });
    setIsBrowserLoading(() => false);
  }

  return (
    <ListBoxBrowser onFetch={handleFetch} data={data} rootTitle="Universes" browserTitle="Heroes">
      <ListBoxBrowser.Browser isLoading={isBrowserLoading} />
      <ListBoxBrowser.OptionsSelected />
    </ListBoxBrowser>
  );
}
```

<!-- eoContent -->

## Links

- [Storybook Showcase](https://paprika.highbond.com/?path=/story/forms-listboxbrowser--showcase)
- [GitHub source code](https://github.com/acl-services/paprika/tree/master/packages/ListBoxBrowser/src)
- [Create GitHub issue](https://github.com/acl-services/paprika/issues/new?label=[]&title=@paprika/list-box-browser%20[help]:%20your%20short%20description&body=%0A%23%20Help%20wanted%0A%0A%23%23%20Please%20write%20your%20question.%0A*A%20clear%20and%20concise%20description%20of%20what%20the%20question%20is*%0A%0A%23%23%20Additional%20context%0A*Add%20any%20other%20context%20or%20screenshots%20about%20your%20question%20here.*%0A)
- [CHANGELOG](https://github.com/acl-services/paprika/tree/master/packages/ListBoxBrowser/CHANGELOG.md)