fix(persons): use semantic color tokens in PersonTypeSelector for dark mode
Replaces hardcoded brand-navy/brand-sand/white classes with semantic tokens (bg-primary/text-primary-fg, bg-surface/text-ink, border-line, ring-focus-ring) so the segmented control adapts correctly in dark mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -37,9 +37,9 @@ function select(type: PersonType) {
|
||||
aria-checked={selected === type}
|
||||
tabindex={selected === type ? 0 : -1}
|
||||
onclick={() => select(type)}
|
||||
class="min-h-[48px] cursor-pointer rounded-sm border px-3 py-2 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none {selected === type
|
||||
? 'border-brand-navy bg-brand-navy text-white'
|
||||
: 'border-brand-sand bg-white text-brand-navy hover:border-brand-navy/50'}"
|
||||
class="min-h-[48px] cursor-pointer rounded-sm border px-3 py-2 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:outline-none {selected === type
|
||||
? 'border-primary bg-primary text-primary-fg'
|
||||
: 'border-line bg-surface text-ink hover:border-primary/50'}"
|
||||
>
|
||||
{labels[type]()}
|
||||
</button>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { describe, it, expect, afterEach } from 'vitest';
|
||||
import { cleanup, render } from 'vitest-browser-svelte';
|
||||
|
||||
import PersonTypeSelector from './PersonTypeSelector.svelte';
|
||||
|
||||
afterEach(() => cleanup());
|
||||
|
||||
describe('PersonTypeSelector', () => {
|
||||
it('selected button uses semantic bg-primary and text-primary-fg classes', () => {
|
||||
const { container } = render(PersonTypeSelector, { value: 'PERSON' });
|
||||
const buttons = container.querySelectorAll('[role="radio"]');
|
||||
const selected = Array.from(buttons).find((b) => b.getAttribute('aria-checked') === 'true');
|
||||
expect(selected).not.toBeNull();
|
||||
expect(selected!.className).toContain('bg-primary');
|
||||
expect(selected!.className).toContain('text-primary-fg');
|
||||
});
|
||||
|
||||
it('unselected buttons use semantic bg-surface, text-ink, border-line classes', () => {
|
||||
const { container } = render(PersonTypeSelector, { value: 'PERSON' });
|
||||
const buttons = container.querySelectorAll('[role="radio"]');
|
||||
const unselected = Array.from(buttons).filter((b) => b.getAttribute('aria-checked') !== 'true');
|
||||
expect(unselected.length).toBeGreaterThan(0);
|
||||
for (const btn of unselected) {
|
||||
expect(btn.className).toContain('bg-surface');
|
||||
expect(btn.className).toContain('text-ink');
|
||||
expect(btn.className).toContain('border-line');
|
||||
}
|
||||
});
|
||||
|
||||
it('focus ring uses semantic ring-focus-ring class', () => {
|
||||
const { container } = render(PersonTypeSelector, { value: 'PERSON' });
|
||||
const buttons = container.querySelectorAll('[role="radio"]');
|
||||
for (const btn of buttons) {
|
||||
expect(btn.className).toContain('ring-focus-ring');
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user