Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Theme initialisation according to JupyterLab or Voilà (lab) #135

Closed
guimillet opened this issue Mar 28, 2021 · 16 comments · Fixed by #196
Closed

Theme initialisation according to JupyterLab or Voilà (lab) #135

guimillet opened this issue Mar 28, 2021 · 16 comments · Fixed by #196

Comments

@guimillet
Copy link
Contributor

guimillet commented Mar 28, 2021

Theme.dark is initialised as False in Themes.py and this value sets the vuetify theme in Themes.js.

When JupyterLab or Voilà is set to a dark theme, the ipyvuetify widgets are rendered by default in light theme, and one has to manually execute ipyvuetify.model.dark = True to change the ipyvuetify theme.

Could this be changed in Themes.js line 22 by adding

if (document.body.classList.contains('theme-dark') ||
    document.body.attributes.getNamedItem("data-jp-theme-light") &&
    document.body.attributes.getNamedItem('data-jp-theme-light').value=='false') {
    this.dark = true;
}

The first condition checks the use of a dark theme in a Voilà display (with the default lab template) and the second in JupyterLab display.

I tested it in a VuetifyTemplate and it worked.

@12rambau
Copy link
Contributor

12rambau commented Apr 5, 2021

I love this idea ❤️

@mariobuikhuizen
Copy link
Collaborator

This feature was implemented in v1.7.0 (9be42b9)

@guimillet
Copy link
Contributor Author

Thanks for the implementation with respect to JupyterLab. What about adding the check for Voilà on line 39 of Theme.js?

@mariobuikhuizen
Copy link
Collaborator

