# dccTab

The `dccTab` and `dccTabs` components can be used to create tabbed sections in your app. The `Tab` component controls the style and value of the individual tab and the `Tabs` component hold a collection of `Tab` components.

See complete examples in Tabs.

## Examples

Find a few usage examples below.

### Method 1. Content as Callback

Attach a callback to the Tabs `value` prop and update a container's `children` property in your callback.

    library(dashCoreComponents)
    library(dashHtmlComponents)
    library(dash)

    utils <- new.env()
    source('dash_docs/utils.R', local=utils)

    examples <- list(
      button = utils$LoadExampleCode('dash_docs/chapters/dash_core_components/Button/examples/button.R'),
      tabs = utils$LoadExampleCode('dash_docs/chapters/dash_core_components/Tabs/examples/tabs.R')
    )

    app <- Dash$new()

    app$layout(htmlDiv(list(
      htmlH1('Dash Tabs component demo'),
      dccTabs(id="tabs-example", value='tab-1-example', children=list(
        dccTab(label='Tab One', value='tab-1-example'),
        dccTab(label='Tab Two', value='tab-2-example')
      )),
      htmlDiv(id='tabs-content-example')
    )))

    app$callback(
      output = list(id='tabs-content-example', property = 'children'),
      params = list(input(id = 'tabs-example', property = 'value')),
      function(tab){
        if(tab == 'tab-1-example'){
          return(htmlDiv(list(
            htmlH3('Tab content 1'),
            dccGraph(
              id='graph-1-tabs',
              figure=list(
                'data' = list(list(
                  'x' = c(1, 2, 3),
                  'y' = c(3, 1, 2),
                  'type' = 'bar'
                ))
              )
            )
          )))
        }
        else if(tab == 'tab-2-example'){
          return(htmlDiv(list(
            htmlH3('Tab content 2'),
            dccGraph(
              id='graph-2-tabs',
              figure=list(
                'data' = list(list(
                  'x' = c(1, 2, 3),
                  'y' = c(5, 10, 6),
                  'type' = 'bar'
                ))
              )
            )
          )))
        }
      }
    )

    app$run_server()

Tab one
Tab two

### Tab content 1

### Method 2. Content as Tab Children

Instead of displaying the content through a callback, you can embed the content directly as the `children` property in the `Tab` component:

    app <- Dash$new()

    app$layout(htmlDiv(list(
      dccTabs(id="tabs", children=list(
        dccTab(label='Tab one', children=list(
          htmlDiv(list(
            dccGraph(
              id='example-graph',
              figure=list(
                'data'= list(
                  list('x'= c(1, 2, 3), 'y'= c(4, 1, 2),
                    'type'= 'bar', 'name'= 'SF'),
                  list('x'= c(1, 2, 3), 'y'= c(2, 4, 5),
                    'type'= 'bar', 'name'= 'Montréal')
                  )
              )
            )
            ))
          )),
        dccTab(label='Tab two', children=list(
          dccGraph(
            id='example-graph-1',
            figure=list(
              'data'= list(
                list('x'= c(1, 2, 3), 'y'= c(1, 4, 1),
                  'type'= 'bar', 'name'= 'SF'),
                list('x'= c(1, 2, 3), 'y'= c(1, 2, 3),
                  'type'= 'bar', 'name'= 'Montréal')
                )
            )
          )
          )),
        dccTab(label='Tab three', children=list(
          dccGraph(
            id='example-graph-2',
            figure=list(
              'data'= list(
                list('x'= list(1, 2, 3), 'y'= list(2, 4, 3),
                  'type'= 'bar', 'name'= 'SF'),
                list('x'= list(1, 2, 3), 'y'= list(5, 4, 3),
                  'type'= 'bar', 'name'= 'Montréal')
                )
            )
          )
          ))
        ))
      )))

    app$run_server()

Tab one
Tab two
Tab three

Note that this method has a drawback: it requires that you compute the children property for each individual tab upfront and send all of the tab's content over the network at once. The callback method allows you to compute the tab's content on the fly (that is, when the tab is clicked).

