(mode: ThemeMode)
| 738 | } |
| 739 | |
| 740 | const pickMode = (mode: ThemeMode): void => { |
| 741 | if (mode === 'auto') { |
| 742 | setTheme({ id: themeId, family: themeFamily, mode: 'auto' }) |
| 743 | return |
| 744 | } |
| 745 | // A custom theme keeps its single id (`custom-<slug>`) and just changes the |
| 746 | // mode — clamped to what the theme supports (a dark-only theme ignores a |
| 747 | // "light" pick). Built-in families fall through to the variant logic below. |
| 748 | if (themeFamily === 'custom') { |
| 749 | const slug = customThemeSlugFromId(themeId) |
| 750 | const theme = slug ? customThemes.find((t) => t.slug === slug) : null |
| 751 | if (theme && customThemeSupportsMode(theme, mode)) { |
| 752 | setTheme({ id: `custom-${theme.slug}`, family: 'custom', mode }) |
| 753 | } |
| 754 | return |
| 755 | } |
| 756 | // Flip to the mode-equivalent variant in the same family. For |
| 757 | // Gruvbox we also try to preserve the user's chosen contrast. |
| 758 | const currentVariant = THEMES.find((t) => t.id === themeId)?.variant |
| 759 | const candidate = |
| 760 | THEMES.find( |
| 761 | (t) => |
| 762 | t.family === themeFamily && |
| 763 | t.mode === mode && |
| 764 | t.variant === currentVariant |
| 765 | ) ?? THEMES.find((t) => t.family === themeFamily && t.mode === mode) |
| 766 | if (candidate) setTheme({ id: candidate.id, family: themeFamily, mode }) |
| 767 | } |
| 768 | |
| 769 | const pickVariant = (id: string): void => { |
| 770 | const t = THEMES.find((x) => x.id === id) |
no test coverage detected