fix(tui): derive session surface colors from hues (#37401)
This commit is contained in:
parent
331533deff
commit
f76e18201a
6 changed files with 67 additions and 36 deletions
|
|
@ -78,8 +78,8 @@ export function createComponentTheme(current: Accessor<ResolvedThemeView>) {
|
|||
|
||||
return {
|
||||
hue,
|
||||
increase: (color: RGBA, amount = 1) => shiftHue(current(), color, amount),
|
||||
decrease: (color: RGBA, amount = 1) => shiftHue(current(), color, -amount),
|
||||
increase: (color: RGBA, amount = 1) => current().increase(color, amount),
|
||||
decrease: (color: RGBA, amount = 1) => current().decrease(color, amount),
|
||||
text,
|
||||
background,
|
||||
border: () => current().border.default,
|
||||
|
|
@ -123,17 +123,6 @@ export function createComponentTheme(current: Accessor<ResolvedThemeView>) {
|
|||
}
|
||||
}
|
||||
|
||||
function shiftHue(theme: ResolvedThemeView, color: RGBA, amount: number) {
|
||||
const colors = Object.values(theme.hue).flatMap((scale) =>
|
||||
HueStep.literals.map((step, index) => ({ color: scale[step], index, scale })),
|
||||
)
|
||||
const match = colors.find((entry) => entry.color === color) ?? colors.find((entry) => entry.color.equals(color))
|
||||
if (!match) return color
|
||||
const offset = Number.isFinite(amount) ? Math.trunc(amount) : 0
|
||||
const index = Math.max(0, Math.min(HueStep.literals.length - 1, match.index + offset))
|
||||
return match.scale[HueStep.literals[index]]
|
||||
}
|
||||
|
||||
function actions(get: (variant: ActionVariant, state: ResolvedActionState) => RGBA) {
|
||||
const action = (variant: ActionVariant) => (states: ActionState | "default" | ActionStates = "default") => {
|
||||
if (typeof states === "string") return get(variant, states)
|
||||
|
|
|
|||
|
|
@ -70,14 +70,15 @@ export function resolveTheme(definition: ThemeDefinition): ResolvedTheme {
|
|||
|
||||
function resolveExpandedTheme(definition: ThemeDefinition): ResolvedTheme {
|
||||
const hue = resolveHue(definition.hue)
|
||||
const hueSteps = compileHueSteps(hue)
|
||||
const base = tokens(definition)
|
||||
const resolved = resolveView(base, hue)
|
||||
const resolved = resolveView(base, hue, hueSteps)
|
||||
const contexts = Object.fromEntries(
|
||||
Object.entries(definition)
|
||||
.filter(([key]) => key.startsWith("@context:"))
|
||||
.map(([key, override]) => {
|
||||
const contextual = contextualize(base, override as ThemeTokensDefinition)
|
||||
return [key, resolveView(contextual, hue)]
|
||||
return [key, resolveView(contextual, hue, hueSteps)]
|
||||
}),
|
||||
)
|
||||
|
||||
|
|
@ -138,9 +139,36 @@ function contextualActions(
|
|||
)
|
||||
}
|
||||
|
||||
function resolveView(definition: ThemeTokensDefinition, hue: ResolvedThemeView["hue"]): ResolvedThemeView {
|
||||
function resolveView(
|
||||
definition: ThemeTokensDefinition,
|
||||
hue: ResolvedThemeView["hue"],
|
||||
hueSteps: Pick<ResolvedThemeView, "increase" | "decrease">,
|
||||
): ResolvedThemeView {
|
||||
const source: Record<string, unknown> = { hue, ...definition }
|
||||
return { ...(createResolver(source)(source, "theme") as ResolvedThemeView), hue }
|
||||
return { ...(createResolver(source)(source, "theme") as ResolvedThemeView), hue, ...hueSteps }
|
||||
}
|
||||
|
||||
function compileHueSteps(hue: ResolvedThemeView["hue"]): Pick<ResolvedThemeView, "increase" | "decrease"> {
|
||||
const index = new Map(
|
||||
Object.values(hue).flatMap((scale) =>
|
||||
HueStep.literals.map((step, position) => [colorKey(scale[step]), { position, scale }] as const),
|
||||
),
|
||||
)
|
||||
const shift = (color: RGBA, amount: number) => {
|
||||
const match = index.get(colorKey(color))
|
||||
if (!match) return color
|
||||
const offset = Number.isFinite(amount) ? Math.trunc(amount) : 0
|
||||
const position = Math.max(0, Math.min(HueStep.literals.length - 1, match.position + offset))
|
||||
return match.scale[HueStep.literals[position]]
|
||||
}
|
||||
return {
|
||||
increase: (color, amount = 1) => shift(color, amount),
|
||||
decrease: (color, amount = 1) => shift(color, -amount),
|
||||
}
|
||||
}
|
||||
|
||||
function colorKey(color: RGBA) {
|
||||
return color.toInts().join(":")
|
||||
}
|
||||
|
||||
function resolveHue(definition: HueDefinition) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ export type FormfieldColor = Readonly<Record<ResolvedFormfieldState, RGBA>>
|
|||
|
||||
export type ResolvedThemeView = {
|
||||
readonly hue: Hue
|
||||
readonly increase: (color: RGBA, amount?: number) => RGBA
|
||||
readonly decrease: (color: RGBA, amount?: number) => RGBA
|
||||
readonly text: {
|
||||
readonly default: RGBA
|
||||
readonly subdued: RGBA
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue