React to pydata-sphinx-theme theme change
martinRenou opened this issue · 6 comments
Problem
Somewhat related to pydata/pydata-sphinx-theme#745
pydata-sphinx-theme has a theme switch allowing to go from a light to a dark theme. We could have the embedded jupyterlite respect the current theme flavor.
In order to do this, we need to tell JupyterLab app which theme to use:
Proposed Solution
For replite
For replite it's quite straightforward, we can simply change the URL to pass the right query parameter ?theme=Jupyterlab Dark
.
For JupyterLite and RetroLite
We can probably force JupyterLab to expose its app object with:
iframe.addEventListener('load', () => {
iframe.contentWindow.document.body.dataset.exposeAppInBrowser = "true";
});
And then use the iframe.contentWindow.jupyterapp
object to access the themeManager and make it switch to the theme flavor that is currently used in the docs?
Pinging @jtpio in case you have some ideas
We can probably force JupyterLab to expose its app object with:
This can also be enabled with the exposeAppInBrowser
setting in jupyter-lite.json
: https://jupyterlite.readthedocs.io/en/latest/reference/schema-v0.html#jupyter-config-data
Maybe jupyterlite/jupyterlite#525 could also be relevant and apply to more apps than just repl
.
Another idea would be to have a JupyterLab extension honoring the prefers-color-scheme
CSS media feature: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme
Which is what most light / dark themes use nowadays to choose a default theme on page load.
Edit: tracked in jupyterlab/jupyterlab#8777
Although this could be done separately and would not sync the theme when a user switches from light to dark by clicking on the button.
I wanted to work on it from our theme side and I have few comments to add here
Another idea would be to have a JupyterLab extension honoring the
prefers-color-scheme
CSS media feature
That won't be sufficient as theming is not natively supported by Sphinx so the few theme implementing it (pydata-sphinx-theme
, sphinx-book
, lutra
and furo
to my knowledge) are doing it in different ways and can enforce theming that is not matching with this parameter.
Also as they are all doing it a different way, I think the best way to proceed is to expose a JS handle that themes can switch when changing the theme. by doing so you will be compatible with any theme as long as their maintainers are happy to support your extention. We are willing to work on it from pydata-sphinx-theme (pydata/pydata-sphinx-theme#745) but we are missing this interface.
looking down the web it seems that I'm not facing any cross-domain issues when manipulating the content of the iframe via javascript. I tried the following code and it worked like a charm:
var frm = document.querySelectorAll(".jupyterlite_sphinx_iframe")
var cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frm.forEach( frame => {
frame.contentWindow.document.head.appendChild(cssLink);
})
I think the next step for me is to change the css when a theme changed is triggered in the page.
3 questions:
- Are all the css already loaded in the iframe (meaning both the dark and light theme of jupyterlab) ?
- What is the parameter that drive the used theme in jupyterlite ?
- Is it the same for all 3 supported interfaces (jupyterlite, retrolite and replite) ?