Changing the body background color
With Voilà (default) lab template, the background surrounding the ipyvuetify application appears to be the HTML body background, so a workaround is to apply the background color of the ipyvuetify theme to the body background. Ipyvuetify-v.1.6.2 background colors are #fff in the light theme and #121212 in the dark theme (from vuetify.min.css-v2.2.26).
The background color can be modified by adding an internal CSS in an HTML <style> element:
dark_bg = '.jp-Notebook {background-color: #121212}'
light_bg = '.jp-Notebook {background-color: #fff}'
def bg_switch(widget, event, data):
v.theme.dark = not v.theme.dark
css.children = [dark_bg] if v.theme.dark==True else [light_bg]
btn = v.Btn(children=[v.Icon(children=['mdi-theme-light-dark'])])
btn.on_event('click',bg_switch)
css = v.Html(tag='style', children=[dark_bg] if v.theme.dark==True else [light_bg])
v.Container(children=[css,btn])
Another solution is to add an inline CSS by setting the JS HTML DOM Style backgroundColor property of body:
class BtnTheme(v.VuetifyTemplate):
dark = traitlets.Bool(v.theme.dark).tag(sync=True)
template = traitlets.Unicode('''
<v-btn icon @click="switchTheme">
<v-icon>mdi-theme-light-dark</v-icon>
</v-btn>
<script> {created() {this.updateBackground()},
methods: {
switchTheme() {
this.dark = !this.dark;
this.updateBackground()
},
updateBackground() {
document.body.style.backgroundColor = this.dark ? '#121212' : '#fff'
}
}}
</script>''').tag(sync=True)
btn = BtnTheme()
ipywidgets.jslink((btn, 'dark'), (v.theme, 'dark'))
v.Container(children=[btn])
In the above solutions, the theme button is initialised with the value of v.theme.dark which is False unless set to True earlier in the application code. In addition, the theme button can be initialised as the Voilà (lab template) theme:
- by checking the query parameters:
v.theme.dark = (os.environ.get('QUERY_STRING', '').find('dark') != -1)
- or by checking at the beginning of the
created() function the presence of theme-dark in the body classes:
if (document.body.classList.contains('theme-dark')) {this.dark = true}
In case of unknown background colors, these two colors can be detected via two dummy elements, each styled with one of the two themes:
class BtnTheme(v.VuetifyTemplate):
dark = traitlets.Bool(v.theme.dark).tag(sync=True)
v_dark_bg = traitlets.Unicode('').tag(sync=True)
v_light_bg = traitlets.Unicode('').tag(sync=True)
template = traitlets.Unicode('''
<v-btn icon @click="switchTheme">
<v-icon>mdi-theme-light-dark</v-icon>
<div class="v-application theme--dark" id="v-dark-style"></div>
<div class="v-application theme--light" id="v-light-style"></div>
</v-btn>
<script> {
mounted() {
this.v_dark_bg = getComputedStyle(document.getElementById("v-dark-style")).backgroundColor
this.v_light_bg = getComputedStyle(document.getElementById("v-light-style")).backgroundColor
if (document.body.classList.contains('theme-dark')) {this.dark = true}
this.updateBackground()
},
methods: {
switchTheme() {
this.dark = !this.dark
this.updateBackground()
},
updateBackground() {
document.body.style.backgroundColor = this.dark ? this.v_dark_bg : this.v_light_bg
}
}
}
</script>''').tag(sync=True)