AnnMarieW / dash-bootstrap-templates

A collection of 52 Plotly figure templates with a Bootstrap theme. Two theme switch components. Stylesheet to apply Bootstrap themes to Plotly Dash components.
https://hellodash.pythonanywhere.com/
MIT License
132 stars 25 forks source link

YETI theme for dcc.Dropdown() #27

Closed mrabiepour closed 1 month ago

mrabiepour commented 7 months ago

Hi,

could you please help me to apply YETI style to dcc.Dropdown() component?

Thanks.

AnnMarieW commented 7 months ago

HI @mrabiepour

Sure - I'm happy to help :slightly_smiling_face:

If you go to the live site and change the theme to Yeti, you'll see that the changes applied to the dcc.Dropdown are quite subtle because the Yeti font and primary color are similar to the default style of the dcc.Dropdown component. You will see the biggest difference if you are using the Yeti in dark mode, because the dcc.Dropdown will have a dark background and the text will be readable.

https://hellodash.pythonanywhere.com/adding-themes/dcc-components

image

Dark mode:

image

mrabiepour commented 7 months ago

Thanks @AnnMarieW for the response.

Since I am using dcc.Dropdown() with dbc.Input(), I would like to unify the styles and have similar appearance for both. I could change some features using external css file within the asset folder per below, but I am wondering there might be easier way to do so and truther styling: (dcc.Dropdown() should have exactly the same style as sbc.Select())

Select{

border-radius: 0 !important; } .Select-control { border-radius: 0 !important; line-height: 1.5 !important; }

Thanks.

AnnMarieW commented 7 months ago

Hi @mrabiepour You are on the right track. The dbc class is minimal styling to add primary colors and make the component visible in light and dark themes. It's designed to work with any Bootstrap theme. However, it's necessary to include some additional CSS to fine tune for your selected theme.

By inspecting the browser, for a dbc.Input you can see some additional styling. Try adding this:


/* input box */
.Select-control {
  background-color: var(--bs-body-bg) !important;
  border: var(--bs-border-width) solid var(--bs-border-color) !important;
  border-radius: var(--bs-border-radius) !important;
  font-size: 1rem  !important;
  font-weight: 400  !important;
  line-height: 1.5  !important;
}

.Select-menu-outer {
  border: var(--bs-border-width) solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
}

/* border on focus - default is blue
 * shadow box around input box.  default is blue
 */
.is-focused:not(.is-open) > .Select-control {
  border-color: var(--bs-primary) !important;
  box-shadow: 0 0 0 var(--bs-focus-ring-width) var(--bs-focus-ring-color) !important;
}

Using Bootstrap variables wherever possible will help if you are using dark mode as well.

Here's a minimal app:

"""
Example of light and dark color modes available in Bootstrap >= 5.3
"""
from dash import Dash, html, dcc, Input, Output, clientside_callback
import dash_bootstrap_components as dbc

app = Dash(__name__, external_stylesheets=[dbc.themes.YETI, dbc.icons.FONT_AWESOME])

color_mode_switch =  html.Span(
    [
        dbc.Label(className="fa fa-moon", html_for="switch"),
        dbc.Switch( id="switch", value=False, className="d-inline-block ms-1", persistence=True),
        dbc.Label(className="fa fa-sun", html_for="switch"),
    ]
)

dropdown = html.Div(
    [
        dbc.Label("Dropdown", html_for="dropdown"),
        dcc.Dropdown(
            id="dropdown",
            options=[
                {"label": "Option 1", "value": 1},
                {"label": "Option 2", "value": 2},
                {"label": "Option 3", "value": 3},
            ],        
        ),
    ],
    className="mb-3",
)

input = html.Div(
    [
        dbc.Label("Input", html_for="input"),
        dbc.Input(
            id="input",
            placeholder="some placeholder"
        ),
    ],
    className="mb-3",
)

range_slider = html.Div(
    [
        dbc.Label("RangeSlider", html_for="range-slider"),
        dcc.RangeSlider(id="range-slider", min=0, max=10, value=[3, 7]),
    ],
    className="mb-3",
)

form = html.Div([dropdown, input, range_slider])

app.layout = dbc.Container(
    [
        html.Div(["Bootstrap Light Dark Color Modes Demo"], className="bg-primary text-white h3 p-2"),
        color_mode_switch,
        form
    ],
    className="dbc"

)

clientside_callback(
    """
    (switchOn) => {
       document.documentElement.setAttribute('data-bs-theme', switchOn ? 'light' : 'dark');         
       return window.dash_clientside.no_update
    }
    """,
    Output("switch", "id"),
    Input("switch", "value"),
)

if __name__ == "__main__":
    app.run_server(debug=True)
mrabiepour commented 7 months ago

Thank you so much for your comprehensive response.

I would also like to add the below style to yours:

.is-focused > .Select-control { border-color: var(--bs-primary) !important; box-shadow: 0 0 0 var(--bs-focus-ring-width) var(--bs-focus-ring-color) !important; transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out !important; }

Thanks again.