Skip to content

Commit

Permalink
Merge pull request #44 from sdidier-dev/main
Browse files Browse the repository at this point in the history
Fix persistence and add support of custom themes of theme changer
  • Loading branch information
AnnMarieW authored Nov 7, 2024
2 parents dfa2b32 + f9ddf0d commit 1feb511
Show file tree
Hide file tree
Showing 7 changed files with 435 additions and 169 deletions.
131 changes: 131 additions & 0 deletions examples/demo_new_theme_changer/demo_new_theme_changer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
from dash import Dash, dcc, html, Input, Output, dash_table, callback
import pandas as pd
import plotly.express as px
import dash_bootstrap_components as dbc
import dash_ag_grid as dag

from dash_bootstrap_templates import ThemeChangerAIO, template_from_url

app = Dash(
__name__,
external_stylesheets=["https://cdn.jsdelivr.net/gh/AnnMarieW/dash-bootstrap-templates/dbc.min.css"],
########## test custom server/client assets folders ##########
assets_folder='server_side_assets',
assets_url_path='client_side_assets'
)

df = pd.DataFrame({
"Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
"Amount": [4, 1, 2, 2, 4, 5],
"City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"],
})

app.layout = html.Div(
[
# header
html.Div(
[
html.H3("ThemeChangerAIO Demo"),
ThemeChangerAIO(
aio_id="theme",
button_props={'outline': False},
########## test custom themes ##########
custom_themes={
'custom-light': 'custom_light_theme.css',
'custom-dark': 'custom_dark_theme.css'
},
custom_dark_themes=['custom-dark'],
########## test custom RadioItems list ##########
## Note: the value must match the name of the theme
# radio_props={
# "options": [
# {"label": "Cyborg", "value": dbc.themes.CYBORG},
# {"label": "My Theme", "value": "custom_light_theme.css"},
# {"label": "My Dark Theme", "value": "custom_dark_theme.css"},
# {"label": "Spacelab", "value": dbc.themes.SPACELAB},
# # test setting label styling (here unset the style)
# {"label": "Vapor", "value": dbc.themes.VAPOR, "label_id": ""}
# ],
# "value": dbc.themes.VAPOR,
# },
########## test persistence ##########
# radio_props={"persistence": True},
),
], className="sticky-top bg-primary p-2"
),

# test DBC components
html.H4('Dash Bootstrap Components:'),
html.Div([
dbc.Button(f"{color}", color=f"{color}", size="sm")
for color in ["primary", "secondary", "success", "warning", "danger", "info", "light", "dark", "link"]
]),
dbc.Checklist(['New York City', 'Montréal', 'San Francisco'], ['New York City', 'Montréal'], inline=True),
dbc.RadioItems(['New York City', 'Montreal', 'San Francisco'], 'Montreal', inline=True),
html.Hr(),

# test DCC components
html.H4('Dash Core Components:'),
dcc.Checklist(['New York City', 'Montréal', 'San Francisco'], ['New York City', 'Montréal'], inline=True),
dcc.RadioItems(['New York City', 'Montreal', 'San Francisco'], 'Montreal', inline=True),
dcc.Dropdown(["Apple", "Carrots", "Chips", "Cookies"], ["Cookies", "Carrots"], multi=True),
dcc.Slider(min=0, max=20, step=5, value=10),
html.Hr(),

# test DataTable
html.H4('Dash DataTable:'),
dash_table.DataTable(
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict("records"),
row_selectable="single",
row_deletable=True,
editable=True,
filter_action="native",
sort_action="native",
style_table={"overflowX": "auto"},
),
html.Hr(),

# test DAG
html.H4('Dash AG Grid:'),
dag.AgGrid(
columnDefs=[{"field": i} for i in df.columns],
rowData=df.to_dict("records"),
defaultColDef={
"flex": 1, "filter": True,
"checkboxSelection": {
"function": 'params.column == params.api.getAllDisplayedColumns()[0]'
},
"headerCheckboxSelection": {
"function": 'params.column == params.api.getAllDisplayedColumns()[0]'
}
},
dashGridOptions={"rowSelection": "multiple", "domLayout": "autoHeight"},
className='ag-theme-quartz dbc-ag-grid'
),
html.Hr(),

# test plotly fig
html.H4('Plotly Figure:'),
dcc.Graph(
id='theme_changer-graph',
figure=px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")
)
], className='dbc'
)


# Switch figure themes
@callback(
Output("theme_changer-graph", "figure"),
Input(ThemeChangerAIO.ids.radio("theme"), "value"),
)
def update_figure_template(theme):
return px.bar(
df, x="Fruit", y="Amount", color="City", barmode="group",
template=template_from_url(theme)
)


if __name__ == "__main__":
app.run(debug=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
body {
background-color: black;
color: white;
}

.offcanvas {
position: fixed;
bottom: 0;
top: 0;
left: 0;
z-index: 1045;
display: flex;
flex-direction: column;
max-width: 100%;
visibility: hidden;
background-color: black;
transition: transform 0.3s ease-in-out;
}

.offcanvas-backdrop {
position: fixed;
top: 0;
left: 0;
z-index: 1040;
width: 100vw;
height: 100vh;
background-color: white
}

.offcanvas-backdrop.fade {
opacity: 0
}

.offcanvas-backdrop.show {
opacity: .5
}

.offcanvas-header {
display: flex;
}

.btn-close {
--bs-btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");
box-sizing: content-box;
width: 1em;
height: 1em;
padding: .25em .25em;
background: transparent var(--bs-btn-close-bg) center/1em auto no-repeat;
border: 0;
opacity: 0.5
}

.btn-close:hover {
opacity: 0.75
}

.form-check {
display: block;
padding-left: 1.5em;
}

.form-check .form-check-input {
float: left;
margin-left: -1.5em
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
body {
background-color: white;
color: black;
}

.offcanvas {
position: fixed;
bottom: 0;
top: 0;
left: 0;
z-index: 1045;
display: flex;
flex-direction: column;
max-width: 100%;
visibility: hidden;
background-color: white;
transition: transform 0.3s ease-in-out;
}

.offcanvas-backdrop {
position: fixed;
top: 0;
left: 0;
z-index: 1040;
width: 100vw;
height: 100vh;
background-color: black
}

.offcanvas-backdrop.fade {
opacity: 0
}

.offcanvas-backdrop.show {
opacity: .5
}

.offcanvas-header {
display: flex;
}

.btn-close {
--bs-btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");
box-sizing: content-box;
width: 1em;
height: 1em;
padding: .25em .25em;
background: transparent var(--bs-btn-close-bg) center/1em auto no-repeat;
border: 0;
opacity: 0.5
}

.btn-close:hover {
opacity: 0.75
}

.form-check {
display: block;
padding-left: 1.5em;
}

.form-check .form-check-input {
float: left;
margin-left: -1.5em
}
13 changes: 0 additions & 13 deletions src/aio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,2 @@
import os

from .aio_theme_switch import ThemeSwitchAIO
from .aio_theme_changer import ThemeChangerAIO, template_from_url

# needed for Dash for _js_dist
from dash_bootstrap_templates import __version__

_js_dist = [
{
"namespace": "aio",
"relative_package_path": "clientsideCallbacks.js",
"external_url": f'{os.path.dirname(os.path.realpath(__file__))}\\clientsideCallbacks.js',
}
]
Loading

0 comments on commit 1feb511

Please sign in to comment.