> For the complete documentation index, see [llms.txt](https://webkom.gitbook.io/spin/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://webkom.gitbook.io/spin/bootstrap4-additional-components.md).

# Bootstrap4 Additional Components

{% hint style="info" %}
This is the documentation for **"SPIN" v2:** [v2.react.spin.webkom.co](http://v2.react.spin.webkom.co)
{% endhint %}

All of the components from [Reactstrap](https://reactstrap.github.io/components) are availeble to import from the root `/components`. Also some of them are extended by some new functionalities / props.

### Accordion

`Card` and `Collapse` based Accordion. Should be composed of the provided subcomponents. Can work in an controlled and uncontrolled mode.

**Props:**

* `onToggle:(opened: bool) => void` - Accordion is being opened or closed. Providing this function will set the Accordion into controlled mode.
* `open` - For controlled mode only. Should the accordion be opned
* `initialOpen` - For uncontrolled mode only. Should the Accordion start opened or not.

**Example Implementation:**

```jsx
<Accordion initialOpen>
    <Accordion.Header className='h6'>
        <Accordion.Indicator className="mr-2"/>
        Example Header
    </Accordion.Header>
    <Accordion.Body>
        <CardText>
            Some text...
        </CardText>
    </Accordion.Body>
</Accordion>
```

#### Accordion.Body

Should contain the collapsable content of the Accordion. This is basically a `Collapse` + `CardBody` composition.

**Props:**

* childen:node - Collapsable children

#### Accordion.Header

The trogger for open/close the accordion. Based on `CardHeader`.

**Props:**

* `children:node` - The elements which should be rendered as Accordion trigger.

#### Accordion.Indicator

Shows an information (preferably icon) if the Accordion is opened or closed

**Props:**

* `open:node` - shown when the Accordion is open (default: )
* `closed:node` - shown when the Accordion is closed (default: )

### Avatar

`Avatar` consists of two versions `Avatar.Image`, `Avatar.Font`, for displaying avatars and text/icon based versions respocitvely.

**Common Props:**

* `size:string` - Available options: `sm`, `md`, `lg`.
* `addOns:node` - An array of additional components which will be placed within the Avatar. Allowed componets are: `AvatarAddOn.Icon` and `AvatarAddOn.Badge`. Please not that this should be an array of elements, and each of them should have a `key` prop provided.

#### Avatar.Font

Renders text based avatars.

* `children:node` - Text or a FontAwesome icon
* `bgColor` - Background color id
* `fgColor` - Text color id
* `bgCustomColor` - A raw hex or rgba color for the background
* `fgCustomColor` - A raw hex or rgba color of the text

#### Avatar.Image

Displays `<img/>` based avatars.

**Props:**

* `src:string` - URL passed to the `<img />`
* `placeholder:node` - A text node which will be rendered until the image is loaded. Typically it should ba a FontAwesome icon `<i className="fa fa-..." />`
* `alt:strin` - Alt Text for the `<img />`

#### AvatarAddOn.Badge

The same as Reacstrap's `Badge` but for use only in `Avatar`'s `addOns` prop. They are placed in the top-right corner of the Avatar.

#### AvtarAddOn.Icon

Icons are placed in the in the bottom-right corner of the Avatar and they can be stacked on top of each other. For example a configuration of:

```jsx
<Avatar.Image
    size="lg"
    src="http://bs4.webkom.co/img/avatars/2.jpg"
    className="mr-1"
    addOns={[
        <AvatarAddOn.Icon 
            className="fa fa-circle"
            color="white"
            key="avatar-icon-bg"
        />,
        <AvatarAddOn.Icon 
            className="fa fa-circle"
            color="success"
            key="avatar-icon-bg"
        />,
        <AvatarAddOn.Icon 
            className="fa fa-plus"
            color="white"
            key="avatar-icon-fg"
            small
        />
    ]}
/>
```

will produce the following result:

![Stacked Avatar Icons](https://content.screencast.com/users/unskilled/folders/Jing/media/bd66dd88-e1c4-46a3-909c-63301e9bea9d/2018-07-25_1645.png)

### Card

The same as Reactstrap's `Card`, but with some additional props

* `type:string` - Available types are: `border`, `side-border`, `border-dash`, `border-dot`, `background`, `shadow`, `none`; Effects applied to the card itself.
* `color:string` - Color id assigned with the effect provided by `type` prop.

### CardHeader

The same sa Reatstrap's `CardHeader`, but with some additional props

* `type:string` - Available types are: `background` and `border`
* `color:string` - Color id asssigned with the effect provided by `type` props.

### Checkable

Allows you to crate whole elements (rows, cards, etc) to trigger a checkbox / radio contained within.

**Props:**

* `children:node` - Elements rendered inside
* `tag:string|func` - Component that should be used internally to render (default: div)

#### Checkable.Trigger

The trigger element will pass all of the clicks to the input provided by Checkable.

**Props:**

* `children:node` - Elements rendered inside

#### Checkable.Input

The input element which will be checked when Trigger is clicked.

**Props:**

* `children:node`- Elements rendered inside of the input
* `tag:string|func` - The input component itself (default: Input)

**Example Implementation:**

```jsx
<Checkable tag={ Media }>
    <Checkable.Trigger tag={ Media } left top>
        <Avatar.Image
            {/* ... */}
        /> 
    </Checkable.Trigger>
    <Checkable.Trigger tag={ Media } body>
        <p>
            Some text
        </p>
    </Checkable.Trigger>
    <Media right top>
        <Checkable.Input tag={ CustomInput } type="checkbox" id="rightCheckbox1" defaultChecked />
    </Media>
</Checkable>
```

### EmptyLayout

Toggles the layout to be empty - `Sidebar` and `Navbar` are disabled and the content is set to be centered within the viewport. Mainly used for single Card pages for example: Login, Register, etc...

**Props:** `children:node` - element which will be rendered in the center of the screen.

### ExtendedDropdown

More flexible dropdown menu, which consists of static and fluid sections. In mobile mode while in navbar this dropdown will fill the whole screen. **Uses also Props and Context from Reactstrap's DropdownMenu**

**Props:**

* `children:node` `ExtendedDropdown.Section`s from which you can compose the Dropodown.

#### ExtendedDropdown.Section

There are two types of sections - static, and fluid. Static section don't resize vertically, and fluid do resize. Typically you should add Reactstrap's `ListGroup`s in the fluid part, so they can be scrolled inside.

**Props:**

* `fluid:boolean` - should the section be stretched/shrinked vertically
* `tag:string|func` - tag element used as the Section. Allows to make whole sections as Links.

### HolderProvider

A wrapper for [holder.js](http://holderjs.com) - allows to generate placeholder images and injects them into the child element. This components is made out of two subcomponents which you should be using:

**General Props:** [Click here](https://github.com/imsky/holder#placeholder-options) to see what options are used by holder.js. These options are available as props.

#### HolderProvider.Text

Renders an image with defined text in the center of the picture.

**Props**

* `children:node` - Element of which the `src` prop will be populated with the placeholder image

#### HolderProvider.Icon

Renders a FontAwesome icon in the center of the picture.

**Props**

* `iconChar:string` - FontAwesome character to render - for example pasting  will render fa-picture-o
* `children:node` - Element of which the `src` prop will be populated with the placeholder image

### IconWithBadge

Icon with badge, mainly used in buttons and navs. Preview:

![IconWithBadge Preview](https://content.screencast.com/users/unskilled/folders/Jing/media/0f17122f-7243-4dbe-be8e-8b652ef1cbee/2018-07-26_1009.png)

* `badge:node` - Reactstrap's `Badge` elemnt which will be added to the Icon
* `children:node` - FontAwesome icon element

### Layout

The whole layout parent, contains the state of the layout, and provides data to child layout elements.

* `children:node` - one of `Layout.Content`, `Layout.Sidebar`, `Layout.Navbar`. Providing these will make the `Layout` element to compose the layout properly.
* `sidebarSlim:boolean` - Should the sidebar be slim when collapsed on >= `lg` screens

#### Layout.Navbar

Reactstrap's `Navbar` container.

* `children:node` - Typically `Navbar` element

#### Layout.Sidebar

The `Sidebar` container.

* `children:node` - Typically `Sidebar` component inside
* `sidebarSlim:boolean` - should the sidebar be in slim mode when collapsed on >= `lg` **(dont' use directly, provided by** `Layout`**)**
* `sidebarCollapsed:boolean` - is the sidebar collapsed **(dont' use directly, provided by** `Layout`**)**

#### Layout.Content

Page content container.

* `children:node` - Page content

#### withPageConfig (HOC)

Provides `pageConfig` object to the component which is composed of the followin fields:

* `sidebarHidden:boolean` - is sidebar hidden
* `navbarHidden:boolean` - is navbar hidden
* `footerHideen:boolean` - is footer hidden
* `sidebarCollapsed:boolean` - is sidebar collapsed
* `sidebarSlim:boolean` - is slim sidebar option is enabled
* `pageTitle: string` - title of the current page
* `pageDescription: string` - description of the current page
* `pageKeywords: string` - meta keywords for the current page
* `toggleSidebar: func` - toggle collapsed sidebar

### NestedDropdown

A Dropdown which can contain Nested Dropdowns inside which will be rendered on the side of the main dropdown on hover. Renders as nested menus in Collapsed Navbars.

**Example Implementation (taken from Only Navbar example)**

```jsx
<NestedDropdown nav inNavbar>
    <DropdownToggle nav>
        Apps
        <i className="fa fa-angle-down fa-fw ml-1"></i>
    </DropdownToggle>
    <DropdownMenu>
        <NestedDropdown.Submenu title="Mailbox">
            <DropdownItem tag={ Link } to="/apps/inbox">Inbox</DropdownItem>
            <DropdownItem tag={ Link } to="/apps/new-email">New Email</DropdownItem>
            <DropdownItem tag={ Link } to="/apps/email-details">Email Details</DropdownItem>
        </NestedDropdown.Submenu>
        <NestedDropdown.Submenu title="Profile">
            <DropdownItem tag={ Link } to="/apps/profile-details">Profile Details</DropdownItem>
            <DropdownItem tag={ Link } to="/apps/profile-edit">Profile Edit</DropdownItem>
        </NestedDropdown.Submenu>
        <DropdownItem tag={ Link } to="/apps/clients">Clients</DropdownItem>
        <DropdownItem tag={ Link } to="/apps/chat">Chat</DropdownItem>
    </DropdownMenu>
</NestedDropdown>
```

#### NestedDropdown.Submenu

The submenu element which is placed inside of the main dropdown and contains further nested `DropodwnItem`s

**Props**

* `children:node` - list of nested `DropdownItem`s
* `title:string|node` - the title which will be visible in the main Dropdown
* `tag:string|func` - component which will be rendered as a parent (default: div)
* `subMenuTag:string|func` - component which will contain the child elements (default: div)

### OuterClick

When a user clicks outside of the provided child `onClickOutside` will be called.

* `onClickOutside:func` - event handler called when the click occours
* `children:node` - the element of outside which the click should be picked
* `active:boolean` - is this functionality enabled
* `excludedElements:HTMLElement[]` - *deprecated* which elements outside of the child should no trigger the click event

### Progress

Reactstrap's `Progress` component extended with `slim` prop.

* `slim:boolean` - should the progress bar be rendered in a slim version

### Sidebar

The sidebar component which is build from `Sidebar.Section`s.

* `children:node` - `Sidebar.Section` elemnets from which the sidebar will be build
* `slim:boolean` - should the sidebar be in slim mode **(avoid direct usage, provided by context)**
* `collapsed:boolean` - is the sidebar collased **(avoid direct usage, provided by context)**

#### Sidebar.Section

Section of the sidebar

* `fluid:boolean` - should the section be stretching/shrinking, typically used for `SidebarMenu` section
* `cover:boolean` - no padding in the section should be used

#### Sidebar.Close

Closes the sidebar in Overlay Mode, it is visible only when the sidebar is overlayed.

#### Sidebar.MobileFluid

Allows the content to be scrolled inside in mobile devices. For example when you have 2 static `Sidebar.Sections` and 1 fluid for scrollable menu, you will come on a problem in mobile devices - the fluid part will be very small, and most of vertical screen space will be used for the static Sections. To mitigate this you can wrap 1 static Section and the fluid Section with this component. This will make both of those sections scrollable on mobile.

**Props**

* `children:node` - Sections which will be wrapped in a scroll in mobile view.

**Example Usage**

```jsx
<Sidebar>
    <Sidebar.Close>
        <SidebarTrigger tag={ 'a' } href="javascript:;">
            <i className="fa fa-times-circle fa-fw"></i>
        </SidebarTrigger>
    </Sidebar.Close>

    <Sidebar.Section>
        { /* ( Always Static Section ) */ }
    </Sidebar.Section>

    <Sidebar.MobileFluid>
        <Sidebar.Section>
            { /* ( Static only on Desktop ) */ }
        </Sidebar.Section>

        <Sidebar.Section fluid cover>
            { /* ( scrollable on Desktop and Mobile )  */ }
            <SidebarMiddleNav />
        </Sidebar.Section>

        <Sidebar.Section>
            { /* ( Static only on Desktop ) */ }
        </Sidebar.Section>
    </Sidebar.MobileFluid>
</Sidebar>
```

### SidebarMenu

The navigation menu. Composed of `SidebarMenu.Item`s.

* `children:node` - `SidebarMenu.Item`s of which the menu will be composed

#### SidebarMenu.Item

SidebarMenu entry, the top level ones contain icons, while the nested ones don't.

* `to:string`- url to which the entry should point
* `children:node` - nested `SidebarMenu.Item`s, can't be used with `to`, should be one of them
* `title:string` - the title of the entry
* `exact:bool` - should the entry be marked as active by an exact url match

### SidebarTrigger

Element which will trigger the sidebar to be collapsed or not

**Props**

* `tag:string|func` - the tag which will be used to render the element - `NavLink` default
* `children:node` - contents of the Button

### Tools

Ultility elements for conditional rendering and such.

#### Tools.DefaultOnly

Children of this component will only be rendered when the sidebar is **not in slim mode**

#### Tools.SlimOnly

Children of this component will only be rendered when the sidebar **is in slim mode**

#### Tools.SlimProps

Children of this component will have their declared props overriden with the ones provided in `slimProps` object, when the sidebar is in slim mode. For example if we want an avatar inside the sidebar to change its size depending on the state of the sidebar. For example:

```jsx
<Tools.SlimProps
    slimProps={{ size: 'md' }}
>
    <Avatar.Image
        size="lg"
        src={ avatarImg }
    />
</Tools.SlimProps>
```

In the above when the Sidebar becomes `slim` the `AvatarImage`'s `size` prop will be changed to `md`.

### UncontrolledModal

Uncontrolled version of [reactstrap's Modal](https://reactstrap.github.io/components/modals/).

**Props:** *all of the Modal props +*

* `target:string` - id of the trigger element which will show the Modal

#### UncontrolledModal.Close

Element which will close the Modal.

**Props:**

* `tag:string|func` - Component which will be used to represent this trigger

### Uncontrolled Popover

Uncontrolled version of [reactstrap's Popover](https://reactstrap.github.io/components/popovers/).

**Props:** *all of the Popover props +*

* `activateTrigger:bool` - should the targeted trigger receive the active class defined by the `activeClassName` prop
* `activeClassName:string` - class which will be added to the trigger element when active

### UncontrolledTabs

Uncontrolled Tabs container. Should be composed of `UncontrolledTabs.NavLink` and `UncontrolledTabs.TabContent` which are context extended versions of reactstrap's components.

&#x20;**Props:**

* `children:node` - composition of `UncontrolledTabs.NavLink` and `UncontrolledTabs.TabContent`
* `initialActiveTabId:string` - the id of the tab that should be visible at the start

#### UnconctrolledTabs.NavLink

[reactstrap's NavLink](https://reactstrap.github.io/components/navs/#app) for switching the Uncontrolled Tabs.

**Props:** *all of the Popover props +*

* `tabId:string` - id of the corresponding TabContent which should be show when clicked

#### UnconctrolledTabs.TabContent

[reactstrap's TabContent](https://reactstrap.github.io/components/tabs/) connected with the UncontrolledTabs.

**Props:** *all of the TabContent props +*
