jupyterlite-sphinx icon indicating copy to clipboard operation
jupyterlite-sphinx copied to clipboard

React to pydata-sphinx-theme theme change

Open martinRenou opened this issue 1 year ago • 5 comments

Problem

Somewhat related to https://github.com/pydata/pydata-sphinx-theme/issues/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

martinRenou avatar Jul 26 '22 13:07 martinRenou

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

jtpio avatar Jul 26 '22 14:07 jtpio

Maybe https://github.com/jupyterlite/jupyterlite/pull/525 could also be relevant and apply to more apps than just repl.

jtpio avatar Jul 26 '22 14:07 jtpio

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 https://github.com/jupyterlab/jupyterlab/issues/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.

jtpio avatar Jul 26 '22 14:07 jtpio

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 (https://github.com/pydata/pydata-sphinx-theme/issues/745) but we are missing this interface.

12rambau avatar Oct 18 '22 10:10 12rambau

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) ?

12rambau avatar Nov 14 '22 17:11 12rambau