mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-14 04:01:35 +00:00
Client feature plugins never import one another's components, so ui-primitives is their only channel for sharing one. Nothing told an author to look there first, and the package offered nothing to look at: its README named six source files against forty-plus exports. Add Tag (read-only capsule badge, eight tones) and Switch (36x20 toggle with a required accessible name), extend StateDotState with idle for a tracked subject with no activity, and move ui-agent-preset, ui-settings-plugins, and ui-settings-plugin-inventory onto them. The plugin inventory's conditional tag referenced --dsw-alias-state-warning-primary, which does not exist, so both themes had been painting its hardcoded #b45309 fallback. State the reuse rule as the first step of the new-component checklist, and give the README a component catalog so the rule has something to check. The rule is guidance, not a gate: a package may still write its own control, and the Agent Note records the five that stay local.
55 lines
2.4 KiB
TypeScript
55 lines
2.4 KiB
TypeScript
// @vitest-environment jsdom
|
|
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
|
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
import { Switch } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
|
|
afterEach(cleanup)
|
|
|
|
describe('Switch', () => {
|
|
it('exposes its state and its caller-owned name to assistive technology', () => {
|
|
render(<Switch checked label="Subagent model selection" onChange={() => {}} />)
|
|
const control = screen.getByRole('switch', { name: 'Subagent model selection' })
|
|
expect(control.getAttribute('aria-checked')).toBe('true')
|
|
})
|
|
|
|
it('reports the state the click asks for, not the state it has', () => {
|
|
const onChange = vi.fn()
|
|
const { rerender } = render(<Switch checked={false} label="Toggle" onChange={onChange} />)
|
|
fireEvent.click(screen.getByRole('switch'))
|
|
expect(onChange).toHaveBeenCalledWith(true)
|
|
|
|
onChange.mockClear()
|
|
rerender(<Switch checked label="Toggle" onChange={onChange} />)
|
|
fireEvent.click(screen.getByRole('switch'))
|
|
expect(onChange).toHaveBeenCalledWith(false)
|
|
})
|
|
|
|
it('stays silent while disabled', () => {
|
|
const onChange = vi.fn()
|
|
render(<Switch checked={false} disabled label="Toggle" onChange={onChange} />)
|
|
const control = screen.getByRole('switch')
|
|
expect((control as HTMLButtonElement).disabled).toBe(true)
|
|
fireEvent.click(control)
|
|
expect(onChange).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('carries a lock reason as the hover title when the owner names one', () => {
|
|
render(<Switch checked={false} disabled label="Toggle" title="Managed by policy" onChange={() => {}} />)
|
|
expect(screen.getByRole('switch').getAttribute('title')).toBe('Managed by policy')
|
|
})
|
|
|
|
it('never submits a surrounding form', () => {
|
|
const onSubmit = vi.fn((event: { preventDefault: () => void }) => { event.preventDefault() })
|
|
render(<form onSubmit={onSubmit}><Switch checked={false} label="Toggle" onChange={() => {}} /></form>)
|
|
fireEvent.click(screen.getByRole('switch'))
|
|
expect(onSubmit).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('keeps a caller class alongside its own so a render site can place it', () => {
|
|
render(<Switch checked={false} className="placed" label="Toggle" onChange={() => {}} />)
|
|
const control = screen.getByRole('switch')
|
|
expect(control.classList.contains('placed')).toBe(true)
|
|
expect(control.classList.length).toBeGreaterThan(1)
|
|
})
|
|
})
|