Skip to content
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
29 changes: 28 additions & 1 deletion style/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -364,13 +364,40 @@

.chat-mode-select {
height: 24px;
background-color: initial;

/* The footer's own background, so the select blends in as it did when this
was transparent; an explicit color (rather than transparent) is what
keeps the native popup from falling back to the light palette. */
background-color: var(--jp-cell-editor-background, var(--jp-layout-color1));
color: var(--jp-ui-font-color1);
padding: 0 5px;
border-color: var(--jp-border-color0);
outline: none;
}

/* The native option list is drawn from the option's own colors, not the
select's, in some browsers (Firefox) and falls back to the light UI palette
otherwise. Without these, light theme text lands on a light popup in a dark
theme and the choices are unreadable. The fallbacks keep a theme that leaves
a variable out from bringing that back. */

/* The chat mode popup matches the select it belongs to, so the closed and open
states are the same tone. */
.chat-mode-select option {
background-color: var(
--jp-cell-editor-background,
var(--jp-layout-color1, Canvas)
);
color: var(--jp-ui-font-color0, CanvasText);
}

.nbi-form-field select option,
.config-dialog-body select option,
.nbi-perf-control select option {
background-color: var(--jp-layout-color2, var(--jp-layout-color1, Canvas));
color: var(--jp-ui-font-color0, CanvasText);
}

.permission-mode-container {
position: relative;
display: flex;
Expand Down
66 changes: 66 additions & 0 deletions tests/ts/select-theme-css.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Mehmet Bektas <mbektasgh@outlook.com>

// The chat mode dropdown reset its background to `initial` while keeping a
// theme-derived text color, so in a dark JupyterLab theme the native option
// list rendered light text on a light popup. jsdom cannot render a native
// popup, so pin the stylesheet declarations that prevent it.
import * as fs from 'fs';
import * as path from 'path';

const css = fs
.readFileSync(path.join(__dirname, '..', '..', 'style', 'base.css'), 'utf8')
.replace(/\/\*[\s\S]*?\*\//g, '');

function declarations(selector: string): string {
const rules = css
.split('}')
.map(chunk => chunk.split('{'))
.filter(
([sel, body]) =>
body !== undefined &&
sel
.split(',')
.map(part => part.trim())
.includes(selector)
);
return rules.map(([, body]) => body).join('\n');
}

// What the chat mode select sits on, so it looks as it did when transparent.
const FOOTER_BACKGROUND = /var\(\s*--jp-cell-editor-background/;

describe('select colors follow the JupyterLab theme', () => {
it('gives the chat mode select the footer background, not transparent', () => {
const body = declarations('.chat-mode-select');
expect(body).toMatch(
new RegExp(`background-color:\\s*${FOOTER_BACKGROUND.source}`)
);
expect(body).not.toMatch(/background-color:\s*initial/);
});

it('matches the chat mode popup to the select it belongs to, with fallbacks', () => {
const body = declarations('.chat-mode-select option');
expect(body).toMatch(
/background-color:\s*var\(\s*--jp-cell-editor-background,\s*var\(\s*--jp-layout-color1,\s*Canvas\s*\)\s*\)/
);
expect(body).toMatch(
/\bcolor:\s*var\(\s*--jp-ui-font-color0,\s*CanvasText\s*\)/
);
});

it.each([
'.nbi-form-field select option',
'.config-dialog-body select option',
'.nbi-perf-control select option'
])('themes the option list for %s, with fallbacks', selector => {
const body = declarations(selector);
// A theme that omits --jp-layout-color2 must not leave the option
// transparent, which is the original bug.
expect(body).toMatch(
/background-color:\s*var\(\s*--jp-layout-color2,\s*var\(\s*--jp-layout-color1,\s*Canvas\s*\)\s*\)/
);
expect(body).toMatch(
/\bcolor:\s*var\(\s*--jp-ui-font-color0,\s*CanvasText\s*\)/
);
});
});
Loading