Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Tabs component #213

Merged
merged 55 commits into from Jul 26, 2018

Conversation

Projects
None yet
@valentijnnieman
Copy link
Contributor

commented Jun 21, 2018

Update July 9, 2018
We are looking to merge and release this component this week. Please give it a try! You can install with:
dash_core_components==0.24.0rc2
Feedback welcome 馃檶


Hello there!
Here is the improved Tabs component I've been working on, branched off the current master branch. It supports className's and inline style's for the multiple containers (parent, tabs, tab, tab-content, tab--selected) which appends classes to the base classes (let me know if it should overwrite the default classes instead of appending) and has a vertical bool for rendering vertically.
screen shot 2018-06-21 at 11 37 40
screen shot 2018-06-21 at 11 36 40

It's also more responsive:
screen shot 2018-06-21 at 11 38 31

It's basically 2 components: a dcc.Tabs component which is the container, where you can specify vertical and set some classes and styles, and a dcc.Tab component, which renders a tab with a label, and renders it's children (which can be anything in Dash) when that tab is selected! Thanks to @T4rk1n for his work and ideas!

Here's an example of how to use Tabs:

import dash
import dash_html_components as html
import dash_core_components as dcc

from dash.dependencies import Input, Output, State

app = dash.Dash()

app.css.config.serve_locally = True
app.scripts.config.serve_locally = True


app.layout = html.Div([
    html.H1('Dash Tabs component demo', style={
            'textAlign': 'center', 'margin': '48px 0', 'fontFamily': 'system-ui'}),
    dcc.Tabs(id="tabs", children=[
        dcc.Tab(label='Tab one', children=[
            html.Div([
                dcc.Graph(
                    id='example-graph',
                    figure={
                        'data': [
                            {'x': [1, 2, 3], 'y': [4, 1, 2],
                                'type': 'bar', 'name': 'SF'},
                            {'x': [1, 2, 3], 'y': [2, 4, 5],
                             'type': 'bar', 'name': u'Montr茅al'},
                        ],
                        'layout': {
                            'title': 'Dash Data Visualization'
                        }
                    }
                )
            ])
        ]),
        dcc.Tab(label='Tab two', children=[
            html.Div([
                html.H1("This is the content in tab 2"),
                html.P("A graph here would be nice!")
            ])
        ]),
        dcc.Tab(label='Tab three', children=[
            html.Div([
                html.H1("This is the content in tab 3"),
            ])
        ]),
    ],
        style={
        'fontFamily': 'system-ui'
    },
        content_style={
        'borderLeft': '1px solid #d6d6d6',
        'borderRight': '1px solid #d6d6d6',
        'borderBottom': '1px solid #d6d6d6',
        'padding': '44px'
    },
        parent_style={
        'maxWidth': '1000px',
        'margin': '0 auto'
    }
    )
])


if __name__ == '__main__':
    app.run_server(debug=True)

I haven't included any builds yet, because I'm not sure if I should - CircleCI etc will handle that stuff, right?

edit:
Please be aware that the component API has changed a bit - it now uses 2 components:

  • dcc.Tabs() is the container component, which renders it's children as tabs, complete with selection logic - you no longer have to set this up yourself in Dash, it's handled internally, which I hope is more easy to use. Would love to hear some feedback on this, especially if this is giving you trouble or prevents a certain use case for you.
  • dcc.Tab() is the actual Tab component - it has a label prop that holds the label of the tab's button, and renders it's children as the content that will be visible when this tab is selected

@valentijnnieman valentijnnieman requested a review from chriddyp Jun 21, 2018

@chriddyp chriddyp referenced this pull request Jun 21, 2018

Closed

Dash Tabs component #74

@kyleabeauchamp

This comment has been minimized.

Copy link

commented Jun 21, 2018

I noticed that the changes to test_integration.py from #74 (e.g.,

) are not in the current PR. Do you recall if the old integration tests are still applicable for the new Tab classes? If so, should we add back in those tests to this PR so that the features are tested?

@valentijnnieman

This comment has been minimized.

Copy link
Contributor Author

commented Jun 21, 2018

@kyleabeauchamp Good point - although the old integration tests aren't applicable here because I've changed the component API a bit, some integration testing with the new components would be nice!

@kyleabeauchamp

This comment has been minimized.

Copy link

commented Jun 21, 2018

I have an open PR as well that attempts this, FWIW.

@freshwuzhere

This comment has been minimized.

Copy link

commented Jun 21, 2018

This looks AWESOME! Thanks

@valentijnnieman

This comment has been minimized.

Copy link
Contributor Author

commented Jun 21, 2018

@kyleabeauchamp Whoops, sorry, didn't see your PR in time :)

@kyleabeauchamp

This comment has been minimized.

Copy link

commented Jun 21, 2018

One more naive question: is rebuilding and committing bundle.js part of the PR process? I suspect that would facilitate testing this branch (for those of us too lazy to get a fully working dev environment).

@valentijnnieman

This comment has been minimized.

Copy link
Contributor Author

commented Jun 22, 2018

@kyleabeauchamp Good question - I wasn't sure about this (couldn't find any documentation about it) but I think you're right, looking back at older PR's it looks like the build is included, and I forgot to update the version as well, so I've now done that. Thanks for your help! :)

valentijnnieman added some commits Jun 22, 2018

@ZeroCool2u

This comment has been minimized.

Copy link

commented Jun 22, 2018

This is beautiful. I'm a big fan of the dual component design. Great work!

@kyleabeauchamp

This comment has been minimized.

Copy link

commented Jun 22, 2018

Thanks, with the latest commits I can now import the dcc.Tabs component. This will help folks test this out.

@valentijnnieman

This comment has been minimized.

Copy link
Contributor Author

