diff --git a/src/pages/themeSetting/themeSetting.js b/src/pages/themeSetting/themeSetting.js index 9d10bd503..285509b30 100644 --- a/src/pages/themeSetting/themeSetting.js +++ b/src/pages/themeSetting/themeSetting.js @@ -3,7 +3,7 @@ import { javascript } from "@codemirror/lang-javascript"; // For CodeMirror preview import { EditorState } from "@codemirror/state"; import { oneDark } from "@codemirror/theme-one-dark"; -import { getThemeExtensions, getThemes } from "cm/themes"; +import { getThemeConfig, getThemeExtensions, getThemes } from "cm/themes"; import { basicSetup, EditorView } from "codemirror"; import Page from "components/page"; import searchBar from "components/searchbar"; @@ -111,15 +111,16 @@ export default function () { const currentTheme = appSettings.value.appTheme; let $currentItem; - themes.list().forEach((theme) => { + themes.list().forEach((themeSummary) => { + const theme = themes.get(themeSummary.id); const isCurrentTheme = theme.id === currentTheme; const isPremium = theme.version === "paid" && IS_FREE_VERSION; const $item = ( setAppTheme(theme, isPremium)} /> ); @@ -150,7 +151,7 @@ export default function () { setEditorTheme({ caption: t.caption, theme: t.id })} /> ); @@ -245,19 +246,9 @@ export default function () { list.get(`[theme="${theme}"]`)?.check(); } - function Item({ name, color, isDark, onclick, isCurrent, isPremium }) { + function Item({ name, swatches, onclick, isCurrent, isPremium }) { const check = ; const star = ; - let style = {}; - let className = "icon color"; - - if (color) { - style = { color }; - } else if (isDark) { - className += " dark"; - } else { - className += " light"; - } const $el = (
- + {createSwatchPreview(swatches)}
{name}
@@ -285,4 +276,51 @@ export default function () { }; return $el; } + + function createSwatchPreview(swatches) { + const colors = [...new Set((swatches || []).filter(Boolean))].slice(0, 3); + while (colors.length < 3) { + colors.push(colors[colors.length - 1] || "var(--border-color)"); + } + + return ( + + ); + } + + function getAppThemeSwatches(theme) { + if (!theme) { + return [ + "var(--primary-color)", + "var(--secondary-color)", + "var(--active-color)", + ]; + } + + return [theme.primaryColor, theme.secondaryColor, theme.activeColor]; + } + + function getEditorThemeSwatches(themeId) { + const config = getThemeConfig(themeId); + return [ + config.background, + config.keyword || config.function || config.foreground, + config.string || config.variable || config.foreground, + ]; + } } diff --git a/src/pages/themeSetting/themeSetting.scss b/src/pages/themeSetting/themeSetting.scss index f8328199c..d89b7ad7e 100644 --- a/src/pages/themeSetting/themeSetting.scss +++ b/src/pages/themeSetting/themeSetting.scss @@ -1,19 +1,55 @@ -#theme-setting { - display: flex; - flex-direction: column; - - #theme-preview:not(:empty) { - height: 120px; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); - box-shadow: 0 0 4px var(--box-shadow-color); - pointer-events: none; - } - - .icon.color.custom::before { - background-color: var(--primary-color); - } - - #theme-list { - flex: 1; - } -} \ No newline at end of file +#theme-setting { + display: flex; + flex-direction: column; + + #theme-preview:not(:empty) { + height: 120px; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 4px var(--box-shadow-color); + pointer-events: none; + } + + #theme-preview .cm-editor { + width: 100%; + } + + #theme-list { + flex: 1; + } + + .theme-swatch-slot { + display: flex; + align-items: center; + justify-content: center; + width: 60px; + min-width: 60px; + height: 60px; + flex-shrink: 0; + } + + .theme-swatch-preview { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 0.72fr); + grid-template-rows: repeat(2, minmax(0, 1fr)); + width: 1.5rem; + min-width: 1.5rem; + height: 1.5rem; + padding: 0.08rem; + box-sizing: border-box; + border: 1px solid var(--border-color); + border: 1px solid color-mix(in srgb, var(--border-color), transparent 18%); + border-radius: 0.45rem; + background: var(--secondary-color); + overflow: hidden; + } + + .theme-swatch { + display: block; + min-width: 0; + min-height: 0; + } + + .theme-swatch-main { + grid-row: 1 / 3; + } +}