### Styling the Tabs Component

#### With CSS Classes

Styling the Tabs (and Tab) component can either be done using CSS classes by providing your own to the `className` property:

    library(dashCoreComponents)
    library(dashHtmlComponents)
    library(dash)

    app <- Dash$new()

    app$layout(htmlDiv(list(
      dccTabs(
        id="tabs-with-classes",
        value='tab-2',
        parent_className='custom-tabs',
        className='custom-tabs-container',
        children=list(
          dccTab(
            label='Tab one',
            value='tab-1',
            className='custom-tab',
            selected_className='custom-tab--selected'
          ),
          dccTab(
            label='Tab two',
            value='tab-2',
            className='custom-tab',
            selected_className='custom-tab--selected'
          ),
          dccTab(
            label='Tab three, multiline',
            value='tab-3', className='custom-tab',
            selected_className='custom-tab--selected'
          ),
          dccTab(
            label='Tab four',
            value='tab-4',
            className='custom-tab',
            selected_className='custom-tab--selected'
          )
          )),
      htmlDiv(id='tabs-content-classes')
      )))

    app$callback(
      output = list(id='tabs-content-classes', property = 'children'),
      params = list(input(id = 'tabs-with-classes', property = 'value')),
      function(tab){
        if(tab == 'tab-1'){
          return(htmlDiv(
            list(htmlH3('Tab content 1'))
          ))
        } else if(tab == 'tab-2'){
          return(htmlDiv(
            list(htmlH3('Tab content 2'))
          ))
        } else if(tab == 'tab-3'){
          return(htmlDiv(
            list(htmlH3('Tab content 3'))
          ))
        } else if(tab == 'tab-4'){
          return(htmlDiv(
            list(htmlH3('Tab content 4'))
          ))
        }
      }
    )

    app$run_server()

Tab one
Tab two
Tab three, multiline
Tab four

### Tab content 2

Notice how the container of the Tabs can be styled as well by supplying a class to the `parent_className` prop, which we use here to draw a border below it, positioning the actual Tabs (with padding) more in the center. We also added `display: flex` and `justify-content: center` to the regular `Tab` components, so that labels with multiple lines will not break the flow of the text. The corresponding CSS file (`assets/tabs.css`) looks like this. Save the file in an `assets` folder (it can be named anything you want). Dash will automatically include this CSS when the app is loaded. Learn more in Adding CSS & JS and Overriding the Page-Load Template.

    .custom-tabs-container {
        width: 85%;
    }
    .custom-tabs {
        border-top-left-radius: 3px;
        background-color: #f9f9f9;
        padding: 0px 24px;
        border-bottom: 1px solid #d6d6d6;
    }

    .custom-tab {
        color:#586069;
        border-top-left-radius: 3px;
        border-top: 3px solid transparent !important;
        border-left: 0px !important;
        border-right: 0px !important;
        border-bottom: 0px !important;
        background-color: #fafbfc;
        padding: 12px !important;
        font-family: "system-ui";
        display: flex !important;
        align-items: center;
        justify-content: center;
    }
    .custom-tab--selected {
        color: black;
        box-shadow: 1px 1px 0px white;
        border-left: 1px solid lightgrey !important;
        border-right: 1px solid lightgrey !important;
        border-top: 3px solid #e36209 !important;
    }

#### With Inline Styles

An alternative to providing CSS classes is to provide style dictionaries directly:

    library(dashCoreComponents)
    library(dashHtmlComponents)
    library(dash)

    app <- Dash$new()

    tabs_styles = list(
      'height'= '44px'
    )
    tab_style = list(
      'borderBottom'= '1px solid #d6d6d6',
      'padding'= '6px',
      'fontWeight'= 'bold'
    )

    tab_selected_style = list(
      'borderTop'= '1px solid #d6d6d6',
      'borderBottom'= '1px solid #d6d6d6',
      'backgroundColor'= '#119DFF',
      'color'= 'white',
      'padding'= '6px'
    )

    app$layout(htmlDiv(list(
      dccTabs(id="tabs-styled-with-inline", value='tab-1', children=list(
        dccTab(label='Tab 1', value='tab-1', style=tab_style, selected_style=tab_selected_style),
        dccTab(label='Tab 2', value='tab-2', style=tab_style, selected_style=tab_selected_style),
        dccTab(label='Tab 3', value='tab-3', style=tab_style, selected_style=tab_selected_style),
        dccTab(label='Tab 4', value='tab-4', style=tab_style, selected_style=tab_selected_style)
        ), style=tabs_styles),
      htmlDiv(id='tabs-content-inline')
      )))

    app$callback(
      output = list(id='tabs-content-inline', property = 'children'),
      params = list(input(id = 'tabs-styled-with-inline', property = 'value')),
      function(tab){
        if(tab == 'tab-1'){
          return(htmlDiv(
            list(htmlH3('Tab content 1'))
          ))
        } else if(tab == 'tab-2'){
          return(htmlDiv(
            list(htmlH3('Tab content 2'))
          ))
        } else if(tab == 'tab-3'){
          return(htmlDiv(
            list(htmlH3('Tab content 3'))
          ))
        } else if(tab == 'tab-4'){
          return(htmlDiv(
            list(htmlH3('Tab content 4'))
          ))
        }
      }
    )

    app$run_server()

Tab 1
Tab 2
Tab 3
Tab 4

### Tab content 1

Lastly, you can set the colors of the Tabs components in the `color` prop, by specifying the "border", "primary", and "background" colors in a dict. Make sure you set them all, if you are using them!

    library(dashCoreComponents)
    library(dashHtmlComponents)
    library(dash)

    app <- Dash$new()

    app$layout(htmlDiv(list(
      dccTabs(id="tabs-styled-with-props", value='tab-1', children=list(
        dccTab(label='1', value='tab-1'),
        dccTab(label='2', value='tab-2')
        ), colors=list(
          "border"= "white",
          "primary"= "gold",
          "background"= "cornsilk"
        )),
      htmlDiv(id='tabs-content-props')
      )))

    app$callback(
      output = list(id='tabs-content-props', property = 'children'),
      params = list(input(id = 'tabs-styled-with-props', property = 'value')),
      function(tab){
        if(tab == 'tab-1'){
          return(htmlDiv(
            list(htmlH3('Tab content 1'))
          ))
        } else if(tab == 'tab-2'){
          return(htmlDiv(
            list(htmlH3('Tab content 2'))
          ))
        }
      })

    app$run_server()

1
2

### Tab content 1

## Tab Properties

> Our recommended IDE for writing Dash apps is Dash Enterprise's Data Science Workspaces, which has typeahead support for Dash Component Properties. Find out if your company is using Dash Enterprise.

`children` (unnamed list of or a singular dash component, character or numeric; optional): The content of the tab - will only be displayed if this tab is selected.

`id` (character; optional): The ID of this component, used to identify dash components in callbacks. The ID needs to be unique across all of the components in an app.

`label` (character; optional): The tab's label.

`value` (character; optional): Value for determining which Tab is currently selected.

`disabled` (logical; default `FALSE`): Determines if tab is disabled or not - defaults to FALSE.

`disabled_style` (named list; default `{ color: '#d6d6d6',}`): Overrides the default (inline) styles when disabled.

`disabled_className` (character; optional): Appends a class to the Tab component when it is disabled.

`className` (character; optional): Appends a class to the Tab component.

`selected_className` (character; optional): Appends a class to the Tab component when it is selected.

`style` (named list; optional): Overrides the default (inline) styles for the Tab component.

`selected_style` (named list; optional): Overrides the default (inline) styles for the Tab component when it is selected.

`loading_state` (named list; optional): Object that holds the loading state object coming from dash-renderer.

`loading_state` is a named list with keys:

- `component_name` (character; optional): Holds the name of the component that is loading.

- `is_loading` (logical; optional): Determines if the component is loading or not.

- `prop_name` (character; optional): Holds which property is loading.