commented Jul 24, 2018

@chriddyp Custom styles like selected_style are being appended, not replaced, otherwise it would mean that you'd have to style everything yourself, even if you just wanted to update a color or something. My guess is that this is why you have a double border somewhere.

@lilianeolmos

This comment has been minimized.

Copy link

commented Jul 24, 2018

Hi @valentijnnieman ! I'm having an issue: when I select the tab for the first time, the layout is correct , but when I switch tabs and then return to it, the layout has been messed up:
tabs

@chriddyp

This comment has been minimized.

Copy link
Member

commented Jul 24, 2018

Custom styles like selected_style are being appended, not replaced, otherwise it would mean that you'd have to style everything yourself, even if you just wanted to update a color or something. My guess is that this is why you have a double border somewhere.

@valentijnnieman - I'm OK with these styles being merged into the defaults, but what I'm concerned about is that the selected styles seem to be mutated after I've clicked on them. Here is the same GIF but annotated:
Step 1 - Initial state. Note how there are no borders on any of the tabs. This is expected as the stab styles have been overriden.
image

Step 2 - Click on Tab #3.
image

Step 3 - Click on Tab #1. Note how Tab #3 now has a left and top border. It shouldn't have any borders, it should appear the same way as it appears in Step 1. It seems like the style is getting mutated rather than copied.
image

Similarly, note how in Step 2, Tab #1 has left and top borders. This is unexpected, it shouldn't have any borders.

Does that make sense or am I missing something here?

@valentijnnieman

This comment has been minimized.

Copy link
Contributor Author

commented Jul 25, 2018

@chriddyp Sorry, I missed that completely when watching your gif :) I'll take a look at it!

@valentijnnieman

This comment has been minimized.

Copy link
Contributor Author

commented Jul 25, 2018

@chriddyp I made a mistake where I copied the styles over - thus leaving styles that were being appended (from selected_style). Good catch! It should work now - note though that you set width: inherit as tab_style, and selected_style will still have the width: calc(25%) on it, which will look weird.

@valentijnnieman

This comment has been minimized.

Copy link
Contributor Author

commented Jul 25, 2018

@lilianeolmos Hmm that's odd! I've just published prerelease version 0.24.0rc6, could you use that (run pip install dash_core_components==0.24.0rc6) and see if that fixes anything?

@lilianeolmos

This comment has been minimized.

Copy link

commented Jul 25, 2018

@valentijnnieman thanks for your answer. I've just tried and I'm still having the same problem. When I use the previous versions of dash_core_components this problem doesn't happen.

@valentijnnieman

This comment has been minimized.

Copy link
Contributor Author

commented Jul 25, 2018

@lilianeolmos Hmm! Would you perhaps create a post on our forums, here with a short reproducible example code of the bug? Would help us out a lot!

@chriddyp

This comment has been minimized.

Copy link
Member

commented Jul 25, 2018

Thanks for making this changes! Let's do this 馃樃

馃拑 馃拑 馃拑

@valentijnnieman valentijnnieman merged commit b828083 into master Jul 26, 2018

2 checks passed

ci/circleci Your tests passed on CircleCI!
Details
percy/dash-core-components No visual changes since last approval
Details
@danigallo

This comment has been minimized.

Copy link

commented Jul 27, 2018

@valentijnnieman is there a way to change the tab sizes/length? I have 4 and one is carrying over to a new row

@valentijnnieman

This comment has been minimized.

Copy link
Contributor Author

commented Jul 27, 2018

@danigallo You could specify the style of a Tab component and define it's own width. So dcc.Tab(style={'width': '25%'}, children=[]) for example.

@frogger72

This comment has been minimized.

Copy link

commented Jul 31, 2018

Thanks for all your work on the new Tabs functionality. My apps still use the old one from the 0.21.rc1 release and was wondering if it would be safe to switch over for my use case. Typically, each tab's content takes 20 seconds or so to load because of internal data fetching, computation and rendering of a complicated plotly Figure. Additionally, most tabs are never used during a given session, so the content never needs to be generated. Would the new component slow down the app?

@chriddyp

This comment has been minimized.

Copy link
Member

commented Jul 31, 2018

Additionally, most tabs are never used during a given session, so the content never needs to be generated. Would the new component slow down the app?

It will not, you can still use the previous method "generate content through a callback" with the new tabs component. This is what I recommend for most use cases. See the second example here: https://dash.plot.ly/dash-core-components/tabs

@Chris3691

This comment has been minimized.

Copy link

commented Aug 2, 2018

Hi

Fairly new to Plotly and Dash but loving what I can do with it so far! Have started experimenting with tabs and I have two tabs, but when I load my dashboard it opens my "second" tab as the first tab you see.

Is there a way to set tab1 as the "default" tab that should be displayed first? Have done a fair bit of searching but can't see it covered anywhere.

Thanks

Chris

@robfraz

This comment has been minimized.

Copy link

commented Aug 2, 2018

@Chris3691 Yes there is. Look at the code example in this earlier comment where a bug (now resolved) was spotted with this default tab functionality.

You'll see each Tab object has a value specified (value='tab-1', value='tab-2', etc), and there is also a value specified in the Tabs object, which is set to 'tab-3' in that example, thus making the Tab object with the value 'tab-3' the default choice.

@plotly plotly locked as resolved and limited conversation to collaborators Aug 2, 2018

@chriddyp

This comment has been minimized.

Copy link
Member

commented Aug 2, 2018

We have published the documentation for this component online here: https://dash.plot.ly/dash-core-components/tabs. Many thanks to everyone who has contributed to this effort!

If you have any other questions or issues with this component, please create a new issue or discuss in the community forum https://community.plot.ly/c/dash

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can鈥檛 perform that action at this time.