mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
Merge pull request #74610 from NousResearch/bb/checkbox-indeterminate
fix(desktop): stop the checkbox painting the check and dash at once
This commit is contained in:
commit
382282d5a0
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