Skip to content

Commit

Permalink
refactor: incorporate feedback from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Maarten Breddels <[email protected]>
  • Loading branch information
iisakkirotko and maartenbreddels committed Feb 20, 2024
1 parent 3335abb commit 1df5c2a
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 38 deletions.
5 changes: 3 additions & 2 deletions solara/lab/components/theming.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@

@component_vue("theming.vue")
def _ThemeToggle(
theme_effective: str,
theme_dark: str,
event_sync_themes: Callable[[str], None],
enable_auto: bool,
on_icon: str,
off_icon: str,
auto_icon: str,
clicks: int = 1,
):
pass

Expand Down Expand Up @@ -52,7 +53,7 @@ def sync_themes(selected_theme: str):
theme.dark = selected_theme

return _ThemeToggle(
theme_effective=theme.dark,
theme_dark=theme.dark,
event_sync_themes=sync_themes,
enable_auto=settings.theme.variant_user_selectable,
on_icon="mdi-weather-night",
Expand Down
53 changes: 28 additions & 25 deletions solara/lab/components/theming.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,70 @@
@click="countClicks"
>
<v-icon
:color="theme_effective ? 'primary' : null">
:color="theme_dark ? 'primary' : null">
{{ this.clicks === 1 ? this.on_icon : this.clicks === 2 ? this.off_icon : this.auto_icon }}
</v-icon>
</v-btn>
</template>
<script>
module.exports = {
mounted() {
if (theme.variant_user_selectable) {
if (localStorage.getItem('theme.variant')) {
this.theme_effective = this.initTheme();
if (window.solara && theme.variant_user_selectable) {
if (localStorage.getItem(':solara:theme.variant')) {
this.theme_dark = this.initTheme();
}
}
if ( this.theme_effective === false ) {
if ( this.theme_dark === false ) {
this.clicks = 2;
} else if ( this.theme_effective === null ) {
} else if ( this.theme_dark === null ) {
this.clicks = 3;
}
this.lim = this.enable_auto ? 3 : 2;
},
methods: {
countClicks() {
const lim = this.enable_auto ? 3 : 2;
if ( this.clicks < lim ) {
if ( this.clicks < this.lim ) {
this.clicks++;
} else {
this.clicks = 1;
}
if ( this.clicks === 3 ) {
this.theme_effective = null;
} else if ( this.clicks === 2 ) {
this.theme_effective = false;
this.theme_dark = this.get_theme_bool( this.clicks );
},
get_theme_bool( clicks ) {
if ( clicks === 3 ) {
return null;
} else if ( clicks === 2 ) {
return false;
} else {
this.theme_effective = true;
return true;
}
if ( window.solara ) {theme.variant = this.stringifyTheme();}
this.setTheme();
if ( window.solara ) {localStorage.setItem('theme.variant', JSON.stringify(theme.variant));}
this.sync_themes(this.theme_effective);
},
stringifyTheme() {
return this.theme_effective === true ? 'dark' : this.theme_effective === false ? 'light' : 'auto';
return this.theme_dark === true ? 'dark' : this.theme_dark === false ? 'light' : 'auto';
},
initTheme() {
storedTheme = JSON.parse(localStorage.getItem('theme.variant'));
storedTheme = JSON.parse(localStorage.getItem(':solara:theme.variant'));
return storedTheme === 'dark' ? true : storedTheme === 'light' ? false : null;
},
setTheme() {
if ( window.solara && this.theme_effective === null ) {
if ( window.solara && this.theme_dark === null ) {
this.$vuetify.theme.dark = this.prefersDarkScheme();
return;
}
this.$vuetify.theme.dark = this.theme_effective;
this.$vuetify.theme.dark = this.theme_dark;
},
prefersDarkScheme() {
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
},
},
data: () => ({
clicks: 1,
})
watch: {
clicks (val) {
if ( window.solara ) {theme.variant = this.stringifyTheme();}
this.setTheme();
if ( window.solara ) {localStorage.setItem(':solara:theme.variant', JSON.stringify(theme.variant));}
this.sync_themes(this.theme_dark);
},
}
}
</script>
4 changes: 4 additions & 0 deletions solara/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,11 @@ def on_msg(msg):

from solara.lab import theme

# While this usually gets set from the frontend, in solara (server) we want to know this directly at the first
# render. Also, using the same trait allows us to write code which works on all widgets platforms, instead
# or using something different when running under solara server
theme.dark_effective = dark

container = ipyvuetify.Html(tag="div")
context.container = container
load_app_widget(None, app, path)
Expand Down
6 changes: 5 additions & 1 deletion solara/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,11 @@ def include_css(path: str) -> Markup:
url = f"{root_path}{path}?v={hash}"
# when < 10k we embed, also when we use a url, it can be relative, which can break the url
embed = len(content) < 1024 * 10 and b"url" not in content
if embed:
# Include the jupyterlab theme css directly, so we can change it on demand
if path.endswith("theme-dark.css") or path.endswith("theme-light.css"):
content_utf8 = content.decode("utf-8")
code = content_utf8
elif embed:
content_utf8 = content.decode("utf-8")
code = f"<style>/*\npath={path}\n*/\n{content_utf8}</style>"
else:
Expand Down
18 changes: 11 additions & 7 deletions solara/server/templates/solara.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@
{{ resources.include_css("/static/highlight.css") }}
{{ resources.include_css("/static/highlight-dark.css") }}
{{ resources.include_css("/static/assets/style.css") }}
{% if theme.variant == "light" %}
{{ resources.include_css("/static/assets/theme-light.css") }}
{% elif theme.variant == "dark" %}
{{ resources.include_css("/static/assets/theme-dark.css") }}
{% endif %}
<style id="jupyter-theme-css">
{{ resources.include_css("/static/assets/theme-"~theme.variant~".css") }}
</style>
{{ resources.include_css("/static/assets/custom.css") }}

<script id="jupyter-config-data" type="application/json">
Expand Down Expand Up @@ -212,8 +210,8 @@
solara.preRendered = {{ pre_rendered_html | safe | length | tojson }} > 0
var theme = {{ theme | tojson | safe }}
if (theme.variant_user_selectable) {
if (localStorage.getItem('theme.variant')) {
theme.variant = JSON.parse(localStorage.getItem('theme.variant'))
if (localStorage.getItem(':solara:theme.variant')) {
theme.variant = JSON.parse(localStorage.getItem(':solara:theme.variant'))
}
}
function prefersDarkScheme() {
Expand Down Expand Up @@ -268,6 +266,10 @@
reload() {
location.reload();
},
async changeThemeCSS(theme) {
let css = await fetch(`/static/assets/theme-${theme}.css`).then(r => r.text());
document.getElementById('jupyter-theme-css').innerHTML = css;
}
},
watch: {
kernelBusy: function (value) {
Expand Down Expand Up @@ -316,9 +318,11 @@
'$vuetify.theme.dark': function (value) {
let app = document.getElementById('app');
if ( value ) {
this.changeThemeCSS('dark');
app.classList.remove('theme--light');
app.classList.add('theme--dark');
} else {
this.changeThemeCSS('light');
app.classList.remove('theme--dark');
app.classList.add('theme--light');
}
Expand Down
7 changes: 4 additions & 3 deletions solara/website/pages/api/theming.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
Theming is provided to Solara through the [`ipyvuetify`](https://solara.dev/docs/understanding/ipyvuetify) package.
Two themes are provided by default: light and dark.
Control over the theme variant can be provided to the user through the `ThemeToggle` component.
Control over the theme variant can be provided to the user through the `ThemeToggle` component, or at a lower level through the
`solara.lab.theme` object.
## Themes
The default themes can be customized through altering `solara.lab.theme`. The [theme options of vuetify]
(https://v2.vuetifyjs.com/en/features/theme/#customizing)
The default themes can be customized through altering `solara.lab.theme`. The
[theme options of vuetify](https://v2.vuetifyjs.com/en/features/theme/#customizing)
are available as `solara.lab.theme.themes.light` and `solara.lab.theme.themes.dark`. The different properties of the theme can be set through, for example
```python
Expand Down

0 comments on commit 1df5c2a

Please sign in to comment.