mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-21 18:26:09 +00:00
feat(app): color themes (#30824)
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
This commit is contained in:
co-authored by
LukeParkerDev
parent
75557000de
commit
605ae48c6f
@@ -16,14 +16,8 @@ export const DialogSettings: Component = () => {
|
||||
const platform = usePlatform()
|
||||
|
||||
return (
|
||||
<Dialog size="x-large" class="settings-v2-dialog" data-component="settings-v2-dialog">
|
||||
<TabsV2
|
||||
orientation="vertical"
|
||||
variant="settings"
|
||||
defaultValue="general"
|
||||
class="settings-v2"
|
||||
data-component="settings-v2"
|
||||
>
|
||||
<Dialog size="x-large" variant="settings" class="settings-v2-dialog">
|
||||
<TabsV2 orientation="vertical" variant="settings" defaultValue="general" class="settings-v2">
|
||||
<TabsV2.List>
|
||||
<div class="flex flex-col justify-between h-full w-full">
|
||||
<div class="flex flex-col gap-3 w-full">
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
@import "@opencode-ai/ui/v2/text-input-v2.css";
|
||||
@import "@opencode-ai/ui/v2/button-v2.css";
|
||||
|
||||
[data-component="settings-v2"] {
|
||||
[data-component="tabs-v2"][data-variant="settings"] {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
[data-component="settings-v2-dialog"] [data-slot="dialog-body"] {
|
||||
[data-component="dialog-v2"][data-variant="settings"] [data-slot="dialog-container"] {
|
||||
background: var(--v2-background-bg-base);
|
||||
}
|
||||
|
||||
[data-component="dialog-v2"][data-variant="settings"] [data-slot="dialog-body"] {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -81,10 +85,6 @@
|
||||
box-shadow: inset 0 0 0 0.5px var(--v2-border-border-muted);
|
||||
}
|
||||
|
||||
[data-slot="dialog-container"]:has(.settings-v2-dialog) {
|
||||
box-shadow: var(--v2-elevation-overlay);
|
||||
}
|
||||
|
||||
[data-component="settings-v2-row"] {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -153,12 +153,12 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
[data-component="settings-v2-dialog"] [data-component="select-v2-root"] {
|
||||
[data-component="dialog-v2"][data-variant="settings"] [data-component="select-v2-root"] {
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
[data-component="settings-v2-dialog"] [data-component="button-v2"] {
|
||||
[data-component="dialog-v2"][data-variant="settings"] [data-component="button-v2"] {
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ function HomeDesign() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="rounded-[10px] shadow-[var(--v2-elevation-raised)] m-2 bg-background-base self-stretch flex-1">
|
||||
<div class="rounded-[10px] shadow-[var(--v2-elevation-raised)] m-2 bg-v2-background-bg-base self-stretch flex-1">
|
||||
<div class="mx-auto grid w-full h-full max-w-[1080px] gap-8 px-6 pb-16 lg:grid-cols-[280px_minmax(0,720px)]">
|
||||
<HomeProjectColumn
|
||||
projects={projects()}
|
||||
|
||||
@@ -24,7 +24,7 @@ import { initI18n, t } from "./i18n"
|
||||
import { initializationData, initializationReady } from "./initialization"
|
||||
import { resetZoom, setPinchZoomEnabled, webviewZoom, zoomIn, zoomOut } from "./webview-zoom"
|
||||
import "./styles.css"
|
||||
import { useTheme } from "@opencode-ai/ui/theme"
|
||||
import { useTheme } from "@opencode-ai/ui/theme/context"
|
||||
|
||||
const root = document.getElementById("root")
|
||||
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
"test": "bun test src",
|
||||
"test:ci": "mkdir -p .artifacts/unit && bun test src --reporter=junit --reporter-outfile=.artifacts/unit/junit.xml",
|
||||
"dev": "vite",
|
||||
"generate:tailwind": "bun run script/tailwind.ts"
|
||||
"generate:tailwind": "bun run script/tailwind.ts",
|
||||
"generate:v2-oc2": "bun run script/build-oc2-v2-overrides.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/vite": "catalog:",
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import { V2_PRIMITIVES_DEFAULT } from "../src/theme/v2/default-primitives"
|
||||
import type { DesktopTheme } from "../src/theme/types"
|
||||
|
||||
const themePath = import.meta.dir + "/../src/theme/themes/oc-2.json"
|
||||
const theme = (await Bun.file(themePath).json()) as DesktopTheme
|
||||
const css = await Bun.file(import.meta.dir + "/../src/v2/styles/theme.css").text()
|
||||
|
||||
const light = { ...V2_PRIMITIVES_DEFAULT, ...readTokens("light") }
|
||||
const dark = { ...V2_PRIMITIVES_DEFAULT, ...readTokens("dark") }
|
||||
|
||||
const next: DesktopTheme = {
|
||||
...theme,
|
||||
light: { ...theme.light, v2Overrides: light },
|
||||
dark: { ...theme.dark, v2Overrides: dark },
|
||||
}
|
||||
|
||||
await Bun.write(themePath, JSON.stringify(next, null, 2) + "\n")
|
||||
console.log("Updated oc-2.json v2Overrides", Object.keys(light).length, "tokens per mode")
|
||||
|
||||
function readTokens(mode: "light" | "dark") {
|
||||
const selector = mode === "light" ? ":root" : `\\[data-color-scheme="${mode}"\\]`
|
||||
const block = css.match(new RegExp(`${selector} \\{([\\s\\S]*?)\\n \\}`))?.[1]
|
||||
if (!block) throw new Error(`Missing ${mode} OC-2 tokens`)
|
||||
return Object.fromEntries(
|
||||
[...block.matchAll(/--(v2-[\w-]+):\s*([^;]+);/g)]
|
||||
// Fonts and the fixed avatar foreground remain global CSS rather than theme overrides.
|
||||
.filter(([, key]) => key !== "v2-avatar-fg" && key !== "v2-font-family-sans")
|
||||
.map(([, key, value]) => [key, value!.replace(/\s+/g, " ").trim()]),
|
||||
)
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
// @refresh reload
|
||||
|
||||
import { createEffect, onMount } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||
import { createSimpleContext } from "../context/helper"
|
||||
import oc2ThemeJson from "./themes/oc-2.json"
|
||||
import { resolveThemeVariant, themeToCss } from "./resolve"
|
||||
import { resolveThemeVariantV2, themeV2ToCss } from "./v2/resolve"
|
||||
import type { DesktopTheme } from "./types"
|
||||
|
||||
export type ColorScheme = "light" | "dark" | "system"
|
||||
@@ -132,15 +135,17 @@ function applyThemeCss(theme: DesktopTheme, themeId: string, mode: "light" | "da
|
||||
const variant = isDark ? theme.dark : theme.light
|
||||
const tokens = resolveThemeVariant(variant, isDark)
|
||||
const css = themeToCss(tokens)
|
||||
const v2 = themeV2ToCss(resolveThemeVariantV2(variant, isDark))
|
||||
|
||||
if (themeId !== "oc-2") {
|
||||
write(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, css)
|
||||
write(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, `${css}\n ${v2}`)
|
||||
}
|
||||
|
||||
const fullCss = `:root {
|
||||
color-scheme: ${mode};
|
||||
--text-mix-blend-mode: ${isDark ? "plus-lighter" : "multiply"};
|
||||
${css}
|
||||
${v2}
|
||||
}`
|
||||
|
||||
document.getElementById("oc-theme-preload")?.remove()
|
||||
@@ -160,7 +165,8 @@ function cacheThemeVariants(theme: DesktopTheme, themeId: string) {
|
||||
const variant = isDark ? theme.dark : theme.light
|
||||
const tokens = resolveThemeVariant(variant, isDark)
|
||||
const css = themeToCss(tokens)
|
||||
write(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, css)
|
||||
const v2 = themeV2ToCss(resolveThemeVariantV2(variant, isDark))
|
||||
write(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, `${css}\n ${v2}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -154,6 +154,13 @@
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/ColorValue"
|
||||
}
|
||||
},
|
||||
"v2Overrides": {
|
||||
"type": "object",
|
||||
"description": "Optional direct overrides for any v2 CSS variable (without -- prefix)",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ export type {
|
||||
ResolvedTheme,
|
||||
ColorValue,
|
||||
CssVarRef,
|
||||
V2ColorValue,
|
||||
ResolvedV2Theme,
|
||||
} from "./types"
|
||||
|
||||
export {
|
||||
@@ -30,6 +32,7 @@ export {
|
||||
} from "./color"
|
||||
|
||||
export { resolveThemeVariant, resolveTheme, themeToCss } from "./resolve"
|
||||
export { resolveThemeVariantV2, resolveThemeV2, themeV2ToCss, generateV2Primitives } from "./v2/resolve"
|
||||
export { applyTheme, loadThemeFromUrl, getActiveTheme, removeTheme, setColorScheme } from "./loader"
|
||||
export { ThemeProvider, useTheme, type ColorScheme } from "./context"
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { DesktopTheme, ResolvedTheme } from "./types"
|
||||
import type { DesktopTheme, ResolvedTheme, ResolvedV2Theme } from "./types"
|
||||
import { resolveThemeVariant, themeToCss } from "./resolve"
|
||||
import { resolveThemeVariantV2, themeV2ToCss } from "./v2/resolve"
|
||||
|
||||
let activeTheme: DesktopTheme | null = null
|
||||
const THEME_STYLE_ID = "opencode-theme"
|
||||
@@ -19,17 +20,25 @@ export function applyTheme(theme: DesktopTheme, themeId?: string): void {
|
||||
activeTheme = theme
|
||||
const lightTokens = resolveThemeVariant(theme.light, false)
|
||||
const darkTokens = resolveThemeVariant(theme.dark, true)
|
||||
const lightV2Tokens = resolveThemeVariantV2(theme.light, false)
|
||||
const darkV2Tokens = resolveThemeVariantV2(theme.dark, true)
|
||||
const targetThemeId = themeId ?? theme.id
|
||||
const css = buildThemeCss(lightTokens, darkTokens, targetThemeId)
|
||||
const css = buildThemeCss(lightTokens, darkTokens, lightV2Tokens, darkV2Tokens, targetThemeId)
|
||||
const themeStyleElement = ensureLoaderStyleElement()
|
||||
themeStyleElement.textContent = css
|
||||
document.documentElement.setAttribute("data-theme", targetThemeId)
|
||||
}
|
||||
|
||||
function buildThemeCss(light: ResolvedTheme, dark: ResolvedTheme, themeId: string): string {
|
||||
function buildThemeCss(
|
||||
light: ResolvedTheme,
|
||||
dark: ResolvedTheme,
|
||||
lightV2: ResolvedV2Theme,
|
||||
darkV2: ResolvedV2Theme,
|
||||
themeId: string,
|
||||
): string {
|
||||
const isDefaultTheme = themeId === "oc-2"
|
||||
const lightCss = themeToCss(light)
|
||||
const darkCss = themeToCss(dark)
|
||||
const lightCss = `${themeToCss(light)}\n ${themeV2ToCss(lightV2)}`
|
||||
const darkCss = `${themeToCss(dark)}\n ${themeV2ToCss(darkV2)}`
|
||||
|
||||
if (isDefaultTheme) {
|
||||
return `
|
||||
|
||||
@@ -43,6 +43,17 @@
|
||||
"markdown-image": "#30b3ff",
|
||||
"markdown-image-text": "#24f6d9",
|
||||
"markdown-code-block": "#203022"
|
||||
},
|
||||
"v2Overrides": {
|
||||
"v2-text-text-base": "#353535",
|
||||
"v2-text-text-muted": "#748476",
|
||||
"v2-text-text-faint": "#748476",
|
||||
"v2-background-bg-accent": "var(--v2-green-600)",
|
||||
"v2-text-text-accent": "var(--v2-green-600)",
|
||||
"v2-text-text-accent-hover": "var(--v2-green-700)",
|
||||
"v2-icon-icon-accent": "var(--v2-green-600)",
|
||||
"v2-icon-icon-accent-hover": "var(--v2-green-700)",
|
||||
"v2-border-border-focus": "var(--v2-green-500)"
|
||||
}
|
||||
},
|
||||
"dark": {
|
||||
@@ -86,6 +97,17 @@
|
||||
"markdown-image": "#30b3ff",
|
||||
"markdown-image-text": "#24f6d9",
|
||||
"markdown-code-block": "#62ff94"
|
||||
},
|
||||
"v2Overrides": {
|
||||
"v2-text-text-base": "#ececec",
|
||||
"v2-text-text-muted": "#8ca391",
|
||||
"v2-text-text-faint": "#8ca391",
|
||||
"v2-background-bg-accent": "var(--v2-green-600)",
|
||||
"v2-text-text-accent": "var(--v2-green-400)",
|
||||
"v2-text-text-accent-hover": "var(--v2-green-300)",
|
||||
"v2-icon-icon-accent": "var(--v2-green-400)",
|
||||
"v2-icon-icon-accent-hover": "var(--v2-green-300)",
|
||||
"v2-border-border-focus": "var(--v2-green-500)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,194 @@
|
||||
"syntax-diff-delete": "#ff8c00",
|
||||
"syntax-diff-unknown": "#a753ae",
|
||||
"surface-critical-base": "#FFF2F0"
|
||||
},
|
||||
"v2Overrides": {
|
||||
"v2-grey-100": "#ffffffff",
|
||||
"v2-grey-200": "#fafafaff",
|
||||
"v2-grey-300": "#eeeeeeff",
|
||||
"v2-grey-400": "#d4d4d4ff",
|
||||
"v2-grey-500": "#aeaeaeff",
|
||||
"v2-grey-600": "#808080ff",
|
||||
"v2-grey-700": "#5c5c5cff",
|
||||
"v2-grey-800": "#3a3a3aff",
|
||||
"v2-grey-900": "#242424ff",
|
||||
"v2-grey-1000": "#161616ff",
|
||||
"v2-grey-1100": "#080808ff",
|
||||
"v2-grey-1200": "#000000ff",
|
||||
"v2-red-100": "#fcecebff",
|
||||
"v2-red-200": "#f6d5d3ff",
|
||||
"v2-red-300": "#f2bbb7ff",
|
||||
"v2-red-400": "#f29b96ff",
|
||||
"v2-red-500": "#f17471ff",
|
||||
"v2-red-600": "#f1484fff",
|
||||
"v2-red-700": "#d92e3cff",
|
||||
"v2-red-800": "#b82d35ff",
|
||||
"v2-red-900": "#97252bff",
|
||||
"v2-red-1000": "#7a1f23ff",
|
||||
"v2-red-1100": "#5f1a1cff",
|
||||
"v2-red-1200": "#461516ff",
|
||||
"v2-orange-100": "#fdf2edff",
|
||||
"v2-orange-200": "#ffe7dcff",
|
||||
"v2-orange-300": "#ffd8c6ff",
|
||||
"v2-orange-400": "#ffc1a4ff",
|
||||
"v2-orange-500": "#ffa478ff",
|
||||
"v2-orange-600": "#ff8648ff",
|
||||
"v2-orange-700": "#ee7330ff",
|
||||
"v2-orange-800": "#d16427ff",
|
||||
"v2-orange-900": "#b35624ff",
|
||||
"v2-orange-1000": "#954c27ff",
|
||||
"v2-orange-1100": "#723d22ff",
|
||||
"v2-orange-1200": "#5a2c14ff",
|
||||
"v2-yellow-100": "#fefaecff",
|
||||
"v2-yellow-200": "#fcefd0ff",
|
||||
"v2-yellow-300": "#f7e5b5ff",
|
||||
"v2-yellow-400": "#f3da9bff",
|
||||
"v2-yellow-500": "#f2cf76ff",
|
||||
"v2-yellow-600": "#f6c251ff",
|
||||
"v2-yellow-700": "#e7af36ff",
|
||||
"v2-yellow-800": "#cb9f34ff",
|
||||
"v2-yellow-900": "#ac8833ff",
|
||||
"v2-yellow-1000": "#8e7231ff",
|
||||
"v2-yellow-1100": "#68552bff",
|
||||
"v2-yellow-1200": "#4b4025ff",
|
||||
"v2-green-100": "#e7f9eaff",
|
||||
"v2-green-200": "#d0f0d5ff",
|
||||
"v2-green-300": "#b8e9c1ff",
|
||||
"v2-green-400": "#96e3a6ff",
|
||||
"v2-green-500": "#6bd586ff",
|
||||
"v2-green-600": "#49c970ff",
|
||||
"v2-green-700": "#2eaf5aff",
|
||||
"v2-green-800": "#198b43ff",
|
||||
"v2-green-900": "#1d783cff",
|
||||
"v2-green-1000": "#196130ff",
|
||||
"v2-green-1100": "#164c26ff",
|
||||
"v2-green-1200": "#14361dff",
|
||||
"v2-cyan-100": "#e2f7fbff",
|
||||
"v2-cyan-200": "#c4edf4ff",
|
||||
"v2-cyan-300": "#a3e4efff",
|
||||
"v2-cyan-400": "#65d9ebff",
|
||||
"v2-cyan-500": "#00c5dfff",
|
||||
"v2-cyan-600": "#00abcfff",
|
||||
"v2-cyan-700": "#0096b8ff",
|
||||
"v2-cyan-800": "#007d9bff",
|
||||
"v2-cyan-900": "#006c85ff",
|
||||
"v2-cyan-1000": "#005a6eff",
|
||||
"v2-cyan-1100": "#004756ff",
|
||||
"v2-cyan-1200": "#00353fff",
|
||||
"v2-blue-100": "#ecf1feff",
|
||||
"v2-blue-200": "#d7e2fcff",
|
||||
"v2-blue-300": "#c3d4fdff",
|
||||
"v2-blue-400": "#a2bcffff",
|
||||
"v2-blue-500": "#7698fdff",
|
||||
"v2-blue-600": "#3b5cf6ff",
|
||||
"v2-blue-700": "#3250dfff",
|
||||
"v2-blue-800": "#2c47c8ff",
|
||||
"v2-blue-900": "#263fa9ff",
|
||||
"v2-blue-1000": "#22388fff",
|
||||
"v2-blue-1100": "#1c2e70ff",
|
||||
"v2-blue-1200": "#1b2852ff",
|
||||
"v2-purple-100": "#ebecfeff",
|
||||
"v2-purple-200": "#d5d5fcff",
|
||||
"v2-purple-300": "#b9b8f5ff",
|
||||
"v2-purple-400": "#9e99f7ff",
|
||||
"v2-purple-500": "#8271f8ff",
|
||||
"v2-purple-600": "#7152f4ff",
|
||||
"v2-purple-700": "#623be2ff",
|
||||
"v2-purple-800": "#5230c2ff",
|
||||
"v2-purple-900": "#442aa1ff",
|
||||
"v2-purple-1000": "#361f83ff",
|
||||
"v2-purple-1100": "#2b1b6aff",
|
||||
"v2-purple-1200": "#221358ff",
|
||||
"v2-pink-100": "#fdecf3ff",
|
||||
"v2-pink-200": "#f7d5e4ff",
|
||||
"v2-pink-300": "#fabcd8ff",
|
||||
"v2-pink-400": "#f799c6ff",
|
||||
"v2-pink-500": "#f26cb2ff",
|
||||
"v2-pink-600": "#f64aabff",
|
||||
"v2-pink-700": "#e4429eff",
|
||||
"v2-pink-800": "#c83d8bff",
|
||||
"v2-pink-900": "#aa3576ff",
|
||||
"v2-pink-1000": "#8c2d61ff",
|
||||
"v2-pink-1100": "#6f284fff",
|
||||
"v2-pink-1200": "#5c1d3fff",
|
||||
"v2-background-bg-base": "var(--v2-grey-100)",
|
||||
"v2-background-bg-deep": "var(--v2-grey-200)",
|
||||
"v2-background-bg-layer-01": "var(--v2-grey-200)",
|
||||
"v2-background-bg-layer-02": "var(--v2-grey-300)",
|
||||
"v2-background-bg-layer-03": "var(--v2-grey-400)",
|
||||
"v2-background-bg-inverse": "var(--v2-grey-1000)",
|
||||
"v2-background-bg-contrast": "var(--v2-grey-900)",
|
||||
"v2-background-bg-button-neutral": "var(--v2-grey-100)",
|
||||
"v2-background-bg-accent": "var(--v2-blue-600)",
|
||||
"v2-text-text-base": "var(--v2-grey-1000)",
|
||||
"v2-text-text-muted": "var(--v2-grey-700)",
|
||||
"v2-text-text-faint": "var(--v2-grey-600)",
|
||||
"v2-text-text-inverse": "var(--v2-grey-100)",
|
||||
"v2-text-text-contrast": "var(--v2-grey-100)",
|
||||
"v2-text-text-accent": "var(--v2-blue-600)",
|
||||
"v2-text-text-accent-hover": "var(--v2-blue-700)",
|
||||
"v2-icon-icon-base": "var(--v2-grey-800)",
|
||||
"v2-icon-icon-muted": "var(--v2-grey-600)",
|
||||
"v2-icon-icon-inverse": "var(--v2-grey-100)",
|
||||
"v2-icon-icon-contrast": "var(--v2-grey-200)",
|
||||
"v2-icon-icon-accent": "var(--v2-blue-600)",
|
||||
"v2-icon-icon-accent-hover": "var(--v2-blue-700)",
|
||||
"v2-border-border-muted": "var(--v2-alpha-dark-8)",
|
||||
"v2-border-border-base": "var(--v2-alpha-dark-10)",
|
||||
"v2-border-border-strong": "var(--v2-alpha-dark-20)",
|
||||
"v2-border-border-inverse": "var(--v2-grey-1000)",
|
||||
"v2-border-border-focus": "var(--v2-blue-500)",
|
||||
"v2-overlay-simple-overlay-hover": "var(--v2-alpha-dark-4)",
|
||||
"v2-overlay-simple-overlay-pressed": "var(--v2-alpha-dark-8)",
|
||||
"v2-overlay-simple-overlay-contrast-hover": "var(--v2-alpha-light-12)",
|
||||
"v2-overlay-simple-overlay-contrast-pressed": "var(--v2-alpha-light-24)",
|
||||
"v2-overlay-simple-overlay-scrim": "var(--v2-alpha-dark-40)",
|
||||
"v2-overlay-gradient-depth-overlay-depth-top": "var(--v2-alpha-light-100)",
|
||||
"v2-overlay-gradient-depth-overlay-depth-bot": "var(--v2-alpha-light-0)",
|
||||
"v2-overlay-simple-tab-active-scrim": "#fafafa00",
|
||||
"v2-overlay-simple-tab-hover-scrim": "#eeeeee00",
|
||||
"v2-overlay-simple-tab-scrim": "#fafafa00",
|
||||
"v2-state-bg-success": "var(--v2-green-100)",
|
||||
"v2-state-fg-success": "var(--v2-green-800)",
|
||||
"v2-state-border-success": "var(--v2-green-300)",
|
||||
"v2-state-bg-warning": "var(--v2-yellow-100)",
|
||||
"v2-state-fg-warning": "var(--v2-yellow-800)",
|
||||
"v2-state-border-warning": "var(--v2-yellow-300)",
|
||||
"v2-state-bg-danger": "var(--v2-red-100)",
|
||||
"v2-state-fg-danger": "var(--v2-red-800)",
|
||||
"v2-state-border-danger": "var(--v2-red-300)",
|
||||
"v2-state-bg-info": "var(--v2-blue-100)",
|
||||
"v2-state-fg-info": "var(--v2-blue-800)",
|
||||
"v2-state-border-info": "var(--v2-blue-300)",
|
||||
"v2-avatar-bg-orange": "#ee7330ff",
|
||||
"v2-avatar-border-orange": "#d16427ff",
|
||||
"v2-avatar-bg-yellow": "#e7af36ff",
|
||||
"v2-avatar-border-yellow": "#cb9f34ff",
|
||||
"v2-avatar-bg-cyan": "#0096b8ff",
|
||||
"v2-avatar-border-cyan": "#007d9bff",
|
||||
"v2-avatar-bg-green": "#2eaf5aff",
|
||||
"v2-avatar-border-green": "#198b43ff",
|
||||
"v2-avatar-bg-red": "#d92e3cff",
|
||||
"v2-avatar-border-red": "#b82d35ff",
|
||||
"v2-avatar-bg-pink": "#e4429eff",
|
||||
"v2-avatar-border-pink": "#c83d8bff",
|
||||
"v2-avatar-bg-blue": "#3250dfff",
|
||||
"v2-avatar-border-blue": "#2c47c8ff",
|
||||
"v2-avatar-bg-purple": "#623be2ff",
|
||||
"v2-avatar-border-purple": "#5230c2ff",
|
||||
"v2-avatar-bg-gray": "#5c5c5cff",
|
||||
"v2-avatar-border-gray": "#3a3a3aff",
|
||||
"v2-elevation-raised": "0px 2px 4px 0px var(--v2-alpha-dark-4), 0px 1px 2px -1px var(--v2-alpha-dark-8), 0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-floating": "0px 8px 16px 0px var(--v2-alpha-dark-4), 0px 4px 8px 0px var(--v2-alpha-dark-8), 0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-overlay": "0px 16px 32px 0px var(--v2-alpha-dark-4), 0px 8px 16px 0px var(--v2-alpha-dark-8), 0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-button-neutral": "0px 1px 1.5px 0px var(--v2-alpha-dark-10), 0px 0px 0px 0.5px var(--v2-alpha-dark-14), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-button-contrast": "0px 1px 1.5px 0px var(--v2-alpha-dark-20), 0px 0px 0px 0.5px var(--v2-grey-800), inset 0px 1px 2px 0px var(--v2-alpha-light-14), inset 0px -1px 2px 0px var(--v2-alpha-dark-6), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-elements": "0px 0.5px 0.5px 0px var(--v2-alpha-dark-40)",
|
||||
"v2-elevation-switch-off": "inset 0px 1px 1px 0px var(--v2-alpha-dark-8), inset 0px 0.5px 0.5px 0px var(--v2-alpha-dark-8), inset 0px 0px 0px 0.5px var(--v2-alpha-dark-10)",
|
||||
"v2-elevation-switch-on": "inset 0px 2px 2px 0px var(--v2-alpha-dark-10), inset 0px 1px 1px 0px var(--v2-alpha-dark-10), inset 0px 0px 0px 0.5px var(--v2-alpha-dark-20)",
|
||||
"v2-illustration-illustration-layer-01": "var(--v2-grey-300)",
|
||||
"v2-illustration-illustration-layer-02": "var(--v2-grey-400)",
|
||||
"v2-illustration-illustration-layer-03": "var(--v2-grey-500)"
|
||||
}
|
||||
},
|
||||
"dark": {
|
||||
@@ -83,6 +271,194 @@
|
||||
"syntax-diff-delete": "#fab283",
|
||||
"syntax-diff-unknown": "#edb2f1",
|
||||
"surface-critical-base": "#1F0603"
|
||||
},
|
||||
"v2Overrides": {
|
||||
"v2-grey-100": "#ffffffff",
|
||||
"v2-grey-200": "#fafafaff",
|
||||
"v2-grey-300": "#eeeeeeff",
|
||||
"v2-grey-400": "#d4d4d4ff",
|
||||
"v2-grey-500": "#aeaeaeff",
|
||||
"v2-grey-600": "#808080ff",
|
||||
"v2-grey-700": "#5c5c5cff",
|
||||
"v2-grey-800": "#3a3a3aff",
|
||||
"v2-grey-900": "#242424ff",
|
||||
"v2-grey-1000": "#161616ff",
|
||||
"v2-grey-1100": "#080808ff",
|
||||
"v2-grey-1200": "#000000ff",
|
||||
"v2-red-100": "#fcecebff",
|
||||
"v2-red-200": "#f6d5d3ff",
|
||||
"v2-red-300": "#f2bbb7ff",
|
||||
"v2-red-400": "#f29b96ff",
|
||||
"v2-red-500": "#f17471ff",
|
||||
"v2-red-600": "#f1484fff",
|
||||
"v2-red-700": "#d92e3cff",
|
||||
"v2-red-800": "#b82d35ff",
|
||||
"v2-red-900": "#97252bff",
|
||||
"v2-red-1000": "#7a1f23ff",
|
||||
"v2-red-1100": "#5f1a1cff",
|
||||
"v2-red-1200": "#461516ff",
|
||||
"v2-orange-100": "#fdf2edff",
|
||||
"v2-orange-200": "#ffe7dcff",
|
||||
"v2-orange-300": "#ffd8c6ff",
|
||||
"v2-orange-400": "#ffc1a4ff",
|
||||
"v2-orange-500": "#ffa478ff",
|
||||
"v2-orange-600": "#ff8648ff",
|
||||
"v2-orange-700": "#ee7330ff",
|
||||
"v2-orange-800": "#d16427ff",
|
||||
"v2-orange-900": "#b35624ff",
|
||||
"v2-orange-1000": "#954c27ff",
|
||||
"v2-orange-1100": "#723d22ff",
|
||||
"v2-orange-1200": "#5a2c14ff",
|
||||
"v2-yellow-100": "#fefaecff",
|
||||
"v2-yellow-200": "#fcefd0ff",
|
||||
"v2-yellow-300": "#f7e5b5ff",
|
||||
"v2-yellow-400": "#f3da9bff",
|
||||
"v2-yellow-500": "#f2cf76ff",
|
||||
"v2-yellow-600": "#f6c251ff",
|
||||
"v2-yellow-700": "#e7af36ff",
|
||||
"v2-yellow-800": "#cb9f34ff",
|
||||
"v2-yellow-900": "#ac8833ff",
|
||||
"v2-yellow-1000": "#8e7231ff",
|
||||
"v2-yellow-1100": "#68552bff",
|
||||
"v2-yellow-1200": "#4b4025ff",
|
||||
"v2-green-100": "#e7f9eaff",
|
||||
"v2-green-200": "#d0f0d5ff",
|
||||
"v2-green-300": "#b8e9c1ff",
|
||||
"v2-green-400": "#96e3a6ff",
|
||||
"v2-green-500": "#6bd586ff",
|
||||
"v2-green-600": "#49c970ff",
|
||||
"v2-green-700": "#2eaf5aff",
|
||||
"v2-green-800": "#198b43ff",
|
||||
"v2-green-900": "#1d783cff",
|
||||
"v2-green-1000": "#196130ff",
|
||||
"v2-green-1100": "#164c26ff",
|
||||
"v2-green-1200": "#14361dff",
|
||||
"v2-cyan-100": "#e2f7fbff",
|
||||
"v2-cyan-200": "#c4edf4ff",
|
||||
"v2-cyan-300": "#a3e4efff",
|
||||
"v2-cyan-400": "#65d9ebff",
|
||||
"v2-cyan-500": "#00c5dfff",
|
||||
"v2-cyan-600": "#00abcfff",
|
||||
"v2-cyan-700": "#0096b8ff",
|
||||
"v2-cyan-800": "#007d9bff",
|
||||
"v2-cyan-900": "#006c85ff",
|
||||
"v2-cyan-1000": "#005a6eff",
|
||||
"v2-cyan-1100": "#004756ff",
|
||||
"v2-cyan-1200": "#00353fff",
|
||||
"v2-blue-100": "#ecf1feff",
|
||||
"v2-blue-200": "#d7e2fcff",
|
||||
"v2-blue-300": "#c3d4fdff",
|
||||
"v2-blue-400": "#a2bcffff",
|
||||
"v2-blue-500": "#7698fdff",
|
||||
"v2-blue-600": "#3b5cf6ff",
|
||||
"v2-blue-700": "#3250dfff",
|
||||
"v2-blue-800": "#2c47c8ff",
|
||||
"v2-blue-900": "#263fa9ff",
|
||||
"v2-blue-1000": "#22388fff",
|
||||
"v2-blue-1100": "#1c2e70ff",
|
||||
"v2-blue-1200": "#1b2852ff",
|
||||
"v2-purple-100": "#ebecfeff",
|
||||
"v2-purple-200": "#d5d5fcff",
|
||||
"v2-purple-300": "#b9b8f5ff",
|
||||
"v2-purple-400": "#9e99f7ff",
|
||||
"v2-purple-500": "#8271f8ff",
|
||||
"v2-purple-600": "#7152f4ff",
|
||||
"v2-purple-700": "#623be2ff",
|
||||
"v2-purple-800": "#5230c2ff",
|
||||
"v2-purple-900": "#442aa1ff",
|
||||
"v2-purple-1000": "#361f83ff",
|
||||
"v2-purple-1100": "#2b1b6aff",
|
||||
"v2-purple-1200": "#221358ff",
|
||||
"v2-pink-100": "#fdecf3ff",
|
||||
"v2-pink-200": "#f7d5e4ff",
|
||||
"v2-pink-300": "#fabcd8ff",
|
||||
"v2-pink-400": "#f799c6ff",
|
||||
"v2-pink-500": "#f26cb2ff",
|
||||
"v2-pink-600": "#f64aabff",
|
||||
"v2-pink-700": "#e4429eff",
|
||||
"v2-pink-800": "#c83d8bff",
|
||||
"v2-pink-900": "#aa3576ff",
|
||||
"v2-pink-1000": "#8c2d61ff",
|
||||
"v2-pink-1100": "#6f284fff",
|
||||
"v2-pink-1200": "#5c1d3fff",
|
||||
"v2-background-bg-base": "var(--v2-grey-1000)",
|
||||
"v2-background-bg-deep": "var(--v2-grey-1100)",
|
||||
"v2-background-bg-layer-01": "var(--v2-grey-900)",
|
||||
"v2-background-bg-layer-02": "var(--v2-grey-800)",
|
||||
"v2-background-bg-layer-03": "var(--v2-grey-700)",
|
||||
"v2-background-bg-inverse": "var(--v2-grey-100)",
|
||||
"v2-background-bg-contrast": "var(--v2-grey-700)",
|
||||
"v2-background-bg-button-neutral": "var(--v2-alpha-light-6)",
|
||||
"v2-background-bg-accent": "var(--v2-blue-600)",
|
||||
"v2-text-text-base": "var(--v2-grey-200)",
|
||||
"v2-text-text-muted": "var(--v2-grey-500)",
|
||||
"v2-text-text-faint": "var(--v2-grey-600)",
|
||||
"v2-text-text-inverse": "var(--v2-grey-1000)",
|
||||
"v2-text-text-contrast": "var(--v2-grey-100)",
|
||||
"v2-text-text-accent": "var(--v2-blue-400)",
|
||||
"v2-text-text-accent-hover": "var(--v2-blue-300)",
|
||||
"v2-icon-icon-base": "var(--v2-grey-400)",
|
||||
"v2-icon-icon-muted": "var(--v2-grey-600)",
|
||||
"v2-icon-icon-inverse": "var(--v2-grey-1000)",
|
||||
"v2-icon-icon-contrast": "var(--v2-grey-200)",
|
||||
"v2-icon-icon-accent": "var(--v2-blue-400)",
|
||||
"v2-icon-icon-accent-hover": "var(--v2-blue-300)",
|
||||
"v2-border-border-muted": "var(--v2-alpha-light-8)",
|
||||
"v2-border-border-base": "var(--v2-alpha-light-10)",
|
||||
"v2-border-border-strong": "var(--v2-alpha-light-20)",
|
||||
"v2-border-border-inverse": "var(--v2-grey-100)",
|
||||
"v2-border-border-focus": "var(--v2-blue-500)",
|
||||
"v2-overlay-simple-overlay-hover": "var(--v2-alpha-light-6)",
|
||||
"v2-overlay-simple-overlay-pressed": "var(--v2-alpha-light-10)",
|
||||
"v2-overlay-simple-overlay-contrast-hover": "var(--v2-alpha-dark-24)",
|
||||
"v2-overlay-simple-overlay-contrast-pressed": "var(--v2-alpha-dark-40)",
|
||||
"v2-overlay-simple-overlay-scrim": "var(--v2-alpha-light-30)",
|
||||
"v2-overlay-gradient-depth-overlay-depth-top": "var(--v2-alpha-light-100)",
|
||||
"v2-overlay-gradient-depth-overlay-depth-bot": "var(--v2-alpha-light-0)",
|
||||
"v2-overlay-simple-tab-active-scrim": "#24242400",
|
||||
"v2-overlay-simple-tab-hover-scrim": "#3a3a3a00",
|
||||
"v2-overlay-simple-tab-scrim": "#08080800",
|
||||
"v2-state-bg-success": "var(--v2-green-1200)",
|
||||
"v2-state-fg-success": "var(--v2-green-500)",
|
||||
"v2-state-border-success": "var(--v2-green-900)",
|
||||
"v2-state-bg-warning": "var(--v2-yellow-1200)",
|
||||
"v2-state-fg-warning": "var(--v2-yellow-500)",
|
||||
"v2-state-border-warning": "var(--v2-yellow-900)",
|
||||
"v2-state-bg-danger": "var(--v2-red-1200)",
|
||||
"v2-state-fg-danger": "var(--v2-red-500)",
|
||||
"v2-state-border-danger": "var(--v2-red-900)",
|
||||
"v2-state-bg-info": "var(--v2-blue-1200)",
|
||||
"v2-state-fg-info": "var(--v2-blue-500)",
|
||||
"v2-state-border-info": "var(--v2-blue-900)",
|
||||
"v2-avatar-bg-orange": "#723d22ff",
|
||||
"v2-avatar-border-orange": "#ff8648ff",
|
||||
"v2-avatar-bg-yellow": "#68552bff",
|
||||
"v2-avatar-border-yellow": "#e7af36ff",
|
||||
"v2-avatar-bg-cyan": "#005a6eff",
|
||||
"v2-avatar-border-cyan": "#0096b8ff",
|
||||
"v2-avatar-bg-green": "#196130ff",
|
||||
"v2-avatar-border-green": "#49c970ff",
|
||||
"v2-avatar-bg-red": "#7a1f23ff",
|
||||
"v2-avatar-border-red": "#d92e3cff",
|
||||
"v2-avatar-bg-pink": "#8c2d61ff",
|
||||
"v2-avatar-border-pink": "#e4429eff",
|
||||
"v2-avatar-bg-blue": "#263fa9ff",
|
||||
"v2-avatar-border-blue": "#7698fdff",
|
||||
"v2-avatar-bg-purple": "#361f83ff",
|
||||
"v2-avatar-border-purple": "#7152f4ff",
|
||||
"v2-avatar-bg-gray": "#5c5c5cff",
|
||||
"v2-avatar-border-gray": "#aeaeaeff",
|
||||
"v2-elevation-raised": "0px 2px 4px 0px var(--v2-alpha-dark-30), 0px 1px 2px 0px var(--v2-alpha-dark-30), 0px 0px 0px 0.5px var(--v2-alpha-light-16), 0px -0.5px 0px 0px var(--v2-alpha-light-6)",
|
||||
"v2-elevation-floating": "0px 8px 16px 0px var(--v2-alpha-dark-30), 0px 4px 8px 0px var(--v2-alpha-dark-30), 0px 0px 0px 0.5px var(--v2-alpha-light-16), 0px -0.5px 0px 0px var(--v2-alpha-light-6)",
|
||||
"v2-elevation-overlay": "0px 16px 32px 0px var(--v2-alpha-dark-30), 0px 8px 16px 0px var(--v2-alpha-dark-30), 0px 0px 0px 0.5px var(--v2-alpha-light-16), 0px -0.5px 0px 0px var(--v2-alpha-light-6)",
|
||||
"v2-elevation-button-neutral": "0px 1px 2px 0px var(--v2-alpha-dark-40), 0px 0px 0px 0.5px var(--v2-alpha-light-20), 0px -0.5px 0px 0px var(--v2-alpha-light-10)",
|
||||
"v2-elevation-button-contrast": "0px 1px 2px 0px var(--v2-alpha-dark-40), 0px 0px 0px 0.5px var(--v2-alpha-light-40), inset 0px 0px 0px 0px var(--v2-alpha-light-0), inset 0px 0px 0px 0px var(--v2-alpha-light-0), 0px -0.5px 0px 0px var(--v2-alpha-light-30)",
|
||||
"v2-elevation-elements": "0px 0.5px 0.5px 0px var(--v2-alpha-dark-40)",
|
||||
"v2-elevation-switch-off": "inset 0px -0.5px 0px 0px var(--v2-alpha-light-10), inset 0px 0px 0px 0px var(--v2-alpha-light-0), inset 0px 0px 0px 0.5px var(--v2-alpha-light-16)",
|
||||
"v2-elevation-switch-on": "inset 0px -0.5px 0px 0px var(--v2-alpha-light-10), inset 0px 0px 0px 0px var(--v2-alpha-light-0), inset 0px 0px 0px 0.5px var(--v2-alpha-light-16)",
|
||||
"v2-illustration-illustration-layer-01": "var(--v2-grey-900)",
|
||||
"v2-illustration-illustration-layer-02": "var(--v2-grey-800)",
|
||||
"v2-illustration-illustration-layer-03": "var(--v2-grey-700)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ export interface ThemePaletteColors {
|
||||
|
||||
type ThemeVariantBase = {
|
||||
overrides?: Record<string, ColorValue>
|
||||
v2Overrides?: Record<string, V2ColorValue>
|
||||
}
|
||||
|
||||
export type ThemeVariant =
|
||||
@@ -67,4 +68,8 @@ export type CssVarRef = `var(--${string})`
|
||||
|
||||
export type ColorValue = HexColor | CssVarRef
|
||||
|
||||
export type V2ColorValue = HexColor | CssVarRef | string
|
||||
|
||||
export type ResolvedTheme = Record<ThemeToken, ColorValue>
|
||||
|
||||
export type ResolvedV2Theme = Record<string, V2ColorValue>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { V2ColorValue } from "../types"
|
||||
|
||||
/** Fixed project avatar colors (OC-2); theme-independent like v1 `avatar-background-*`. */
|
||||
export const V2_AVATAR_FG = "#ffffffff"
|
||||
|
||||
export const V2_AVATAR_LIGHT: Record<string, V2ColorValue> = {
|
||||
"v2-avatar-fg": V2_AVATAR_FG,
|
||||
"v2-avatar-bg-orange": "#ee7330ff",
|
||||
"v2-avatar-border-orange": "#d16427ff",
|
||||
"v2-avatar-bg-yellow": "#e7af36ff",
|
||||
"v2-avatar-border-yellow": "#cb9f34ff",
|
||||
"v2-avatar-bg-cyan": "#0096b8ff",
|
||||
"v2-avatar-border-cyan": "#007d9bff",
|
||||
"v2-avatar-bg-green": "#2eaf5aff",
|
||||
"v2-avatar-border-green": "#198b43ff",
|
||||
"v2-avatar-bg-red": "#d92e3cff",
|
||||
"v2-avatar-border-red": "#b82d35ff",
|
||||
"v2-avatar-bg-pink": "#e4429eff",
|
||||
"v2-avatar-border-pink": "#c83d8bff",
|
||||
"v2-avatar-bg-blue": "#3250dfff",
|
||||
"v2-avatar-border-blue": "#2c47c8ff",
|
||||
"v2-avatar-bg-purple": "#623be2ff",
|
||||
"v2-avatar-border-purple": "#5230c2ff",
|
||||
"v2-avatar-bg-gray": "#5c5c5cff",
|
||||
"v2-avatar-border-gray": "#3a3a3aff",
|
||||
}
|
||||
|
||||
export const V2_AVATAR_DARK: Record<string, V2ColorValue> = {
|
||||
"v2-avatar-fg": V2_AVATAR_FG,
|
||||
"v2-avatar-bg-orange": "#723d22ff",
|
||||
"v2-avatar-border-orange": "#ff8648ff",
|
||||
"v2-avatar-bg-yellow": "#68552bff",
|
||||
"v2-avatar-border-yellow": "#e7af36ff",
|
||||
"v2-avatar-bg-cyan": "#005a6eff",
|
||||
"v2-avatar-border-cyan": "#0096b8ff",
|
||||
"v2-avatar-bg-green": "#196130ff",
|
||||
"v2-avatar-border-green": "#49c970ff",
|
||||
"v2-avatar-bg-red": "#7a1f23ff",
|
||||
"v2-avatar-border-red": "#d92e3cff",
|
||||
"v2-avatar-bg-pink": "#8c2d61ff",
|
||||
"v2-avatar-border-pink": "#e4429eff",
|
||||
"v2-avatar-bg-blue": "#263fa9ff",
|
||||
"v2-avatar-border-blue": "#7698fdff",
|
||||
"v2-avatar-bg-purple": "#361f83ff",
|
||||
"v2-avatar-border-purple": "#7152f4ff",
|
||||
"v2-avatar-bg-gray": "#5c5c5cff",
|
||||
"v2-avatar-border-gray": "#aeaeaeff",
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import type { V2ColorValue } from "../types"
|
||||
|
||||
/** Default v2 hue ramps from `v2/styles/colors.css` (OC-2). Alpha ramps live in CSS only. */
|
||||
export const V2_PRIMITIVES_DEFAULT: Record<string, V2ColorValue> = {
|
||||
"v2-grey-100": "#ffffffff",
|
||||
"v2-grey-200": "#fafafaff",
|
||||
"v2-grey-300": "#eeeeeeff",
|
||||
"v2-grey-400": "#d4d4d4ff",
|
||||
"v2-grey-500": "#aeaeaeff",
|
||||
"v2-grey-600": "#808080ff",
|
||||
"v2-grey-700": "#5c5c5cff",
|
||||
"v2-grey-800": "#3a3a3aff",
|
||||
"v2-grey-900": "#242424ff",
|
||||
"v2-grey-1000": "#161616ff",
|
||||
"v2-grey-1100": "#080808ff",
|
||||
"v2-grey-1200": "#000000ff",
|
||||
"v2-red-100": "#fcecebff",
|
||||
"v2-red-200": "#f6d5d3ff",
|
||||
"v2-red-300": "#f2bbb7ff",
|
||||
"v2-red-400": "#f29b96ff",
|
||||
"v2-red-500": "#f17471ff",
|
||||
"v2-red-600": "#f1484fff",
|
||||
"v2-red-700": "#d92e3cff",
|
||||
"v2-red-800": "#b82d35ff",
|
||||
"v2-red-900": "#97252bff",
|
||||
"v2-red-1000": "#7a1f23ff",
|
||||
"v2-red-1100": "#5f1a1cff",
|
||||
"v2-red-1200": "#461516ff",
|
||||
"v2-orange-100": "#fdf2edff",
|
||||
"v2-orange-200": "#ffe7dcff",
|
||||
"v2-orange-300": "#ffd8c6ff",
|
||||
"v2-orange-400": "#ffc1a4ff",
|
||||
"v2-orange-500": "#ffa478ff",
|
||||
"v2-orange-600": "#ff8648ff",
|
||||
"v2-orange-700": "#ee7330ff",
|
||||
"v2-orange-800": "#d16427ff",
|
||||
"v2-orange-900": "#b35624ff",
|
||||
"v2-orange-1000": "#954c27ff",
|
||||
"v2-orange-1100": "#723d22ff",
|
||||
"v2-orange-1200": "#5a2c14ff",
|
||||
"v2-yellow-100": "#fefaecff",
|
||||
"v2-yellow-200": "#fcefd0ff",
|
||||
"v2-yellow-300": "#f7e5b5ff",
|
||||
"v2-yellow-400": "#f3da9bff",
|
||||
"v2-yellow-500": "#f2cf76ff",
|
||||
"v2-yellow-600": "#f6c251ff",
|
||||
"v2-yellow-700": "#e7af36ff",
|
||||
"v2-yellow-800": "#cb9f34ff",
|
||||
"v2-yellow-900": "#ac8833ff",
|
||||
"v2-yellow-1000": "#8e7231ff",
|
||||
"v2-yellow-1100": "#68552bff",
|
||||
"v2-yellow-1200": "#4b4025ff",
|
||||
"v2-green-100": "#e7f9eaff",
|
||||
"v2-green-200": "#d0f0d5ff",
|
||||
"v2-green-300": "#b8e9c1ff",
|
||||
"v2-green-400": "#96e3a6ff",
|
||||
"v2-green-500": "#6bd586ff",
|
||||
"v2-green-600": "#49c970ff",
|
||||
"v2-green-700": "#2eaf5aff",
|
||||
"v2-green-800": "#198b43ff",
|
||||
"v2-green-900": "#1d783cff",
|
||||
"v2-green-1000": "#196130ff",
|
||||
"v2-green-1100": "#164c26ff",
|
||||
"v2-green-1200": "#14361dff",
|
||||
"v2-cyan-100": "#e2f7fbff",
|
||||
"v2-cyan-200": "#c4edf4ff",
|
||||
"v2-cyan-300": "#a3e4efff",
|
||||
"v2-cyan-400": "#65d9ebff",
|
||||
"v2-cyan-500": "#00c5dfff",
|
||||
"v2-cyan-600": "#00abcfff",
|
||||
"v2-cyan-700": "#0096b8ff",
|
||||
"v2-cyan-800": "#007d9bff",
|
||||
"v2-cyan-900": "#006c85ff",
|
||||
"v2-cyan-1000": "#005a6eff",
|
||||
"v2-cyan-1100": "#004756ff",
|
||||
"v2-cyan-1200": "#00353fff",
|
||||
"v2-blue-100": "#ecf1feff",
|
||||
"v2-blue-200": "#d7e2fcff",
|
||||
"v2-blue-300": "#c3d4fdff",
|
||||
"v2-blue-400": "#a2bcffff",
|
||||
"v2-blue-500": "#7698fdff",
|
||||
"v2-blue-600": "#3b5cf6ff",
|
||||
"v2-blue-700": "#3250dfff",
|
||||
"v2-blue-800": "#2c47c8ff",
|
||||
"v2-blue-900": "#263fa9ff",
|
||||
"v2-blue-1000": "#22388fff",
|
||||
"v2-blue-1100": "#1c2e70ff",
|
||||
"v2-blue-1200": "#1b2852ff",
|
||||
"v2-purple-100": "#ebecfeff",
|
||||
"v2-purple-200": "#d5d5fcff",
|
||||
"v2-purple-300": "#b9b8f5ff",
|
||||
"v2-purple-400": "#9e99f7ff",
|
||||
"v2-purple-500": "#8271f8ff",
|
||||
"v2-purple-600": "#7152f4ff",
|
||||
"v2-purple-700": "#623be2ff",
|
||||
"v2-purple-800": "#5230c2ff",
|
||||
"v2-purple-900": "#442aa1ff",
|
||||
"v2-purple-1000": "#361f83ff",
|
||||
"v2-purple-1100": "#2b1b6aff",
|
||||
"v2-purple-1200": "#221358ff",
|
||||
"v2-pink-100": "#fdecf3ff",
|
||||
"v2-pink-200": "#f7d5e4ff",
|
||||
"v2-pink-300": "#fabcd8ff",
|
||||
"v2-pink-400": "#f799c6ff",
|
||||
"v2-pink-500": "#f26cb2ff",
|
||||
"v2-pink-600": "#f64aabff",
|
||||
"v2-pink-700": "#e4429eff",
|
||||
"v2-pink-800": "#c83d8bff",
|
||||
"v2-pink-900": "#aa3576ff",
|
||||
"v2-pink-1000": "#8c2d61ff",
|
||||
"v2-pink-1100": "#6f284fff",
|
||||
"v2-pink-1200": "#5c1d3fff",
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { blend, hexToOklch, shift } from "../color"
|
||||
import type { ColorValue, HexColor, V2ColorValue } from "../types"
|
||||
|
||||
export function mapV2Foreground(
|
||||
ink: HexColor,
|
||||
isDark: boolean,
|
||||
overrides: Record<string, ColorValue> = {},
|
||||
): Record<string, V2ColorValue> {
|
||||
const tint = hexToOklch(ink)
|
||||
const body = shift(ink, {
|
||||
l: isDark ? Math.max(0, 0.88 - tint.l) * 0.4 : -Math.max(0, tint.l - 0.18) * 0.24,
|
||||
c: isDark ? 1.04 : 1.02,
|
||||
})
|
||||
|
||||
return {
|
||||
"v2-text-text-base": isDark
|
||||
? blend("#ffffff", body, 0.9)
|
||||
: shift(body, { l: -0.07, c: 1.04 }),
|
||||
"v2-text-text-muted":
|
||||
overrides["text-weak"] ??
|
||||
shift(body, { l: isDark ? -0.11 : 0.11, c: 0.9 }),
|
||||
"v2-text-text-faint": shift(body, { l: isDark ? -0.2 : 0.21, c: isDark ? 0.78 : 0.72 }),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
import type { V2ColorValue } from "../types"
|
||||
import { V2_AVATAR_DARK, V2_AVATAR_LIGHT } from "./avatar"
|
||||
|
||||
const ref = (name: string): V2ColorValue => `var(--${name})`
|
||||
|
||||
const light: Record<string, V2ColorValue> = {
|
||||
"v2-background-bg-base": ref("v2-grey-100"),
|
||||
"v2-background-bg-deep": ref("v2-grey-200"),
|
||||
"v2-background-bg-layer-01": ref("v2-grey-300"),
|
||||
"v2-background-bg-layer-02": ref("v2-grey-400"),
|
||||
"v2-background-bg-layer-03": ref("v2-grey-500"),
|
||||
"v2-background-bg-inverse": ref("v2-grey-1000"),
|
||||
"v2-background-bg-contrast": ref("v2-grey-900"),
|
||||
"v2-background-bg-button-neutral": ref("v2-grey-100"),
|
||||
"v2-background-bg-accent": ref("v2-blue-600"),
|
||||
"v2-text-text-inverse": ref("v2-grey-100"),
|
||||
"v2-text-text-contrast": ref("v2-grey-100"),
|
||||
"v2-text-text-accent": ref("v2-blue-600"),
|
||||
"v2-text-text-accent-hover": ref("v2-blue-700"),
|
||||
"v2-icon-icon-base": ref("v2-grey-1000"),
|
||||
"v2-icon-icon-muted": ref("v2-grey-800"),
|
||||
"v2-icon-icon-inverse": ref("v2-grey-100"),
|
||||
"v2-icon-icon-contrast": ref("v2-grey-200"),
|
||||
"v2-icon-icon-accent": ref("v2-blue-600"),
|
||||
"v2-icon-icon-accent-hover": ref("v2-blue-700"),
|
||||
"v2-border-border-muted": ref("v2-alpha-dark-8"),
|
||||
"v2-border-border-base": ref("v2-alpha-dark-10"),
|
||||
"v2-border-border-strong": ref("v2-alpha-dark-20"),
|
||||
"v2-border-border-inverse": ref("v2-grey-1000"),
|
||||
"v2-border-border-focus": ref("v2-blue-500"),
|
||||
"v2-overlay-simple-overlay-hover": ref("v2-alpha-dark-4"),
|
||||
"v2-overlay-simple-overlay-pressed": ref("v2-alpha-dark-8"),
|
||||
"v2-overlay-simple-overlay-contrast-hover": ref("v2-alpha-light-12"),
|
||||
"v2-overlay-simple-overlay-contrast-pressed": ref("v2-alpha-light-24"),
|
||||
"v2-overlay-simple-overlay-scrim": ref("v2-alpha-dark-40"),
|
||||
"v2-overlay-gradient-depth-overlay-depth-top": ref("v2-alpha-light-100"),
|
||||
"v2-overlay-gradient-depth-overlay-depth-bot": ref("v2-alpha-light-0"),
|
||||
"v2-overlay-simple-tab-active-scrim": "#fafafa00",
|
||||
"v2-overlay-simple-tab-hover-scrim": "#eeeeee00",
|
||||
"v2-overlay-simple-tab-scrim": "#fafafa00",
|
||||
"v2-state-bg-success": ref("v2-green-100"),
|
||||
"v2-state-fg-success": ref("v2-green-800"),
|
||||
"v2-state-border-success": ref("v2-green-300"),
|
||||
"v2-state-bg-warning": ref("v2-yellow-100"),
|
||||
"v2-state-fg-warning": ref("v2-yellow-800"),
|
||||
"v2-state-border-warning": ref("v2-yellow-300"),
|
||||
"v2-state-bg-danger": ref("v2-red-100"),
|
||||
"v2-state-fg-danger": ref("v2-red-800"),
|
||||
"v2-state-border-danger": ref("v2-red-300"),
|
||||
"v2-state-bg-info": ref("v2-blue-100"),
|
||||
"v2-state-fg-info": ref("v2-blue-800"),
|
||||
"v2-state-border-info": ref("v2-blue-300"),
|
||||
...V2_AVATAR_LIGHT,
|
||||
"v2-elevation-raised":
|
||||
"0px 2px 4px 0px var(--v2-alpha-dark-4), 0px 1px 2px -1px var(--v2-alpha-dark-8), 0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-floating":
|
||||
"0px 8px 16px 0px var(--v2-alpha-dark-4), 0px 4px 8px 0px var(--v2-alpha-dark-8), 0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-overlay":
|
||||
"0px 16px 32px 0px var(--v2-alpha-dark-4), 0px 8px 16px 0px var(--v2-alpha-dark-8), 0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-button-neutral":
|
||||
"0px 1px 1.5px 0px var(--v2-alpha-dark-10), 0px 0px 0px 0.5px var(--v2-alpha-dark-14), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-button-contrast":
|
||||
"0px 1px 1.5px 0px var(--v2-alpha-dark-20), 0px 0px 0px 0.5px var(--v2-grey-800), inset 0px 1px 2px 0px var(--v2-alpha-light-14), inset 0px -1px 2px 0px var(--v2-alpha-dark-6), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
||||
"v2-elevation-elements": "0px 0.5px 0.5px 0px var(--v2-alpha-dark-40)",
|
||||
"v2-elevation-switch-off":
|
||||
"inset 0px 1px 1px 0px var(--v2-alpha-dark-8), inset 0px 0.5px 0.5px 0px var(--v2-alpha-dark-8), inset 0px 0px 0px 0.5px var(--v2-alpha-dark-10)",
|
||||
"v2-elevation-switch-on":
|
||||
"inset 0px 2px 2px 0px var(--v2-alpha-dark-10), inset 0px 1px 1px 0px var(--v2-alpha-dark-10), inset 0px 0px 0px 0.5px var(--v2-alpha-dark-20)",
|
||||
"v2-illustration-illustration-layer-01": ref("v2-grey-300"),
|
||||
"v2-illustration-illustration-layer-02": ref("v2-grey-400"),
|
||||
"v2-illustration-illustration-layer-03": ref("v2-grey-500"),
|
||||
}
|
||||
|
||||
const dark: Record<string, V2ColorValue> = {
|
||||
"v2-background-bg-base": ref("v2-grey-1000"),
|
||||
"v2-background-bg-deep": ref("v2-grey-1100"),
|
||||
"v2-background-bg-layer-01": ref("v2-grey-800"),
|
||||
"v2-background-bg-layer-02": ref("v2-grey-600"),
|
||||
"v2-background-bg-layer-03": ref("v2-grey-500"),
|
||||
"v2-background-bg-inverse": ref("v2-grey-100"),
|
||||
"v2-background-bg-contrast": ref("v2-grey-700"),
|
||||
"v2-background-bg-button-neutral": ref("v2-alpha-light-6"),
|
||||
"v2-background-bg-accent": ref("v2-blue-600"),
|
||||
"v2-text-text-inverse": ref("v2-grey-1000"),
|
||||
"v2-text-text-contrast": ref("v2-grey-100"),
|
||||
"v2-text-text-accent": ref("v2-blue-400"),
|
||||
"v2-text-text-accent-hover": ref("v2-blue-300"),
|
||||
"v2-icon-icon-base": ref("v2-grey-300"),
|
||||
"v2-icon-icon-muted": ref("v2-grey-400"),
|
||||
"v2-icon-icon-inverse": ref("v2-grey-1000"),
|
||||
"v2-icon-icon-contrast": ref("v2-grey-200"),
|
||||
"v2-icon-icon-accent": ref("v2-blue-400"),
|
||||
"v2-icon-icon-accent-hover": ref("v2-blue-300"),
|
||||
"v2-border-border-muted": ref("v2-alpha-light-8"),
|
||||
"v2-border-border-base": ref("v2-alpha-light-10"),
|
||||
"v2-border-border-strong": ref("v2-alpha-light-20"),
|
||||
"v2-border-border-inverse": ref("v2-grey-100"),
|
||||
"v2-border-border-focus": ref("v2-blue-500"),
|
||||
"v2-overlay-simple-overlay-hover": ref("v2-alpha-light-6"),
|
||||
"v2-overlay-simple-overlay-pressed": ref("v2-alpha-light-10"),
|
||||
"v2-overlay-simple-overlay-contrast-hover": ref("v2-alpha-dark-24"),
|
||||
"v2-overlay-simple-overlay-contrast-pressed": ref("v2-alpha-dark-40"),
|
||||
"v2-overlay-simple-overlay-scrim": ref("v2-alpha-light-30"),
|
||||
"v2-overlay-gradient-depth-overlay-depth-top": ref("v2-alpha-light-100"),
|
||||
"v2-overlay-gradient-depth-overlay-depth-bot": ref("v2-alpha-light-0"),
|
||||
"v2-overlay-simple-tab-active-scrim": "#24242400",
|
||||
"v2-overlay-simple-tab-hover-scrim": "#3a3a3a00",
|
||||
"v2-overlay-simple-tab-scrim": "#08080800",
|
||||
"v2-state-bg-success": ref("v2-green-1200"),
|
||||
"v2-state-fg-success": ref("v2-green-500"),
|
||||
"v2-state-border-success": ref("v2-green-900"),
|
||||
"v2-state-bg-warning": ref("v2-yellow-1200"),
|
||||
"v2-state-fg-warning": ref("v2-yellow-500"),
|
||||
"v2-state-border-warning": ref("v2-yellow-900"),
|
||||
"v2-state-bg-danger": ref("v2-red-1200"),
|
||||
"v2-state-fg-danger": ref("v2-red-500"),
|
||||
"v2-state-border-danger": ref("v2-red-900"),
|
||||
"v2-state-bg-info": ref("v2-blue-1200"),
|
||||
"v2-state-fg-info": ref("v2-blue-500"),
|
||||
"v2-state-border-info": ref("v2-blue-900"),
|
||||
...V2_AVATAR_DARK,
|
||||
"v2-elevation-raised":
|
||||
"0px 2px 4px 0px var(--v2-alpha-dark-30), 0px 1px 2px 0px var(--v2-alpha-dark-30), 0px 0px 0px 0.5px var(--v2-alpha-light-16), 0px -0.5px 0px 0px var(--v2-alpha-light-6)",
|
||||
"v2-elevation-floating":
|
||||
"0px 8px 16px 0px var(--v2-alpha-dark-30), 0px 4px 8px 0px var(--v2-alpha-dark-30), 0px 0px 0px 0.5px var(--v2-alpha-light-16), 0px -0.5px 0px 0px var(--v2-alpha-light-6)",
|
||||
"v2-elevation-overlay":
|
||||
"0px 16px 32px 0px var(--v2-alpha-dark-30), 0px 8px 16px 0px var(--v2-alpha-dark-30), 0px 0px 0px 0.5px var(--v2-alpha-light-16), 0px -0.5px 0px 0px var(--v2-alpha-light-6)",
|
||||
"v2-elevation-button-neutral":
|
||||
"0px 1px 2px 0px var(--v2-alpha-dark-40), 0px 0px 0px 0.5px var(--v2-alpha-light-20), 0px -0.5px 0px 0px var(--v2-alpha-light-10)",
|
||||
"v2-elevation-button-contrast":
|
||||
"0px 1px 2px 0px var(--v2-alpha-dark-40), 0px 0px 0px 0.5px var(--v2-alpha-light-40), inset 0px 0px 0px 0px var(--v2-alpha-light-0), inset 0px 0px 0px 0px var(--v2-alpha-light-0), 0px -0.5px 0px 0px var(--v2-alpha-light-30)",
|
||||
"v2-elevation-elements": "0px 0.5px 0.5px 0px var(--v2-alpha-dark-40)",
|
||||
"v2-elevation-switch-off":
|
||||
"inset 0px -0.5px 0px 0px var(--v2-alpha-light-10), inset 0px 0px 0px 0px var(--v2-alpha-light-0), inset 0px 0px 0px 0.5px var(--v2-alpha-light-16)",
|
||||
"v2-elevation-switch-on":
|
||||
"inset 0px -0.5px 0px 0px var(--v2-alpha-light-10), inset 0px 0px 0px 0px var(--v2-alpha-light-0), inset 0px 0px 0px 0.5px var(--v2-alpha-light-16)",
|
||||
"v2-illustration-illustration-layer-01": ref("v2-grey-900"),
|
||||
"v2-illustration-illustration-layer-02": ref("v2-grey-800"),
|
||||
"v2-illustration-illustration-layer-03": ref("v2-grey-700"),
|
||||
}
|
||||
|
||||
export function mapV2Semantics(isDark: boolean): Record<string, V2ColorValue> {
|
||||
return isDark ? dark : light
|
||||
}
|
||||
|
||||
export function mergeV2Tokens(
|
||||
...layers: Record<string, V2ColorValue>[]
|
||||
): Record<string, V2ColorValue> {
|
||||
return Object.assign({}, ...layers)
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// @refresh reload
|
||||
|
||||
import { generateNeutralScale, hexToOklch, oklchToHex, shift } from "../color"
|
||||
import { mapV2Foreground } from "./foreground"
|
||||
import { mapV2Semantics, mergeV2Tokens } from "./mapping"
|
||||
import type { DesktopTheme, HexColor, ResolvedV2Theme, ThemeVariant, V2ColorValue } from "../types"
|
||||
import { V2_PRIMITIVES_DEFAULT } from "./default-primitives"
|
||||
|
||||
const V2_STEPS = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200] as const
|
||||
|
||||
interface PaletteInput {
|
||||
neutral: HexColor
|
||||
ink: HexColor
|
||||
primary: HexColor
|
||||
accent: HexColor
|
||||
success: HexColor
|
||||
warning: HexColor
|
||||
error: HexColor
|
||||
info: HexColor
|
||||
interactive: HexColor
|
||||
diffAdd: HexColor
|
||||
diffDelete: HexColor
|
||||
}
|
||||
|
||||
function clamp(v: number, min: number, max: number) {
|
||||
return Math.max(min, Math.min(max, v))
|
||||
}
|
||||
|
||||
/** v2 ramps: 100 = lightest, 1200 = darkest — wider spread than v1 `generateScale`. */
|
||||
function generateV2HueScale(seed: HexColor, isDark: boolean): HexColor[] {
|
||||
const base = hexToOklch(seed)
|
||||
const chromaBoost = isDark ? 1 : 1.05
|
||||
const lightSteps = [
|
||||
0.99,
|
||||
0.965,
|
||||
0.93,
|
||||
0.885,
|
||||
0.835,
|
||||
clamp(base.l, 0.48, 0.72),
|
||||
clamp(base.l - 0.07, 0.4, 0.64),
|
||||
clamp(base.l - 0.14, 0.32, 0.55),
|
||||
clamp(base.l - 0.21, 0.24, 0.46),
|
||||
clamp(base.l - 0.28, 0.17, 0.38),
|
||||
clamp(base.l - 0.34, 0.12, 0.3),
|
||||
clamp(base.l - 0.4, 0.08, 0.22),
|
||||
]
|
||||
const chromaMultipliers = [0.28, 0.48, 0.68, 0.86, 1.02, 1.28, 1.34, 1.28, 1.18, 1.08, 0.98, 0.88]
|
||||
|
||||
return lightSteps.map((l, i) =>
|
||||
oklchToHex({
|
||||
l,
|
||||
c: base.c * chromaMultipliers[i]! * chromaBoost,
|
||||
h: base.h,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/** Grey ramp: 100 = lightest, 1200 = darkest. Derived from palette neutral → ink like v1. */
|
||||
function generateV2NeutralScale(neutral: HexColor, ink: HexColor, isDark: boolean): HexColor[] {
|
||||
const scale = generateNeutralScale(neutral, isDark, ink)
|
||||
return isDark ? scale.toReversed() : scale
|
||||
}
|
||||
|
||||
function assignHueRamp(prefix: string, scale: HexColor[]): Record<string, V2ColorValue> {
|
||||
const tokens: Record<string, V2ColorValue> = {}
|
||||
for (let i = 0; i < V2_STEPS.length; i++) {
|
||||
tokens[`v2-${prefix}-${V2_STEPS[i]}`] = scale[i]!
|
||||
}
|
||||
return tokens
|
||||
}
|
||||
|
||||
function readPalette(variant: ThemeVariant): PaletteInput {
|
||||
if ("palette" in variant && variant.palette) {
|
||||
const palette = variant.palette
|
||||
return {
|
||||
neutral: palette.neutral,
|
||||
ink: palette.ink,
|
||||
primary: palette.primary,
|
||||
accent: palette.accent ?? palette.info,
|
||||
success: palette.success,
|
||||
warning: palette.warning,
|
||||
error: palette.error,
|
||||
info: palette.info,
|
||||
interactive: palette.interactive ?? palette.primary,
|
||||
diffAdd: palette.diffAdd ?? shift(palette.success, { c: 0.55, l: 0.14 }),
|
||||
diffDelete: palette.diffDelete ?? palette.error,
|
||||
}
|
||||
}
|
||||
if ("seeds" in variant && variant.seeds) {
|
||||
const seeds = variant.seeds
|
||||
return {
|
||||
neutral: seeds.neutral,
|
||||
ink: seeds.neutral,
|
||||
primary: seeds.primary,
|
||||
accent: seeds.info,
|
||||
success: seeds.success,
|
||||
warning: seeds.warning,
|
||||
error: seeds.error,
|
||||
info: seeds.info,
|
||||
interactive: seeds.interactive,
|
||||
diffAdd: seeds.diffAdd,
|
||||
diffDelete: seeds.diffDelete,
|
||||
}
|
||||
}
|
||||
throw new Error("Theme variant requires `palette` or `seeds`")
|
||||
}
|
||||
|
||||
/** Build v2 primitive ramps (100 = lightest). Alpha ramps are static in `v2/styles/colors.css`. */
|
||||
export function generateV2Primitives(variant: ThemeVariant, isDark: boolean): Record<string, V2ColorValue> {
|
||||
const colors = readPalette(variant)
|
||||
const grey = generateV2NeutralScale(colors.neutral, colors.ink, isDark)
|
||||
const blue = generateV2HueScale(colors.interactive, isDark)
|
||||
const green = generateV2HueScale(colors.success, isDark)
|
||||
const yellow = generateV2HueScale(colors.warning, isDark)
|
||||
const red = generateV2HueScale(colors.error, isDark)
|
||||
const purple = generateV2HueScale(colors.accent, isDark)
|
||||
const pink = generateV2HueScale(colors.info, isDark)
|
||||
const orange = generateV2HueScale(shift(colors.warning, { h: -22, l: -0.082, c: 0.94 }), isDark)
|
||||
const cyan = generateV2HueScale(shift(colors.info, { h: -12, l: 0.128, c: 1.12 }), isDark)
|
||||
|
||||
return {
|
||||
...V2_PRIMITIVES_DEFAULT,
|
||||
...assignHueRamp("grey", grey),
|
||||
...assignHueRamp("blue", blue),
|
||||
...assignHueRamp("green", green),
|
||||
...assignHueRamp("yellow", yellow),
|
||||
...assignHueRamp("red", red),
|
||||
...assignHueRamp("purple", purple),
|
||||
...assignHueRamp("pink", pink),
|
||||
...assignHueRamp("orange", orange),
|
||||
...assignHueRamp("cyan", cyan),
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveThemeVariantV2(variant: ThemeVariant, isDark: boolean): ResolvedV2Theme {
|
||||
const primitives = generateV2Primitives(variant, isDark)
|
||||
const semantics = mapV2Semantics(isDark)
|
||||
const foreground = mapV2Foreground(readPalette(variant).ink, isDark, variant.overrides)
|
||||
return mergeV2Tokens(primitives, semantics, foreground, variant.v2Overrides ?? {})
|
||||
}
|
||||
|
||||
export function resolveThemeV2(theme: DesktopTheme): { light: ResolvedV2Theme; dark: ResolvedV2Theme } {
|
||||
return {
|
||||
light: resolveThemeVariantV2(theme.light, false),
|
||||
dark: resolveThemeVariantV2(theme.dark, true),
|
||||
}
|
||||
}
|
||||
|
||||
export function themeV2ToCss(tokens: ResolvedV2Theme): string {
|
||||
return Object.entries(tokens)
|
||||
.map(([key, value]) => `--${key}: ${value};`)
|
||||
.join("\n ")
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
background-color: var(--v2-overlay-simple-overlay-scrim);
|
||||
}
|
||||
|
||||
[data-component="dialog"] {
|
||||
[data-component="dialog-v2"] {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 50;
|
||||
@@ -25,7 +25,7 @@
|
||||
background: var(--v2-background-bg-layer-01);
|
||||
box-shadow: var(--v2-elevation-overlay);
|
||||
border-radius: 6px;
|
||||
overflow: visible;
|
||||
overflow: hidden;
|
||||
pointer-events: auto;
|
||||
|
||||
[data-slot="dialog-content"] {
|
||||
@@ -37,6 +37,7 @@
|
||||
max-height: 100%;
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
background: transparent;
|
||||
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
|
||||
@@ -17,7 +17,7 @@ Dialog content wrapper built on Kobalte's dialog primitive with v2 styling.
|
||||
- Focus trapping and aria attributes provided by Kobalte Dialog.
|
||||
|
||||
### Theming/tokens
|
||||
- Uses \`data-component="dialog"\` and slot attributes.
|
||||
- Uses \`data-component="dialog-v2"\` and slot attributes.
|
||||
`
|
||||
|
||||
export default {
|
||||
|
||||
@@ -7,6 +7,7 @@ export interface DialogProps extends ParentProps {
|
||||
description?: JSXElement
|
||||
action?: JSXElement
|
||||
size?: "normal" | "large" | "x-large"
|
||||
variant?: "default" | "settings"
|
||||
class?: ComponentProps<"div">["class"]
|
||||
classList?: ComponentProps<"div">["classList"]
|
||||
fit?: boolean
|
||||
@@ -17,14 +18,19 @@ export function DialogFooter(props: ParentProps) {
|
||||
}
|
||||
|
||||
export function Dialog(props: DialogProps) {
|
||||
const [local] = splitProps(props, ["title", "description", "action", "size", "class", "classList", "fit", "children"])
|
||||
const [local] = splitProps(props, ["title", "description", "action", "size", "variant", "class", "classList", "fit", "children"])
|
||||
const title = children(() => local.title)
|
||||
const description = children(() => local.description)
|
||||
const action = children(() => local.action)
|
||||
const hasHeader = () => title() || action()
|
||||
|
||||
return (
|
||||
<div data-component="dialog" data-fit={local.fit ? true : undefined} data-size={local.size || "normal"}>
|
||||
<div
|
||||
data-component="dialog-v2"
|
||||
data-variant={local.variant === "settings" ? "settings" : undefined}
|
||||
data-fit={local.fit ? true : undefined}
|
||||
data-size={local.size || "normal"}
|
||||
>
|
||||
<div data-slot="dialog-container">
|
||||
<Kobalte.Content
|
||||
data-slot="dialog-content"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
letter-spacing: 0.05px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
text-transform: uppercase;
|
||||
color: var(--v2-grey-100);
|
||||
color: var(--v2-avatar-fg);
|
||||
text-shadow: 0 0 4px var(--v2-alpha-dark-20);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
|
||||
@@ -63,25 +63,26 @@
|
||||
--v2-state-fg-info: var(--v2-blue-800);
|
||||
--v2-state-border-info: var(--v2-blue-300);
|
||||
|
||||
/* ── Project avatar ── */
|
||||
--v2-avatar-bg-orange: var(--v2-orange-700);
|
||||
--v2-avatar-border-orange: var(--v2-orange-800);
|
||||
--v2-avatar-bg-yellow: var(--v2-yellow-700);
|
||||
--v2-avatar-border-yellow: var(--v2-yellow-800);
|
||||
--v2-avatar-bg-cyan: var(--v2-cyan-700);
|
||||
--v2-avatar-border-cyan: var(--v2-cyan-800);
|
||||
--v2-avatar-bg-green: var(--v2-green-700);
|
||||
--v2-avatar-border-green: var(--v2-green-800);
|
||||
--v2-avatar-bg-red: var(--v2-red-700);
|
||||
--v2-avatar-border-red: var(--v2-red-800);
|
||||
--v2-avatar-bg-pink: var(--v2-pink-700);
|
||||
--v2-avatar-border-pink: var(--v2-pink-800);
|
||||
--v2-avatar-bg-blue: var(--v2-blue-700);
|
||||
--v2-avatar-border-blue: var(--v2-blue-800);
|
||||
--v2-avatar-bg-purple: var(--v2-purple-700);
|
||||
--v2-avatar-border-purple: var(--v2-purple-800);
|
||||
--v2-avatar-bg-gray: var(--v2-grey-700);
|
||||
--v2-avatar-border-gray: var(--v2-grey-800);
|
||||
/* ── Project avatar (fixed; theme-independent) ── */
|
||||
--v2-avatar-fg: #ffffffff;
|
||||
--v2-avatar-bg-orange: #ee7330ff;
|
||||
--v2-avatar-border-orange: #d16427ff;
|
||||
--v2-avatar-bg-yellow: #e7af36ff;
|
||||
--v2-avatar-border-yellow: #cb9f34ff;
|
||||
--v2-avatar-bg-cyan: #0096b8ff;
|
||||
--v2-avatar-border-cyan: #007d9bff;
|
||||
--v2-avatar-bg-green: #2eaf5aff;
|
||||
--v2-avatar-border-green: #198b43ff;
|
||||
--v2-avatar-bg-red: #d92e3cff;
|
||||
--v2-avatar-border-red: #b82d35ff;
|
||||
--v2-avatar-bg-pink: #e4429eff;
|
||||
--v2-avatar-border-pink: #c83d8bff;
|
||||
--v2-avatar-bg-blue: #3250dfff;
|
||||
--v2-avatar-border-blue: #2c47c8ff;
|
||||
--v2-avatar-bg-purple: #623be2ff;
|
||||
--v2-avatar-border-purple: #5230c2ff;
|
||||
--v2-avatar-bg-gray: #5c5c5cff;
|
||||
--v2-avatar-border-gray: #3a3a3aff;
|
||||
|
||||
/* ── Elevation ── */
|
||||
--v2-elevation-raised:
|
||||
@@ -306,24 +307,25 @@
|
||||
--v2-illustration-illustration-layer-02: var(--v2-grey-400);
|
||||
--v2-illustration-illustration-layer-03: var(--v2-grey-500);
|
||||
|
||||
--v2-avatar-bg-orange: var(--v2-orange-700);
|
||||
--v2-avatar-border-orange: var(--v2-orange-800);
|
||||
--v2-avatar-bg-yellow: var(--v2-yellow-700);
|
||||
--v2-avatar-border-yellow: var(--v2-yellow-800);
|
||||
--v2-avatar-bg-cyan: var(--v2-cyan-700);
|
||||
--v2-avatar-border-cyan: var(--v2-cyan-800);
|
||||
--v2-avatar-bg-green: var(--v2-green-700);
|
||||
--v2-avatar-border-green: var(--v2-green-800);
|
||||
--v2-avatar-bg-red: var(--v2-red-700);
|
||||
--v2-avatar-border-red: var(--v2-red-800);
|
||||
--v2-avatar-bg-pink: var(--v2-pink-700);
|
||||
--v2-avatar-border-pink: var(--v2-pink-800);
|
||||
--v2-avatar-bg-blue: var(--v2-blue-700);
|
||||
--v2-avatar-border-blue: var(--v2-blue-800);
|
||||
--v2-avatar-bg-purple: var(--v2-purple-700);
|
||||
--v2-avatar-border-purple: var(--v2-purple-800);
|
||||
--v2-avatar-bg-gray: var(--v2-grey-700);
|
||||
--v2-avatar-border-gray: var(--v2-grey-800);
|
||||
--v2-avatar-fg: #ffffffff;
|
||||
--v2-avatar-bg-orange: #ee7330ff;
|
||||
--v2-avatar-border-orange: #d16427ff;
|
||||
--v2-avatar-bg-yellow: #e7af36ff;
|
||||
--v2-avatar-border-yellow: #cb9f34ff;
|
||||
--v2-avatar-bg-cyan: #0096b8ff;
|
||||
--v2-avatar-border-cyan: #007d9bff;
|
||||
--v2-avatar-bg-green: #2eaf5aff;
|
||||
--v2-avatar-border-green: #198b43ff;
|
||||
--v2-avatar-bg-red: #d92e3cff;
|
||||
--v2-avatar-border-red: #b82d35ff;
|
||||
--v2-avatar-bg-pink: #e4429eff;
|
||||
--v2-avatar-border-pink: #c83d8bff;
|
||||
--v2-avatar-bg-blue: #3250dfff;
|
||||
--v2-avatar-border-blue: #2c47c8ff;
|
||||
--v2-avatar-bg-purple: #623be2ff;
|
||||
--v2-avatar-border-purple: #5230c2ff;
|
||||
--v2-avatar-bg-gray: #5c5c5cff;
|
||||
--v2-avatar-border-gray: #3a3a3aff;
|
||||
}
|
||||
|
||||
/* Explicit dark mode via data attribute (Storybook toggle, runtime JS) */
|
||||
@@ -385,24 +387,25 @@
|
||||
--v2-state-fg-info: var(--v2-blue-500);
|
||||
--v2-state-border-info: var(--v2-blue-900);
|
||||
|
||||
--v2-avatar-bg-orange: var(--v2-orange-1100);
|
||||
--v2-avatar-border-orange: var(--v2-orange-600);
|
||||
--v2-avatar-bg-yellow: var(--v2-yellow-1100);
|
||||
--v2-avatar-border-yellow: var(--v2-yellow-700);
|
||||
--v2-avatar-bg-cyan: var(--v2-cyan-1000);
|
||||
--v2-avatar-border-cyan: var(--v2-cyan-700);
|
||||
--v2-avatar-bg-green: var(--v2-green-1000);
|
||||
--v2-avatar-border-green: var(--v2-green-600);
|
||||
--v2-avatar-bg-red: var(--v2-red-1000);
|
||||
--v2-avatar-border-red: var(--v2-red-700);
|
||||
--v2-avatar-bg-pink: var(--v2-pink-1000);
|
||||
--v2-avatar-border-pink: var(--v2-pink-700);
|
||||
--v2-avatar-bg-blue: var(--v2-blue-900);
|
||||
--v2-avatar-border-blue: var(--v2-blue-500);
|
||||
--v2-avatar-bg-purple: var(--v2-purple-1000);
|
||||
--v2-avatar-border-purple: var(--v2-purple-600);
|
||||
--v2-avatar-bg-gray: var(--v2-grey-700);
|
||||
--v2-avatar-border-gray: var(--v2-grey-500);
|
||||
--v2-avatar-fg: #ffffffff;
|
||||
--v2-avatar-bg-orange: #723d22ff;
|
||||
--v2-avatar-border-orange: #ff8648ff;
|
||||
--v2-avatar-bg-yellow: #68552bff;
|
||||
--v2-avatar-border-yellow: #e7af36ff;
|
||||
--v2-avatar-bg-cyan: #005a6eff;
|
||||
--v2-avatar-border-cyan: #0096b8ff;
|
||||
--v2-avatar-bg-green: #196130ff;
|
||||
--v2-avatar-border-green: #49c970ff;
|
||||
--v2-avatar-bg-red: #7a1f23ff;
|
||||
--v2-avatar-border-red: #d92e3cff;
|
||||
--v2-avatar-bg-pink: #8c2d61ff;
|
||||
--v2-avatar-border-pink: #e4429eff;
|
||||
--v2-avatar-bg-blue: #263fa9ff;
|
||||
--v2-avatar-border-blue: #7698fdff;
|
||||
--v2-avatar-bg-purple: #361f83ff;
|
||||
--v2-avatar-border-purple: #7152f4ff;
|
||||
--v2-avatar-bg-gray: #5c5c5cff;
|
||||
--v2-avatar-border-gray: #aeaeaeff;
|
||||
|
||||
--v2-elevation-raised:
|
||||
0px 2px 4px 0px var(--v2-alpha-dark-30), 0px 1px 2px 0px var(--v2-alpha-dark-30),
|
||||
|
||||
Reference in New Issue
Block a user