( family: ThemeFamily, prefersDark: boolean, /** Optional current theme id. When provided we try to keep the user's * variant choice (e.g. "medium" for gruvbox) across system mode flips * instead of always snapping to the canonical default. */ currentThemeId?: string )
| 131 | * the active family that feels most like its canonical default. |
| 132 | */ |
| 133 | export function resolveAuto( |
| 134 | family: ThemeFamily, |
| 135 | prefersDark: boolean, |
| 136 | /** Optional current theme id. When provided we try to keep the user's |
| 137 | * variant choice (e.g. "medium" for gruvbox) across system mode flips |
| 138 | * instead of always snapping to the canonical default. */ |
| 139 | currentThemeId?: string |
| 140 | ): string { |
| 141 | const targetMode: 'light' | 'dark' = prefersDark ? 'dark' : 'light' |
| 142 | |
| 143 | // Carry the variant across modes when possible: a user who picked |
| 144 | // Gruvbox · Hard in light mode should stay on Hard when the system |
| 145 | // flips to dark instead of being yanked back to Medium. |
| 146 | if (currentThemeId) { |
| 147 | const current = THEMES.find((t) => t.id === currentThemeId) |
| 148 | if (current && current.family === family && current.variant) { |
| 149 | const sameVariant = THEMES.find( |
| 150 | (t) => |
| 151 | t.family === family && t.mode === targetMode && t.variant === current.variant |
| 152 | ) |
| 153 | if (sameVariant) return sameVariant.id |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | if (family === 'apple') { |
| 158 | return targetMode === 'dark' ? 'apple-dark' : 'apple-light' |
| 159 | } |
| 160 | if (family === 'gruvbox') { |
| 161 | return targetMode === 'dark' ? 'dark-medium' : 'light-medium' |
| 162 | } |
| 163 | if (family === 'catppuccin') { |
| 164 | return targetMode === 'dark' ? 'catppuccin-mocha' : 'catppuccin-latte' |
| 165 | } |
| 166 | if (family === 'solarized') { |
| 167 | return targetMode === 'dark' ? 'solarized-dark' : 'solarized-light' |
| 168 | } |
| 169 | if (family === 'one') { |
| 170 | return targetMode === 'dark' ? 'one-dark' : 'one-light' |
| 171 | } |
| 172 | if (family === 'nord') { |
| 173 | return targetMode === 'dark' ? 'nord-dark' : 'nord-light' |
| 174 | } |
| 175 | if (family === 'tokyo-night') { |
| 176 | return targetMode === 'dark' ? 'tokyo-night-storm' : 'tokyo-night-day' |
| 177 | } |
| 178 | if (family === 'kanagawa') { |
| 179 | return targetMode === 'dark' ? 'kanagawa-wave' : 'kanagawa-lotus' |
| 180 | } |
| 181 | if (family === 'black-metal') { |
| 182 | return targetMode === 'dark' ? 'black-metal' : 'black-metal-day' |
| 183 | } |
| 184 | if (family === 'rose-pine') { |
| 185 | return targetMode === 'dark' ? 'rose-pine-main' : 'rose-pine-dawn' |
| 186 | } |
| 187 | // github |
| 188 | return targetMode === 'dark' ? 'github-dark' : 'github-light' |
| 189 | } |
no outgoing calls
no test coverage detected