mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(desktop): stop the checkbox painting the check and dash at once
codicon.css styles glyphs through `.codicon[class*='codicon-']`, a two-class selector that outranks Tailwind's single-class `hidden`. The indicator stacks a check and a dash and hides one per state, so neither was ever hidden and the box rendered both glyphs side by side, spilling past its 16px bounds in every state including unchecked. Use the important modifier on both display utilities so state, not stylesheet order, decides which glyph shows.
This commit is contained in:
parent
71a86101ab
commit
f790d5a6ce
2 changed files with 66 additions and 2 deletions
62
apps/desktop/src/components/ui/checkbox.test.tsx
Normal file
62
apps/desktop/src/components/ui/checkbox.test.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { cleanup, render } from '@testing-library/react'
|
||||
import { afterEach, beforeAll, describe, expect, it } from 'vitest'
|
||||
|
||||
import { Checkbox } from './checkbox'
|
||||
|
||||
/**
|
||||
* The indicator stacks both glyphs and hides one with a utility class, so the
|
||||
* cascade — not the markup — decides what the user sees. codicon.css sets
|
||||
* `display: inline-block` on `.codicon[class*='codicon-']`, which outranks a
|
||||
* single-class utility and paints the check and the dash at the same time.
|
||||
* That specificity race is the real contract, so the test carries both
|
||||
* stylesheets rather than asserting on class strings. Tailwind's nested output
|
||||
* is flattened to the equivalent descendant selector because jsdom does not
|
||||
* implement CSS nesting.
|
||||
*/
|
||||
const CODICON_CSS = `.codicon[class*='codicon-'] { display: inline-block; }`
|
||||
|
||||
const TAILWIND_CSS = `
|
||||
.hidden\\! { display: none !important; }
|
||||
:where(.group)[data-state="checked"] .group-data-\\[state\\=checked\\]\\:block\\! {
|
||||
display: block !important;
|
||||
}
|
||||
:where(.group)[data-state="indeterminate"] .group-data-\\[state\\=indeterminate\\]\\:block\\! {
|
||||
display: block !important;
|
||||
}
|
||||
`
|
||||
|
||||
function shownGlyphs(container: HTMLElement) {
|
||||
return [...container.querySelectorAll<HTMLElement>('.codicon')]
|
||||
.filter(glyph => getComputedStyle(glyph).display !== 'none')
|
||||
.map(glyph => (glyph.classList.contains('codicon-check') ? 'check' : 'dash'))
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
// eslint-disable-next-line no-restricted-globals -- the cascade is the assertion; it needs a real stylesheet
|
||||
const style = document.createElement('style')
|
||||
style.textContent = `${CODICON_CSS}\n${TAILWIND_CSS}`
|
||||
// eslint-disable-next-line no-restricted-globals -- see above
|
||||
document.head.append(style)
|
||||
})
|
||||
|
||||
afterEach(cleanup)
|
||||
|
||||
describe('Checkbox', () => {
|
||||
it('paints the check alone when checked', () => {
|
||||
const { container } = render(<Checkbox checked />)
|
||||
|
||||
expect(shownGlyphs(container)).toEqual(['check'])
|
||||
})
|
||||
|
||||
it('paints the dash alone when indeterminate', () => {
|
||||
const { container } = render(<Checkbox checked="indeterminate" />)
|
||||
|
||||
expect(shownGlyphs(container)).toEqual(['dash'])
|
||||
})
|
||||
|
||||
it('paints no glyph when unchecked', () => {
|
||||
const { container } = render(<Checkbox checked={false} />)
|
||||
|
||||
expect(shownGlyphs(container)).toEqual([])
|
||||
})
|
||||
})
|
||||
|
|
@ -18,8 +18,10 @@ function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxP
|
|||
className="flex items-center justify-center text-current"
|
||||
data-slot="checkbox-indicator"
|
||||
>
|
||||
<Codicon className="hidden group-data-[state=checked]:block" name="check" size="0.875rem" />
|
||||
<Codicon className="hidden group-data-[state=indeterminate]:block" name="dash" size="0.875rem" />
|
||||
{/* codicon.css sets `display: inline-block` at higher specificity than a bare
|
||||
`hidden`, so both glyphs paint at once without the important modifier. */}
|
||||
<Codicon className="hidden! group-data-[state=checked]:block!" name="check" size="0.875rem" />
|
||||
<Codicon className="hidden! group-data-[state=indeterminate]:block!" name="dash" size="0.875rem" />
|
||||
</CheckboxPrimitive.Indicator>
|
||||
</CheckboxPrimitive.Root>
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue