diff --git a/CHANGELOG.md b/CHANGELOG.md index ee783d1..7c32ace 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ - 🧩 Open `.nde` files in H5Web by default - ✨ Improve error display when a file is deleted - ✨ Reload a file automatically when it is recreated +- ✨ Follow VS Code's theme by default instead of the operating system's +- ⚙️ Add `h5web.colorScheme` setting to control the color scheme behaviour + (requires reopening H5Web editors) - 🐛 Release the previous contents of the file from memory when it is reloaded - 🐛 Stop leaving a copy of every file opened from the explorer in VS Code's webview cache, where copies accumulated with no size limit and were never diff --git a/README.md b/README.md index 4ae6f4f..0ccebcf 100644 --- a/README.md +++ b/README.md @@ -86,3 +86,13 @@ This is an issue from VSCode `snap` package that [forces the use of `XWayland/X11` instead of `Wayland`](https://github.com/microsoft/vscode/issues/207033). Since it can not be worked around, our advice is use another VSCode installation instead (e.g. via `apt`). + +## Configuration + +### `h5web.colorScheme` + +Specifies whether to use a light or dark color scheme. By default, H5Web follows +VS Code's theme. + +> After changing this setting, please reopen your H5Web editors for the new +> color scheme to take effect. diff --git a/extension/H5WebViewer.ts b/extension/H5WebViewer.ts index 8cc7350..87693cc 100644 --- a/extension/H5WebViewer.ts +++ b/extension/H5WebViewer.ts @@ -143,6 +143,10 @@ export default class H5WebViewer implements CustomReadonlyEditorProvider { 'worker-src blob:', // for H5WasmLocalFileProvider's inline worker ]; + const colorScheme = workspace + .getConfiguration('h5web') + .get('colorScheme', 'vscode'); + return ` @@ -158,7 +162,7 @@ export default class H5WebViewer implements CustomReadonlyEditorProvider { - +
`; diff --git a/package.json b/package.json index ff75f67..e452108 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,29 @@ ], "priority": "option" } - ] + ], + "configuration": { + "title": "H5Web", + "properties": { + "h5web.colorScheme": { + "description": "Specifies whether to use a light or dark color scheme. By default, follow VS Code's theme. Alternatively, follow the operating system's scheme or force a specific scheme.", + "type": "string", + "default": "vscode", + "enum": [ + "vscode", + "system", + "light", + "dark" + ], + "enumDescriptions": [ + "Follow VS Code's theme", + "Follow the system's color scheme", + "Use a light color scheme", + "Use a dark color scheme" + ] + } + } + } }, "main": "./out/main.js", "scripts": { diff --git a/src/App.tsx b/src/App.tsx index d2d8f69..b5573e4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -36,9 +36,16 @@ function App() { return

File does not exist

; } + /* Configured color scheme is passed to webview via `data-color-scheme` attribute. + * If "system", let H5Web's default behaviour kick in (i.e. `prefer-color-scheme: dark`). + * Otherwise, take over control of the color scheme with CSS. */ + const { colorScheme } = document.body.dataset; + const disableDarkMode = colorScheme !== 'system'; + if (fileInfo.size >= MAX_SIZE_IN_BYTES) { return ( File is too large to be opened from the explorer (max 2 GB). Please @@ -58,7 +65,7 @@ function App() { }} > Loading...

}> - +
); diff --git a/src/StandaloneViewer.tsx b/src/StandaloneViewer.tsx index a44a6f6..481c9f4 100644 --- a/src/StandaloneViewer.tsx +++ b/src/StandaloneViewer.tsx @@ -5,11 +5,12 @@ import { type ReactNode, useState } from 'react'; import { getExportURL, getPlugin } from './utils'; interface Props { + disableDarkMode: boolean; customMessage?: ReactNode; } function StandaloneViewer(props: Props) { - const { customMessage } = props; + const { disableDarkMode, customMessage } = props; const [fallbackFile, setFallbackFile] = useState(); if (!fallbackFile) { @@ -31,7 +32,7 @@ function StandaloneViewer(props: Props) { getExportURL={getExportURL} getPlugin={getPlugin} > - + ); } diff --git a/src/Viewer.tsx b/src/Viewer.tsx index 4d3d276..f5fa652 100644 --- a/src/Viewer.tsx +++ b/src/Viewer.tsx @@ -8,10 +8,11 @@ import WidthGuard from './WidthGuard.js'; interface Props { fileInfo: FileInfo; + disableDarkMode: boolean; } function Viewer(props: Props) { - const { fileInfo } = props; + const { fileInfo, disableDarkMode } = props; const buffer = suspend(async () => { // Make a range request so that VS Code's webview service worker doesn't keep a copy of it @@ -33,7 +34,7 @@ function Viewer(props: Props) { getPlugin={getPlugin} > - + ); diff --git a/src/index.css b/src/index.css index b868da3..cc60980 100644 --- a/src/index.css +++ b/src/index.css @@ -9,3 +9,30 @@ [data-fill-height] { height: 100vh; } + +[data-color-scheme='dark'] #root, +[data-color-scheme='vscode'][data-vscode-theme-kind='vscode-dark'] #root { + filter: invert(); + + /* Set shadows to lighter colors so they remain dark once inverted */ + --h5w-btnRaised--shadowColor: #f5f5f5; + --h5w-btnRaised-hover--shadowColor: #fff; + --h5w-domainSlider-track--shadowColor: #f5f5f5; + --h5w-domainSlider-dataTrack--shadowColor: #fff; + + /* Change line colors for better contrast once inverted */ + --h5w-line--color: deepskyblue; + --h5w-line--colorAux: orange, lightgreen, red, violet, gold; +} + +[data-color-scheme='dark'] #root [data-keep-colors], +[data-color-scheme='dark'] #root [data-keep-canvas-colors] canvas, +[data-color-scheme='vscode'][data-vscode-theme-kind='vscode-dark'] + #root + [data-keep-colors], +[data-color-scheme='vscode'][data-vscode-theme-kind='vscode-dark'] + #root + [data-keep-canvas-colors] + canvas { + filter: invert(); /* invert back to normal colors */ +}