It should work when using Voila with e.g. --theme=dark (https://voila.readthedocs.io/en/stable/customize.html)

@guimillet
Copy link
Contributor Author

I have tried with --theme=dark as well as with the URL query string ?voila-theme=dark, it didn't work. Does it work on your side? What source code is supposed to catch Voilà dark setting?

@mariobuikhuizen
Copy link
Collaborator

You are right, I misremembered, I was using the VoilaVuetify template in which this is handled.

Would you want to make a PR for this? If not, I can make the change.

@mariobuikhuizen
Copy link
Collaborator

Although it might work without that change in a future version of Voila: voila-dashboards/voila#846

@guimillet
Copy link
Contributor Author

I'll try to make a PR. I have an issue with building the extension. After modifying Themes.js, I run jlpm run prepare in the js folder, but webpack complains as follows:

ERROR in ./lib/Themes.js
Module not found: Error: Can't resolve './plugins/vuetify' in '[...]/src/ipyvuetify/js/lib'
@ ./lib/Themes.js 4:0-40 21:9-16 28:10-17 34:6-13 36:6-13 38:6-13 42:6-13 73:9-16 79:6-13 81:8-15
@ ./lib/nodepsEmbed.js

If I add .js to ./plugins/vuetify, the error disappears.

How do you usually rebuild ipyvuetify under development?

I had a look at Jupyterlab documentation and the cookiecutter-ts extension README, but ipyvuetify seems not to follow the same structure (package.json is in js folder and has no general build script).

@mariobuikhuizen
Copy link
Collaborator

It's based on an older js cookiecutter and is also supporting the classic notebook. I'll have to take a look why it's not building.

@mariobuikhuizen
Copy link
Collaborator

Running npm run prepare in the js directory works for me.

After running jupyter labextension develop . --overwrite in the top directory, then running npm run watch in the js directory also works for me.

@guimillet
Copy link
Contributor Author

I still get an error with npm run prepare for two children of webpack, when it processes ./lib/nodeps.js and ./lib/nodepsEmbed.js:

Child
    Hash: da66faa312a62ab78080
    Time: 2942ms
    Built at: 14/09/2021 08:58:30
    Entrypoint main =
    [0] external "jupyter-vue" 42 bytes {0} [built]
    [1] external "@jupyter-widgets/base" 42 bytes {0} [built]
    [2] ./lib/public-path.js 390 bytes {0} [built]
    [3] ./lib/styles.css 1.06 KiB {0} [built]
    [4] ./node_modules/css-loader/dist/cjs.js!./lib/styles.css 858 bytes {0} [built]
    [8] ./package.json 2.36 KiB {0} [built]
    [9] ./lib/nodeps.js + 167 modules 150 KiB {0} [built]
        | ./lib/nodeps.js 54 bytes [built]
        | ./lib/nodepsEmbed.js 342 bytes [built]
        | ./src/nodepsVuetifyView.js 444 bytes [built]
        | ./lib/generated/index.js 7.76 KiB [built]
        | ./lib/Html.js 501 bytes [built]
        | ./lib/VuetifyTemplate.js 531 bytes [built]
        | ./lib/Themes.js 2.59 KiB [built]
        | ./lib/generated/VuetifyWidget.js 530 bytes [built]
        | ./lib/generated/Text.js 394 bytes [built]
        | ./lib/generated/App.js 430 bytes [built]
        | ./lib/generated/AppBar.js 1.33 KiB [built]
        | ./lib/generated/AppBarNavIcon.js 414 bytes [built]
        | ./lib/generated/Alert.js 1020 bytes [built]
        | ./lib/generated/Autocomplete.js 2.17 KiB [built]
        | ./lib/generated/Avatar.js 665 bytes [built]
        |     + 153 hidden modules
        + 3 hidden modules
    
    ERROR in ./lib/Themes.js
    Module not found: Error: Can't resolve './plugins/vuetify' in '/home/guillaume/src/ipyvuetify/js/lib'
     @ ./lib/Themes.js 4:0-40 21:9-16 28:10-17 34:6-13 36:6-13 38:6-13 42:6-13 73:9-16 79:6-13 81:8-15
     @ ./lib/nodepsEmbed.js
     @ ./lib/nodeps.js
    
    ERROR in chunk main [entry]
    nodeps.js
    /home/guillaume/src/ipyvuetify/js/lib/nodeps.js cfbd2241da5a323bdbb1837bc399228b
    Assigning to rvalue (29:10)
    |       ThemeModel.themeManager.themeChanged.connect(() => {
    |         if (this.get('dark') === null) {
    |           !(function webpackMissingModule() { var e = new Error("Cannot find module './plugins/vuetify'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()).framework.theme.dark = document.body.dataset.jpThemeLight === 'false';
    |         }
    |       }, this);
Child
    Hash: a46f58f9ab21d5221240
    Time: 1825ms
    Built at: 14/09/2021 08:58:29
    Entrypoint main =
    [0] external "jupyter-vue" 42 bytes {0} [built]
    [1] external "@jupyter-widgets/base" 42 bytes {0} [built]
    [2] ./lib/styles.css 1.06 KiB {0} [built]
    [3] ./node_modules/css-loader/dist/cjs.js!./lib/styles.css 858 bytes {0} [built]
    [7] ./package.json 2.36 KiB {0} [built]
    [8] ./lib/nodepsEmbed.js + 166 modules 150 KiB {0} [built]
        | ./lib/nodepsEmbed.js 342 bytes [built]
        | ./src/nodepsVuetifyView.js 444 bytes [built]
        | ./lib/generated/index.js 7.76 KiB [built]
        | ./lib/Html.js 501 bytes [built]
        | ./lib/VuetifyTemplate.js 531 bytes [built]
        | ./lib/Themes.js 2.59 KiB [built]
        | ./lib/generated/VuetifyWidget.js 530 bytes [built]
        | ./lib/generated/Text.js 394 bytes [built]
        | ./lib/generated/App.js 430 bytes [built]
        | ./lib/generated/AppBar.js 1.33 KiB [built]
        | ./lib/generated/AppBarNavIcon.js 414 bytes [built]
        | ./lib/generated/Alert.js 1020 bytes [built]
        | ./lib/generated/Autocomplete.js 2.17 KiB [built]
        | ./lib/generated/Avatar.js 665 bytes [built]
        | ./lib/generated/Badge.js 824 bytes [built]
        |     + 152 hidden modules
        + 3 hidden modules
    
    ERROR in ./lib/Themes.js
    Module not found: Error: Can't resolve './plugins/vuetify' in '/home/guillaume/src/ipyvuetify/js/lib'
     @ ./lib/Themes.js 4:0-40 21:9-16 28:10-17 34:6-13 36:6-13 38:6-13 42:6-13 73:9-16 79:6-13 81:8-15
     @ ./lib/nodepsEmbed.js
    
    ERROR in chunk main [entry]
    nodeps.js
    /home/guillaume/src/ipyvuetify/js/lib/nodepsEmbed.js 216d9b2e91b735de5c7349321e4700f4
    Assigning to rvalue (29:10)
    |       ThemeModel.themeManager.themeChanged.connect(() => {
    |         if (this.get('dark') === null) {
    |           !(function webpackMissingModule() { var e = new Error("Cannot find module './plugins/vuetify'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()).framework.theme.dark = document.body.dataset.jpThemeLight === 'false';
    |         }
    |       }, this);

No issue with ./lib/notebook.js and ./lib/embed.js.

The log file from npm for build:webpack reads:

0 verbose cli [
0 verbose cli   '/usr/bin/node',
0 verbose cli   '/usr/share/nodejs/npm/bin/npm-cli.js',
0 verbose cli   'run',
0 verbose cli   'build:webpack'
0 verbose cli ]
1 info using npm@7.5.2
2 info using node@v12.21.0
3 timing config:load:defaults Completed in 2ms
4 timing config:load:file:/usr/share/nodejs/npm/npmrc Completed in 2ms
5 timing config:load:builtin Completed in 2ms
6 timing config:load:cli Completed in 1ms
7 timing config:load:env Completed in 1ms
8 timing config:load:file:/home/guillaume/src/ipyvuetify/js/.npmrc Completed in 1ms
9 timing config:load:project Completed in 1ms
10 timing config:load:file:/home/guillaume/.npmrc Completed in 0ms
11 timing config:load:user Completed in 0ms
12 timing config:load:file:/etc/npmrc Completed in 0ms
13 timing config:load:global Completed in 0ms
14 timing config:load:cafile Completed in 0ms
15 timing config:load:validate Completed in 1ms
16 timing config:load:setUserAgent Completed in 0ms
17 timing config:load:setEnvs Completed in 1ms
18 timing config:load Completed in 9ms
19 verbose npm-session f2e98852e7934577
20 timing npm:load Completed in 17ms
21 timing command:run-script Completed in 7166ms
22 verbose stack Error: command failed
22 verbose stack     at ChildProcess.<anonymous> (/usr/share/nodejs/@npmcli/promise-spawn/index.js:64:27)
22 verbose stack     at ChildProcess.emit (events.js:314:20)
22 verbose stack     at maybeClose (internal/child_process.js:1022:16)
22 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:287:5)
23 verbose pkgid jupyter-vuetify@1.8.1
24 verbose cwd /home/guillaume/src/ipyvuetify/js
25 verbose Linux 5.10.0-8-amd64
26 verbose argv "/usr/bin/node" "/usr/share/nodejs/npm/bin/npm-cli.js" "run" "build:webpack"
27 verbose node v12.21.0
28 verbose npm  v7.5.2
29 error code 2
30 error path /home/guillaume/src/ipyvuetify/js
31 error command failed
32 error command sh -c webpack
33 verbose exit 2

Could it come from an incompatible version of one of the compilers? npm list answers:

jupyter-vuetify@1.8.1 /home/guillaume/src/ipyvuetify/js
├── @babel/cli@7.15.4
├── @babel/core@7.15.5
├── @babel/preset-env@7.15.6
├── @jupyter-widgets/base@4.0.0
├── @jupyterlab/apputils@3.1.10
├── @jupyterlab/builder@3.1.11
├── @mariobuikhuizen/vuetify@2.2.26-rc.0
├── @mdi/font@4.9.95
├── ajv@6.12.6
├── core-js@3.17.3
├── css-loader@2.1.1
├── eslint-config-airbnb-base@13.2.0
├── eslint-plugin-import@2.24.2
├── eslint-plugin-vue@5.2.3
├── eslint@5.16.0
├── file-loader@3.0.1
├── jupyter-vue@1.5.0
├── lodash@4.17.21
├── material-design-icons-iconfont@5.0.1
├── npm-run-all@4.1.5
├── rimraf@2.7.1
├── style-loader@0.23.1
├── typeface-roboto@0.0.54
├── webpack-cli@3.3.12
└── webpack@4.46.0

@mariobuikhuizen
Copy link
Collaborator

Can you confirm that after running npm run build:babel lib/plugins/vuetify.js is present?

My dependencies are indeed different, you should have the same after resetting package-lock.json (if it has changed) and running npm install

├── @babel/cli@7.5.0
├── @babel/core@7.4.4
├── @babel/preset-env@7.4.4
├── @jupyter-widgets/base@2.0.1
├── @jupyterlab/apputils@3.0.9
├── @jupyterlab/builder@3.0.0
├── @mariobuikhuizen/vuetify@2.2.26-rc.0
├── @mdi/font@4.9.95
├── ajv@6.10.0
├── core-js@3.0.1
├── css-loader@2.1.1
├── eslint-config-airbnb-base@13.1.0
├── eslint-plugin-import@2.17.2
├── eslint-plugin-vue@5.2.2
├── eslint@5.16.0
├── file-loader@3.0.1
├── jupyter-vue@1.0.0
├── lodash@4.17.20
├── material-design-icons-iconfont@5.0.1
├── npm-run-all@4.1.5
├── rimraf@2.6.3
├── style-loader@0.23.1
├── typeface-roboto@0.0.54
├── webpack-cli@3.3.2
└── webpack@4.31.0

@guimillet
Copy link
Contributor Author

Yes, lib/plugins/vuetify.js is present. Resetting package-lock.json (changed by pip install I guess?) didn't help.

I gave a try with a fresh clone of ipvuetify, as follows:

git clone https://github.com/mariobuikhuizen/ipyvuetify.git mario_ipyvuetify
cd mario_ipyvuetify/
pip install -e .
jupyter labextension develop . --overwrite
cd js
npm run prepare

npm ends with the same error as before.

@guimillet
Copy link
Contributor Author

guimillet commented Oct 28, 2021

Finally, I found the cause: the file https://github.com/mariobuikhuizen/ipyvuetify/blob/master/js/src/plugins/noDepsVuetify.js has the letter D in capital whereas the webpack config file defines the alias 'src/plugins/nodepsVuetify.js'. Renaming js/src/plugins/noDepsVuetify.js to js/src/plugins/nodepsVuetify.js solved the issue.

Running npm run prepare in the js directory works for me.

@mariobuikhuizen Did you run it on macOS?

I am using Linux. Apparently, webpack behaves differently between macOS and Linux with respect to case sensitivity: https://stackoverflow.com/questions/28789050/webpack-fine-on-macos-loader-errors-on-linux
It may be good to use a Webpack plugin like case-sensitive-paths-webpack-plugin to notive such issues in the future.

@guimillet
Copy link
Contributor Author

guimillet commented Oct 28, 2021

Currently, after displaying a widget in Jupyterlab, v.theme.dark remains None, and if v.theme.dark is set, then the widget theme remains that of v.theme.dark whatever the Jupyterlab or Voila lab/vuetify dark/light theme, so the None value corresponds to an 'inherit' behavior. I thought it would be useful to add a dark_jlab trait to Themes to know the inherited theme on the python side, but eventually I don't see any clear need for that. Do you think it would be useful? If so, I can add it to the PR.

@mariobuikhuizen
Copy link
Collaborator

Great find! I indeed run it on macOS, which has a case-insensitive file system.

It might be useful to have dark_jlab trait, but I can't think of a scenario in which one would need it yet.

guimillet added a commit to guimillet/ipyvuetify that referenced this issue Dec 8, 2021
The class names of the document's body's are checked whether they
contain 'theme-light' or 'theme-dark', which indicates the theme loaded
by Voilà for the lab template.

The patch also adds 'dark_jlab' attribute to know the inherited theme in JupyterLab.

Resolves: widgetti#135
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants