このコミットが含まれているのは:
+137
-16
@@ -14,12 +14,35 @@ export type BuiltinThemeId = 'light' | 'dark'
|
||||
export type ThemeId = BuiltinThemeId | `custom:${ string }`
|
||||
export type ActiveThemeId = ThemeId | 'system'
|
||||
export type ResolvedTheme = 'light' | 'dark'
|
||||
export type ThemeTokens = {
|
||||
background: string
|
||||
foreground: string
|
||||
card: string
|
||||
cardForeground: string
|
||||
popover: string
|
||||
popoverForeground: string
|
||||
primary: string
|
||||
primaryForeground: string
|
||||
secondary: string
|
||||
secondaryForeground: string
|
||||
muted: string
|
||||
mutedForeground: string
|
||||
accent: string
|
||||
accentForeground: string
|
||||
destructive: string
|
||||
destructiveForeground: string
|
||||
border: string
|
||||
input: string
|
||||
ring: string
|
||||
link: string
|
||||
tagColours: ThemeTagColours
|
||||
}
|
||||
export type ClientTheme = {
|
||||
id: ThemeId
|
||||
name: string
|
||||
builtin: boolean
|
||||
baseTheme: BuiltinThemeId
|
||||
tagColours: ThemeTagColours }
|
||||
tokens: ThemeTokens }
|
||||
export type CustomClientTheme =
|
||||
ClientTheme & { builtin: false }
|
||||
|
||||
@@ -119,20 +142,66 @@ export const DEFAULT_DARK_THEME_TAG_COLOURS: ThemeTagColours = {
|
||||
nico: '#e5e7eb',
|
||||
}
|
||||
export const DEFAULT_THEME_TAG_COLOURS = DEFAULT_LIGHT_THEME_TAG_COLOURS
|
||||
export const LIGHT_THEME_TOKENS: ThemeTokens = {
|
||||
background: '0 0% 100%',
|
||||
foreground: '222.2 84% 4.9%',
|
||||
card: '0 0% 100%',
|
||||
cardForeground: '222.2 84% 4.9%',
|
||||
popover: '0 0% 100%',
|
||||
popoverForeground: '222.2 84% 4.9%',
|
||||
primary: '222.2 47.4% 11.2%',
|
||||
primaryForeground: '210 40% 98%',
|
||||
secondary: '210 40% 96.1%',
|
||||
secondaryForeground: '222.2 47.4% 11.2%',
|
||||
muted: '210 40% 96.1%',
|
||||
mutedForeground: '215.4 16.3% 46.9%',
|
||||
accent: '210 40% 96.1%',
|
||||
accentForeground: '222.2 47.4% 11.2%',
|
||||
destructive: '0 72.2% 50.6%',
|
||||
destructiveForeground: '210 40% 98%',
|
||||
border: '214.3 31.8% 91.4%',
|
||||
input: '214.3 31.8% 91.4%',
|
||||
ring: '222.2 84% 4.9%',
|
||||
link: '221.2 83.2% 53.3%',
|
||||
tagColours: DEFAULT_LIGHT_THEME_TAG_COLOURS,
|
||||
}
|
||||
export const DARK_THEME_TOKENS: ThemeTokens = {
|
||||
background: '222.2 84% 4.9%',
|
||||
foreground: '210 40% 98%',
|
||||
card: '222.2 84% 4.9%',
|
||||
cardForeground: '210 40% 98%',
|
||||
popover: '222.2 84% 4.9%',
|
||||
popoverForeground: '210 40% 98%',
|
||||
primary: '210 40% 98%',
|
||||
primaryForeground: '222.2 47.4% 11.2%',
|
||||
secondary: '217.2 32.6% 17.5%',
|
||||
secondaryForeground: '210 40% 98%',
|
||||
muted: '217.2 32.6% 17.5%',
|
||||
mutedForeground: '215 20.2% 65.1%',
|
||||
accent: '217.2 32.6% 17.5%',
|
||||
accentForeground: '210 40% 98%',
|
||||
destructive: '0 62.8% 45%',
|
||||
destructiveForeground: '210 40% 98%',
|
||||
border: '217.2 32.6% 17.5%',
|
||||
input: '217.2 32.6% 17.5%',
|
||||
ring: '212.7 26.8% 83.9%',
|
||||
link: '213.1 93.9% 67.8%',
|
||||
tagColours: DEFAULT_DARK_THEME_TAG_COLOURS,
|
||||
}
|
||||
export const BUILTIN_THEMES: Record<BuiltinThemeId, ClientTheme> = {
|
||||
light: {
|
||||
id: 'light',
|
||||
name: 'ライト・モード',
|
||||
builtin: true,
|
||||
baseTheme: 'light',
|
||||
tagColours: DEFAULT_LIGHT_THEME_TAG_COLOURS,
|
||||
tokens: LIGHT_THEME_TOKENS,
|
||||
},
|
||||
dark: {
|
||||
id: 'dark',
|
||||
name: 'ダーク・モード',
|
||||
builtin: true,
|
||||
baseTheme: 'dark',
|
||||
tagColours: DEFAULT_DARK_THEME_TAG_COLOURS,
|
||||
tokens: DARK_THEME_TOKENS,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -369,10 +438,26 @@ const normaliseCustomTheme = (
|
||||
name,
|
||||
builtin: false,
|
||||
baseTheme,
|
||||
tagColours: normaliseThemeTagColours (
|
||||
theme.tagColours as Partial<ThemeTagColours> | undefined,
|
||||
defaultThemeTagColoursFor (baseTheme),
|
||||
),
|
||||
tokens: {
|
||||
...(
|
||||
baseTheme === 'dark'
|
||||
? DARK_THEME_TOKENS
|
||||
: LIGHT_THEME_TOKENS
|
||||
),
|
||||
...(theme.tokens && typeof theme.tokens === 'object'
|
||||
? theme.tokens as Partial<ThemeTokens>
|
||||
: { }),
|
||||
tagColours: normaliseThemeTagColours (
|
||||
(
|
||||
theme.tokens
|
||||
&& typeof theme.tokens === 'object'
|
||||
&& 'tagColours' in theme.tokens
|
||||
)
|
||||
? (theme.tokens as { tagColours?: Partial<ThemeTagColours> }).tagColours
|
||||
: theme.tagColours as Partial<ThemeTagColours> | undefined,
|
||||
defaultThemeTagColoursFor (baseTheme),
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,10 +490,13 @@ export const getClientCustomThemes = (): Record<string, CustomClientTheme> => {
|
||||
name: themeCopyName (baseTheme),
|
||||
builtin: false,
|
||||
baseTheme,
|
||||
tagColours: normaliseThemeTagColours (
|
||||
legacyTagColours,
|
||||
defaultThemeTagColoursFor (baseTheme),
|
||||
),
|
||||
tokens: {
|
||||
...(baseTheme === 'dark' ? DARK_THEME_TOKENS : LIGHT_THEME_TOKENS),
|
||||
tagColours: normaliseThemeTagColours (
|
||||
legacyTagColours,
|
||||
defaultThemeTagColoursFor (baseTheme),
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -477,7 +565,7 @@ export const deriveUserThemeModeFromSelection = (
|
||||
|
||||
export const createCustomThemeFromBase = (
|
||||
baseTheme: BuiltinThemeId,
|
||||
tagColours?: ThemeTagColours,
|
||||
tokens?: ThemeTokens,
|
||||
): CustomClientTheme => {
|
||||
const id = `custom:${ crypto.randomUUID () }` as ThemeId
|
||||
return {
|
||||
@@ -485,7 +573,9 @@ export const createCustomThemeFromBase = (
|
||||
name: themeCopyName (baseTheme),
|
||||
builtin: false,
|
||||
baseTheme,
|
||||
tagColours: tagColours ?? { ...defaultThemeTagColoursFor (baseTheme) },
|
||||
tokens: tokens ?? {
|
||||
...(baseTheme === 'dark' ? DARK_THEME_TOKENS : LIGHT_THEME_TOKENS),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +585,7 @@ export const getClientThemeTagColours = (
|
||||
customThemes: Record<string, CustomClientTheme> = getClientCustomThemes (),
|
||||
): ThemeTagColours => {
|
||||
return {
|
||||
...getResolvedThemeFromSelection (activeThemeId, customThemes).tagColours,
|
||||
...getResolvedThemeFromSelection (activeThemeId, customThemes).tokens.tagColours,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,7 +621,10 @@ export const setClientThemeTagColours = (
|
||||
...customThemes,
|
||||
[activeThemeId]: {
|
||||
...customThemes[activeThemeId],
|
||||
tagColours,
|
||||
tokens: {
|
||||
...customThemes[activeThemeId].tokens,
|
||||
tagColours,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
@@ -561,13 +654,41 @@ export const applyThemeTagColours = (tagColours: ThemeTagColours): void => {
|
||||
}
|
||||
|
||||
|
||||
export const applyThemeTokens = (tokens: ThemeTokens): void => {
|
||||
const root = document.documentElement
|
||||
|
||||
root.style.setProperty ('--background', tokens.background)
|
||||
root.style.setProperty ('--foreground', tokens.foreground)
|
||||
root.style.setProperty ('--card', tokens.card)
|
||||
root.style.setProperty ('--card-foreground', tokens.cardForeground)
|
||||
root.style.setProperty ('--popover', tokens.popover)
|
||||
root.style.setProperty ('--popover-foreground', tokens.popoverForeground)
|
||||
root.style.setProperty ('--primary', tokens.primary)
|
||||
root.style.setProperty ('--primary-foreground', tokens.primaryForeground)
|
||||
root.style.setProperty ('--secondary', tokens.secondary)
|
||||
root.style.setProperty ('--secondary-foreground', tokens.secondaryForeground)
|
||||
root.style.setProperty ('--muted', tokens.muted)
|
||||
root.style.setProperty ('--muted-foreground', tokens.mutedForeground)
|
||||
root.style.setProperty ('--accent', tokens.accent)
|
||||
root.style.setProperty ('--accent-foreground', tokens.accentForeground)
|
||||
root.style.setProperty ('--destructive', tokens.destructive)
|
||||
root.style.setProperty ('--destructive-foreground', tokens.destructiveForeground)
|
||||
root.style.setProperty ('--border', tokens.border)
|
||||
root.style.setProperty ('--input', tokens.input)
|
||||
root.style.setProperty ('--ring', tokens.ring)
|
||||
root.style.setProperty ('--theme-link', tokens.link)
|
||||
|
||||
applyThemeTagColours (tokens.tagColours)
|
||||
}
|
||||
|
||||
|
||||
export const applyThemeSelection = (
|
||||
activeThemeId: ActiveThemeId,
|
||||
customThemes: Record<string, CustomClientTheme>,
|
||||
): void => {
|
||||
const theme = getResolvedThemeFromSelection (activeThemeId, customThemes)
|
||||
applyThemeMode (theme.baseTheme)
|
||||
applyThemeTagColours (theme.tagColours)
|
||||
applyThemeTokens (theme.tokens)
|
||||
}
|
||||
|
||||
|
||||
|
||||
新しい課題から参照
ユーザをブロックする