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

Universal (nearly) scrollbar styling #6026

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions packages/application/style/scrollbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,88 @@
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/

/*
* Mozilla scrollbar styling
*/

/* use standard opaque scrollbars for most nodes */
div.jp-LabShell[data-theme-scrollbars='true'] {
scrollbar-color: rgb(var(--jp-scrollbar-thumb-color))
var(--jp-scrollbar-background-color);
}

/* for code nodes, use a transparent style of scrollbar */
[data-theme-scrollbars='true'] .CodeMirror-hscrollbar,
[data-theme-scrollbars='true'] .CodeMirror-vscrollbar {
scrollbar-color: rgba(var(--jp-scrollbar-thumb-color), 0.5) transparent;
}

/*
* Webkit scrollbar styling
*/

/* use standard opaque scrollbars for most nodes */

[data-theme-scrollbars='true'] ::-webkit-scrollbar,
[data-theme-scrollbars='true'] ::-webkit-scrollbar-corner {
background: var(--jp-scrollbar-background-color);
}

[data-theme-scrollbars='true'] ::-webkit-scrollbar-thumb {
background: rgb(var(--jp-scrollbar-thumb-color));
border: var(--jp-scrollbar-thumb-margin) solid transparent;
background-clip: content-box;
border-radius: var(--jp-scrollbar-thumb-radius);
}

[data-theme-scrollbars='true'] ::-webkit-scrollbar-track:horizontal {
border-left: var(--jp-scrollbar-endpad) solid
var(--jp-scrollbar-background-color);
border-right: var(--jp-scrollbar-endpad) solid
var(--jp-scrollbar-background-color);
}

[data-theme-scrollbars='true'] ::-webkit-scrollbar-track:vertical {
border-top: var(--jp-scrollbar-endpad) solid
var(--jp-scrollbar-background-color);
border-bottom: var(--jp-scrollbar-endpad) solid
var(--jp-scrollbar-background-color);
}

/* for code nodes, use a transparent style of scrollbar */

[data-theme-scrollbars='true'] .CodeMirror-hscrollbar::-webkit-scrollbar,
[data-theme-scrollbars='true'] .CodeMirror-vscrollbar::-webkit-scrollbar,
[data-theme-scrollbars='true'] .CodeMirror-hscrollbar::-webkit-scrollbar-corner,
[data-theme-scrollbars='true']
.CodeMirror-vscrollbar::-webkit-scrollbar-corner {
background-color: transparent;
}

[data-theme-scrollbars='true'] .CodeMirror-hscrollbar::-webkit-scrollbar-thumb,
[data-theme-scrollbars='true'] .CodeMirror-vscrollbar::-webkit-scrollbar-thumb {
background: rgba(var(--jp-scrollbar-thumb-color), 0.5);
border: var(--jp-scrollbar-thumb-margin) solid transparent;
background-clip: content-box;
border-radius: var(--jp-scrollbar-thumb-radius);
}

[data-theme-scrollbars='true']
.CodeMirror-hscrollbar::-webkit-scrollbar-track:horizontal {
border-left: var(--jp-scrollbar-endpad) solid transparent;
border-right: var(--jp-scrollbar-endpad) solid transparent;
}

[data-theme-scrollbars='true']
.CodeMirror-vscrollbar::-webkit-scrollbar-track:vertical {
border-top: var(--jp-scrollbar-endpad) solid transparent;
border-bottom: var(--jp-scrollbar-endpad) solid transparent;
}

/*
* Phosphor
*/

.p-ScrollBar[data-orientation='horizontal'] {
min-height: 16px;
max-height: 16px;
Expand Down
6 changes: 6 additions & 0 deletions packages/apputils-extension/schema/themes.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
"title": "Selected Theme",
"description": "Application-level visual styling theme",
"default": "JupyterLab Light"
},
"theme-scrollbars": {
"type": "boolean",
"title": "Scrollbar Theming",
"description": "Enable/disable styling of the application scrollbars",
"default": false
}
},
"type": "object"
Expand Down
8 changes: 8 additions & 0 deletions packages/apputils-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ const themes: JupyterFrontEndPlugin<IThemeManager> = {
currentTheme = args.newValue;
app.shell.dataset.themeLight = String(manager.isLight(currentTheme));
app.shell.dataset.themeName = currentTheme;
if (
app.shell.dataset.themeScrollbars !==
String(manager.themeScrollbars(currentTheme))
) {
app.shell.dataset.themeScrollbars = String(
manager.themeScrollbars(currentTheme)
);
}
commands.notifyCommandChanged(CommandIDs.changeTheme);
});

Expand Down
31 changes: 29 additions & 2 deletions packages/apputils/src/thememanager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,17 @@ export class ThemeManager {
return this._themes[name].isLight;
}

/**
* Test whether a given theme styles scrollbars,
* and if the user has scrollbar styling enabled.
*/
themeScrollbars(name: string): boolean {
return (
!!this._settings.composite['theme-scrollbars'] &&
!!this._themes[name].themeScrollbars
);
}

/**
* Handle the current settings.
*/
Expand Down Expand Up @@ -245,13 +256,23 @@ export class ThemeManager {
return Promise.all([old, themes[theme].load()])
.then(() => {
this._current = theme;
Private.fitAll(this._host);
splash.dispose();
this._themeChanged.emit({
name: 'theme',
oldValue: current,
newValue: theme
});

// Need to force a redraw of the app here to avoid a Chrome rendering
// bug that can leave the scrollbars in an invalid state
this._host.hide();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok with this workaround, but let's open a follow up issue so we have a reminder to revisit this (hopefully Chrome will fix it)


// If we hide/show the widget too quickly, no redraw will happen.
// requestAnimationFrame delays until after the next frame render.
requestAnimationFrame(() => {
this._host.show();
Private.fitAll(this._host);
splash.dispose();
});
})
.catch(reason => {
this._onError(reason);
Expand Down Expand Up @@ -333,6 +354,12 @@ export namespace ThemeManager {
*/
isLight: boolean;

/**
* Whether the theme includes styling for the scrollbar.
* If set to false, this theme will leave the native scrollbar untouched.
*/
themeScrollbars?: boolean;

/**
* Load the theme.
*
Expand Down
1 change: 1 addition & 0 deletions packages/theme-dark-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
manager.register({
name: 'JupyterLab Dark',
isLight: false,
themeScrollbars: true,
load: () => manager.loadCSS(style),
unload: () => Promise.resolve(undefined)
});
Expand Down
14 changes: 14 additions & 0 deletions packages/theme-dark-extension/style/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -374,4 +374,18 @@ all of MD as it is not optimized for dense, information rich UIs.
--jp-search-toggle-off-opacity: 0.5;
--jp-search-toggle-hover-opacity: 0.75;
--jp-search-toggle-on-opacity: 1;

/* scrollbar related styles. Supports every browser except Edge. */

/* colors based on JetBrain's Darcula theme */

--jp-scrollbar-background-color: #3f4244;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a note to say where this color came from - otherwise looks arbitrary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/* Based on the JetBrains Darcula theme */

All of this CSS is copied directly from my Darcula theme. I'm no designer, so when I couldn't find an authoritative reference for Material Dark, I figured it was safer to just leave the colors alone (they do look pretty good). If you want to point me to a spec (or just an example of a good Material Dark theme in action) I'd be happy to change these.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note added

--jp-scrollbar-thumb-color: 88, 96, 97; /* need to specify thumb color as an RGB triplet */

--jp-scrollbar-endpad: 3px; /* the minimum gap between the thumb and the ends of a scrollbar */

/* hacks for setting the thumb shape. These do nothing in Firefox */

--jp-scrollbar-thumb-margin: 3.5px; /* the space in between the sides of the thumb and the track */
--jp-scrollbar-thumb-radius: 9px; /* set to a large-ish value for rounded endcaps on the thumb */
}
1 change: 1 addition & 0 deletions packages/theme-light-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
manager.register({
name: 'JupyterLab Light',
isLight: true,
themeScrollbars: false,
load: () => manager.loadCSS(style),
unload: () => Promise.resolve(undefined)
});
Expand Down