Skip to content

Commit 1655209

Browse files
himerusclaude
andcommitted
feat: add fix suggestions for dark mode theme issues
Extends suggest_fix to handle mixed-token-hardcoded and dark-mode-shadow-invisible issues from the enhanced theme checker. Both generate var()-based suggestions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c1e5f29 commit 1655209

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'helixir': patch
3+
---
4+
5+
Add auto-fix suggestions for mixed-token-hardcoded and dark-mode-shadow-invisible theme issues

packages/core/src/handlers/suggest-fix.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,39 @@ function fixThemeCompat(input: SuggestFixInput): FixSuggestion {
289289
return {
290290
original,
291291
suggestion: `background: var(${bgToken}); color: var(${fgToken});`,
292-
explanation: `Light-on-light or dark-on-dark color pairs create contrast issues. Use semantic token pairs (surface + on-surface) that maintain readable contrast across themes.`,
292+
explanation:
293+
`Light-on-light or dark-on-dark color pairs create contrast issues. ` +
294+
`Use semantic token pairs (surface + on-surface) that maintain readable contrast across themes.`,
295+
severity: 'warning',
296+
};
297+
}
298+
299+
if (input.issue === 'mixed-token-hardcoded') {
300+
const propMatch = original.match(/([a-z-]+)\s*:\s*([^;]+)/i);
301+
if (propMatch) {
302+
const [, prop, value] = propMatch;
303+
const token = suggestTokenForProperty(prop ?? 'color', tokenPrefix);
304+
return {
305+
original,
306+
suggestion: `${prop}: var(${token}, ${value?.trim()});`,
307+
explanation:
308+
`One property uses a design token while the paired property is hardcoded. ` +
309+
`When the theme switches, the token adapts but the hardcoded value stays — ` +
310+
`breaking the color pairing. Use tokens for both.`,
311+
severity: 'warning',
312+
};
313+
}
314+
}
315+
316+
if (input.issue === 'dark-mode-shadow-invisible') {
317+
const shadowToken = tokenPrefix ? `${tokenPrefix}-shadow-md` : '--shadow-md';
318+
return {
319+
original,
320+
suggestion: `box-shadow: var(${shadowToken});`,
321+
explanation:
322+
`Very low opacity shadows (alpha <= 0.1) are invisible on dark backgrounds. ` +
323+
`Use a design token that adapts shadow intensity per theme, ` +
324+
`or increase the opacity for dark mode.`,
293325
severity: 'warning',
294326
};
295327
}

tests/handlers/suggest-fix.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,38 @@ describe('suggestFix — library-agnostic tokens', () => {
358358
expect(result.suggestion).not.toContain('--sl-');
359359
});
360360

361+
it('fixes mixed-token-hardcoded by wrapping in var()', () => {
362+
const result = suggestFix({
363+
type: 'theme-compat',
364+
issue: 'mixed-token-hardcoded',
365+
original: 'color: #333333;',
366+
});
367+
expect(result.suggestion).toContain('var(');
368+
expect(result.explanation).toContain('token');
369+
expect(result.severity).toBe('warning');
370+
});
371+
372+
it('fixes dark-mode-shadow-invisible with token', () => {
373+
const result = suggestFix({
374+
type: 'theme-compat',
375+
issue: 'dark-mode-shadow-invisible',
376+
original: 'box-shadow: 0 2px 8px rgba(0,0,0,0.05);',
377+
});
378+
expect(result.suggestion).toContain('var(');
379+
expect(result.suggestion).toContain('shadow');
380+
expect(result.severity).toBe('warning');
381+
});
382+
383+
it('uses tokenPrefix in dark-mode-shadow-invisible fix', () => {
384+
const result = suggestFix({
385+
type: 'theme-compat',
386+
issue: 'dark-mode-shadow-invisible',
387+
original: 'box-shadow: 0 2px 8px rgba(0,0,0,0.05);',
388+
tokenPrefix: '--hx-',
389+
});
390+
expect(result.suggestion).toContain('--hx-');
391+
});
392+
361393
it('generates property-appropriate token names from prefix', () => {
362394
const result = suggestFix({
363395
type: 'token-fallback',

0 commit comments

Comments
 (0)