feat(themes): Built-in Solarized and One light/dark themes (#85)
Adds Solarized Light, Solarized Dark, One Light and One Dark as built-in themes across the workbench, editor, terminal and Mermaid, keeping the original palettes (MIT notices in THIRD_PARTY_LICENSES.md, mapping in docs/themes.md). - Native window colours are read from tokens.css at build time (`theme_frame.rs`) instead of a second colour table. - Startup restores the built-in palette before first paint. - Editor schemes, the terminal and Mermaid refresh on switches between themes of the same kind. - The plugin packages of the same themes are removed. - A test requires every built-in palette theme to define each token (only listed ones may inherit from the base theme), so new tokens can't silently miss them. Co-authored-by: Claude <[email protected]> Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
No files matched your search
|
Після Ширина: | Висота: | Розмір: 169 KiB |
|
Після Ширина: | Висота: | Розмір: 133 KiB |
|
Після Ширина: | Висота: | Розмір: 171 KiB |
|
Після Ширина: | Висота: | Розмір: 135 KiB |
|
Після Ширина: | Висота: | Розмір: 164 KiB |
|
Після Ширина: | Висота: | Розмір: 129 KiB |
|
Після Ширина: | Висота: | Розмір: 168 KiB |
|
Після Ширина: | Висота: | Розмір: 131 KiB |
@@ -1,7 +1,8 @@
|
||||
# Theme plugins
|
||||
|
||||
OpenIDEA ships three built-in themes (Islands Light, Islands Dark, High
|
||||
Contrast). Everything else comes from **theme plugins**, the same model as
|
||||
OpenIDEA ships seven [built-in themes](../themes.md): Islands Light, Islands Dark,
|
||||
High Contrast, Solarized Light, Solarized Dark, One Light and One Dark. Additional
|
||||
themes come from **theme plugins**, the same model as
|
||||
IntelliJ IDEA, where most themes are plugins rather than part of the IDE.
|
||||
|
||||
A theme plugin is data only. Like an IntelliJ theme (a `.theme.json` plus an
|
||||
@@ -16,31 +17,6 @@ my-theme/
|
||||
└─ my-theme.scheme.json # editor colours, optional (IntelliJ: .icls)
|
||||
```
|
||||
|
||||
## Ready-made theme plugins
|
||||
|
||||
The repository's [`plugins/`](../../plugins) folder holds two complete theme
|
||||
plugins, each with a light and a dark theme and an editor colour scheme
|
||||
(syntax, editor and terminal ANSI colours):
|
||||
|
||||
| Package | Themes | Palette |
|
||||
|---|---|---|
|
||||
| [`plugins/theme-solarized`](../../plugins/theme-solarized) | Solarized Light, Solarized Dark | [Solarized](https://github.com/altercation/solarized) by Ethan Schoonover |
|
||||
| [`plugins/theme-one`](../../plugins/theme-one) | One Light, One Dark | Atom [One Light](https://github.com/atom/one-light-syntax) / [One Dark](https://github.com/atom/one-dark-syntax) by GitHub |
|
||||
|
||||
Both palettes are MIT-licensed; each package carries the notice in its
|
||||
`LICENSE`, which is installed with it. To use one:
|
||||
|
||||
1. *Settings › Plugins › ⚙ › Install Plugin from Disk…* and pick the package
|
||||
folder (`plugins/theme-solarized` or `plugins/theme-one` of a checkout or a
|
||||
downloaded copy). Development builds also list both on the *Available*
|
||||
tab, where *Install* does the same.
|
||||
2. Select the plugin and press *Apply* next to a theme.
|
||||
|
||||
The IDE remembers the theme: the next start-up opens its windows, splash and
|
||||
workbench in the theme's colours before the plugin host has loaded.
|
||||
|
||||
## Writing a theme plugin
|
||||
|
||||
The quickest way to start is to copy [`templates/theme-plugin`](../../templates/theme-plugin).
|
||||
It contains *Harbor Night*, a complete example dark theme that sets every
|
||||
themeable token. The rest of this page covers the file format, the token
|
||||
@@ -307,9 +283,8 @@ A `fontStyle: "italic"` on comments maps to `"--syn-comment-style": "italic"`.
|
||||
- Text should keep at least WCAG AA contrast (4.5:1) on its surfaces. The
|
||||
built-in themes are checked by `src/features/settings/__tests__/contrast.test.ts`.
|
||||
- Repository checks (for changes to this repo): `pnpm vitest run scripts/theme`
|
||||
validates the template and the theme plugins in `plugins/` against
|
||||
tokens.css and keeps this reference current, and `cargo test -p ide-plugin`
|
||||
loads them through the plugin host.
|
||||
validates the template against tokens.css and keeps this reference current,
|
||||
and `cargo test -p ide-plugin` loads the template through the plugin host.
|
||||
|
||||
## Token reference
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# Built-in theme sources
|
||||
|
||||
OpenIDEA includes Islands Light, Islands Dark, High Contrast, Solarized Light,
|
||||
Solarized Dark, One Light and One Dark. Select them in Settings › Appearance,
|
||||
Welcome › Customize or the existing quick theme menu. The same themes are
|
||||
available as explicit editor schemes; “Theme default” follows the UI theme.
|
||||
“Sync with OS” uses the existing preferred light/dark theme settings. Existing
|
||||
ids (`light`, `dark`, `dark-hc`, `system`) and attribute overrides remain valid.
|
||||
|
||||
## Upstream palettes and licenses
|
||||
|
||||
All sources below are the original authors’ repositories, pinned for reproducibility.
|
||||
Full MIT notices are preserved in [THIRD_PARTY_LICENSES.md](../THIRD_PARTY_LICENSES.md).
|
||||
|
||||
| Theme | Original source revision | Palette / mapping source |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| Solarized Light / Dark | [Ethan Schoonover, 62f656a](https://github.com/altercation/solarized/tree/62f656a02f93c5190a8753159e34b385588d5ff3) | README’s sixteen exact sRGB hex colours; `vim-colors-solarized/colors/solarized.vim` semantic roles; iTerm2 ANSI slots |
|
||||
| One Light syntax | [GitHub / Atom, d845790](https://github.com/atom/one-light-syntax/tree/d84579027410c576086dfca14d934c4bd74b0438) | `styles/colors.less`, `styles/syntax-variables.less` |
|
||||
| One Dark syntax | [GitHub / Atom, 9c96f44](https://github.com/atom/one-dark-syntax/tree/9c96f4454362267ac45322063e193ccf9d2debb1) | `styles/colors.less`, `styles/syntax-variables.less` |
|
||||
| One Light UI | [GitHub / Atom, a27bce3](https://github.com/atom/one-light-ui/tree/a27bce35088ecd323e44f5c2510bcf2d4e9efcf8) | `styles/ui-variables.less`, `styles/ui-variables-custom.less` |
|
||||
| One Dark UI | [GitHub / Atom, 18c2143](https://github.com/atom/one-dark-ui/tree/18c2143d41e17b337fff6dc7024562c4d999be17) | `styles/ui-variables.less`, `styles/ui-variables-custom.less` |
|
||||
|
||||
## Mapping into OpenIDEA
|
||||
|
||||
`src/platform/themes.ts` registers the stable ids. `data-theme` retains the
|
||||
light/dark kind for icons, native controls and existing selectors;
|
||||
`data-color-theme` selects the additional palette. High Contrast continues to
|
||||
use `data-contrast="high"`. Plugin themes clear the built-in palette attribute
|
||||
and retain their existing light/dark fallback; removing a plugin restores the
|
||||
chosen built-in palette.
|
||||
|
||||
`src/styles/tokens.css` contains the shared mapping for all colour tokens and
|
||||
four palette blocks. No new dependency is required. Solarized uses base3/base2
|
||||
for light backgrounds and base03/base02 for dark backgrounds, base00/base0 for
|
||||
text, and the original eight accents. Vim’s statements are green, constants
|
||||
and strings cyan, identifiers blue, types yellow, and comments the original
|
||||
subdued base1/base01. Solarized’s original ANSI slot order is preserved (the
|
||||
bright slots intentionally include orange, violet and neutrals).
|
||||
|
||||
One retains the exact HSL definitions from Atom, avoiding rounded palette
|
||||
approximations: 230° / 1% / 98% light and 220° / 13% / 18% dark editor backgrounds;
|
||||
purple keywords, green strings, blue functions, red variables/tags, orange
|
||||
numbers and attributes, yellow classes, and the original mono-3 comments.
|
||||
UI frame/popup levels use Atom’s relative background lightness formulas with
|
||||
the matching syntax theme. OpenIDEA’s shared UI text uses the syntax foreground
|
||||
and mono-2 for readable secondary labels. Selection and cursor-line values
|
||||
follow Atom’s syntax variables. Atom does not define a terminal ANSI palette:
|
||||
One’s ANSI slots reuse its exact semantic syntax hues, repeating them for bright
|
||||
colours rather than inventing a different palette. One Light maps ANSI white
|
||||
and bright white to its mono-2 and mono-1 text colours so they remain visible
|
||||
on the light terminal background.
|
||||
|
||||
Components without an upstream equivalent (feedback banners, tool window states,
|
||||
search fills and focus decoration) use the original semantic hues, neutrals,
|
||||
or explicit `color-mix()` tints. This adapts colours to the existing layout;
|
||||
it does not recreate Atom’s or Vim’s UI. Platform traffic-light colours stay
|
||||
platform colours. Original subdued comments and some syntax accents have lower
|
||||
contrast than a high-contrast accessibility theme; High Contrast remains available.
|
||||
|
||||
Native windows open in the theme's frame colour before their page loads:
|
||||
`src-tauri/src/theme_frame.rs` reads `--bg-frame` of each built-in theme from
|
||||
`tokens.css` itself (resolving `var()` and `hsl()`), so there is no second
|
||||
colour table to keep in sync. Elsewhere the frontend resolves HSL and
|
||||
`color-mix()` tokens to RGB (`src/platform/cssColor.ts`) for Tauri's window
|
||||
API, the native Settings window, Mermaid and the terminal.
|
||||
|
||||
`public/boot.js` restores the palette (`data-color-theme`) and the splash's
|
||||
resolved frame, text and accent colours before the application stylesheet
|
||||
loads, so a restart in One Dark or Solarized shows no flash of another theme.
|
||||
The backend's settings persistence remains authoritative. Terminal, Mermaid
|
||||
and editor-scheme observers also watch palette changes within the same
|
||||
light/dark kind. Custom accents, explicit editor schemes, per-scheme attribute
|
||||
overrides, compact mode and accessibility options retain their precedence.
|
||||
|
||||
`src/features/settings/__tests__/contrast.test.ts` requires every palette theme
|
||||
to define every colour token of the base themes (in the shared mapping or its
|
||||
own block), so a token added to `tokens.css` later can't silently fall back to
|
||||
an Islands colour.
|
||||
|
||||
## Browser evidence
|
||||
|
||||
These approved screenshots are reused from the original theme implementation on
|
||||
0.1.15; regression checks are rerun against the upstream contribution base.
|
||||
Captured at 1400 × 900 in Linux Chromium 154 using OpenIDEA's public in-memory
|
||||
`acme-api` project / Kotlin fixture and synthetic ANSI terminal output. The
|
||||
terminal is a real xterm renderer, without a native PTY or shell. These images
|
||||
cover the shell, sidebar, editor, gutter, find matches, terminal, Settings,
|
||||
focused controls, disabled settings and the selected theme popup.
|
||||
|
||||
| Theme | Workbench, editor and terminal | Settings and theme popup |
|
||||
|---|---|---|
|
||||
| Solarized Light | [Screenshot](media/themes/solarized-light-workbench.png) | [Screenshot](media/themes/solarized-light-popup.png) |
|
||||
| Solarized Dark | [Screenshot](media/themes/solarized-dark-workbench.png) | [Screenshot](media/themes/solarized-dark-popup.png) |
|
||||
| One Light | [Screenshot](media/themes/one-light-workbench.png) | [Screenshot](media/themes/one-light-popup.png) |
|
||||
| One Dark | [Screenshot](media/themes/one-dark-workbench.png) | [Screenshot](media/themes/one-dark-popup.png) |
|
||||
|
||||
The browser regression also checks refresh / startup cache restoration,
|
||||
selection visibility, same-kind switches, the quick menu, existing themes,
|
||||
explicit editor schemes and preferred OS themes. Native startup colours are
|
||||
covered by Rust unit tests.
|
||||