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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul CSS and stylesheet handling for Bokeh 3.x #4275

Merged
merged 34 commits into from
Jan 25, 2023

Conversation

philippjfr
Copy link
Member

@philippjfr philippjfr commented Jan 12, 2023

In bokeh 3.1 we can define ImportedStyleSheet models from Python, providing a cleaner mechanism than adding a custom property which then has to be converted to ImportedStyleSheet instances on the JS side.

The templates will then iterate over all components and inject custom stylesheets that extend the default styling of each component. Currently this adds a single components.css file for each template which will be injected on each component. We may decide to break this up and make component specific stylesheets that only inject the necessary CSS.

Developing

To develop the stylesheets select a particular template and then start editing the CSS files associated with that template and re-bundle them with: panel bundle --templates --local-only. Since this can be tedious you use watch panel bundle --templates --only-local --verbose to periodically re-run the bundling every few seconds.

Run the following application to check the styling of different components (note we should update this app to include a variety of components):

import panel as pn
import param
import pandas as pd

template = pn.state.session_args.get('template', [b'bootstrap'])[0].decode('utf-8')
theme = pn.state.session_args.get('theme', [b'default'])[0].decode('utf-8')

pn.extension(template=template, theme=theme)

pn.Row(
    pn.Column(
        '## Sliders',
        pn.widgets.FloatSlider(start=0, end=10, name='FloatSlider'),
        pn.widgets.RangeSlider(start=0, end=10, name='RangeSlider'),
        '## Input',
        pn.widgets.TextInput(name='TextInput'),
        pn.widgets.TextAreaInput(name='TextAreaInput'),
        pn.widgets.IntInput(start=0, end=10),
        '## Select',
        pn.widgets.Select(options=['A', 'B', 'C'], value='B', name='Select'),
        pn.widgets.MultiSelect(options=['A', 'B', 'C'], value=['B', 'C'], name='MultiSelect'),
        pn.widgets.MultiChoice(options=['A', 'B', 'C'], value=['B', 'C'], name='MultiChoice'),
        pn.widgets.AutocompleteInput(options=['Foo', 'Bar', 'Baz'], name='Autocomplete'),
        '## Buttons',
        pn.widgets.Button(name='Click Me!'),
        pn.widgets.Toggle(name='Toggle me!'),
        pn.widgets.RadioButtonGroup(options=['A', 'B', 'C'], value='A'),
        pn.widgets.MenuButton(name='Click', items=['A', 'B', 'C']),
        '## Checkbox',
        pn.widgets.Checkbox(name='Checkbox'),
        pn.widgets.Switch(name='Switch'),
        pn.widgets.RadioBoxGroup(name='Radio Buttons', options=['A', 'B', 'C'])
    ).servable(area='sidebar'),
    pn.Column(
        '## Cards',
        pn.Card('This is a card w/ a header', title='<h3>Card title</h3>', width=300),
        pn.Card('This is a card w/o a header', hide_header=True, width=300),
        '## Accordions',
        pn.Accordion(
            ('<h3>Foo</h3>', 'This is foo'),
            ('<h3>Bar</h3>', 'This is bar'),
            width=300, active=[1]),
        '## Tabs',
        pn.Tabs(
            ('Foo', 'This is foo'),
            ('Bar', 'This is bar'),
            width=300, active=1),
        pn.Tabs(
            ('Foo', 'This is foo'),
            ('Bar', 'This is bar'),
            width=300, active=1, tabs_location='left'),
        pn.Tabs(
            ('Foo', 'This is foo'),
            ('Bar', 'This is bar'),
            width=300, active=1, tabs_location='right'),
        pn.Tabs(
            ('Foo', 'This is foo'),
            ('Bar', 'This is bar'),
            width=300, active=1, tabs_location='below')

    ).servable()
)

MaterialTemplate

Here's the output for the app above for the MaterialTemplate, we should also keep this updated.

Screen Shot 2023-01-18 at 17 48 15

Screen Shot 2023-01-18 at 17 48 52

BootstrapTemplate

Here's the output for the app above for the MaterialTemplate, we should also keep this updated.

Screen Shot 2023-01-19 at 02 05 10

Screen Shot 2023-01-19 at 02 04 57

@philippjfr
Copy link
Member Author

pre-commit.ci autofix

@philippjfr
Copy link
Member Author

@maximlt @hoxbro If you guys continue working on this, simply create the component CSS files in the template directories and reference them using a relative path:

ImportedStyleSheet(url='./components.css')

Whenever you edit the CSS files you'll have to bundle them with:

panel bundle --templates --verbose --only-local

This will copy them to the correct place in the panel/dist directory.

@philippjfr philippjfr changed the title Replace use of custom CSS property with ImportedStyleSheet Overhaul CSS and stylesheet handling for Bokeh 3.x Jan 18, 2023
@codecov
Copy link

codecov bot commented Jan 25, 2023

Codecov Report

Merging #4275 (8f0fbd8) into branch-1.0 (cb5a378) will decrease coverage by 0.04%.
The diff coverage is 52.92%.

❗ Current head 8f0fbd8 differs from pull request most recent head 6bb63ab. Consider uploading reports for the commit 6bb63ab to get more accurate results

@@              Coverage Diff               @@
##           branch-1.0    #4275      +/-   ##
==============================================
- Coverage       73.36%   73.33%   -0.04%     
==============================================
  Files             238      239       +1     
  Lines           34594    34674      +80     
==============================================
+ Hits            25380    25428      +48     
- Misses           9214     9246      +32     
Flag Coverage Δ
unitexamples-tests 73.33% <52.92%> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
panel/models/markup.py 100.00% <ø> (ø)
panel/models/perspective.py 100.00% <ø> (ø)
panel/models/plotly.py 93.54% <ø> (-0.21%) ⬇️
panel/io/notebook.py 34.85% <5.40%> (-5.64%) ⬇️
panel/compiler.py 10.46% <15.00%> (+4.23%) ⬆️
panel/command/bundle.py 33.33% <33.33%> (ø)
panel/pane/base.py 87.23% <51.72%> (+0.05%) ⬆️
panel/command/__init__.py 68.04% <66.66%> (-0.50%) ⬇️
panel/layout/card.py 93.65% <75.00%> (-1.27%) ⬇️
panel/template/base.py 78.43% <84.90%> (+1.79%) ⬆️
... and 28 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

panel/template/base.py Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants