The session row menu's Archive action carried ic_ds_download_outline_16, a download tray that reads as "save to disk" rather than "put away". Swap it for the design's archive glyph — a lidded box with a label slot — added to the ic_ds_* set as IconArchiveOutline20. The glyph is native 20, the first of that size in the set, so the menu's 16px icon slot asks for it explicitly. The figma export's 0.11px stroke ring around the box contour is dropped: it restates the same contour in the same ink, which currentColor already carries.
61 lines
2.7 KiB
TypeScript
61 lines
2.7 KiB
TypeScript
// @vitest-environment jsdom
|
|
import { cleanup, render } from '@testing-library/react'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import * as primitives from '@deepseek-ai/dsh-client-ui-primitives'
|
|
import { IconApiOutline14, IconArchiveOutline20, IconFolderClose16, IconSendOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
|
|
afterEach(cleanup)
|
|
|
|
// Icon components all share the IconProps signature; the barrel also exports
|
|
// non-icon atoms (different props shapes), so filter by prefix BEFORE typing.
|
|
const icons = Object.fromEntries(
|
|
Object.entries(primitives).filter(([name]) => name.startsWith('Icon')),
|
|
) as Record<string, (p: primitives.IconProps) => React.JSX.Element>
|
|
const iconNames = Object.keys(icons)
|
|
|
|
describe('ic_ds_ icon set', () => {
|
|
it('exports the full P-I set (45 deepsuite + 15 figma extracts + the hand-authored sparkle)', () => {
|
|
expect(iconNames.length).toBe(61)
|
|
})
|
|
|
|
it.each(iconNames)('%s renders an svg with currentColor fills and no hardcoded palette', (name) => {
|
|
const Icon = icons[name]!
|
|
const { container } = render(<Icon />)
|
|
const svg = container.querySelector('svg')
|
|
expect(svg).not.toBeNull()
|
|
const markup = container.innerHTML
|
|
expect(markup).not.toMatch(/#[0-9a-fA-F]{3,8}"/)
|
|
expect(markup).toContain('currentColor')
|
|
})
|
|
|
|
it('size and className props land on the root svg', () => {
|
|
const { container } = render(<IconSendOutline16 size={20} className="x" />)
|
|
const svg = container.querySelector('svg')!
|
|
expect(svg.getAttribute('width')).toBe('20')
|
|
expect(svg.getAttribute('height')).toBe('20')
|
|
expect(svg.classList.contains('x')).toBe(true)
|
|
})
|
|
|
|
it('native defaults: 14-glyphs default 14, 16-glyphs default 16, 20-glyphs default 20', () => {
|
|
const api = render(<IconApiOutline14 />)
|
|
expect(api.container.querySelector('svg')!.getAttribute('width')).toBe('14')
|
|
const folder = render(<IconFolderClose16 />)
|
|
expect(folder.container.querySelector('svg')!.getAttribute('width')).toBe('16')
|
|
const archive = render(<IconArchiveOutline20 />)
|
|
expect(archive.container.querySelector('svg')!.getAttribute('width')).toBe('20')
|
|
})
|
|
})
|
|
|
|
describe('FishLogo', () => {
|
|
it('renders the fish path in currentColor at the native ratio', () => {
|
|
const { container } = render(<primitives.FishLogo />)
|
|
const svg = container.querySelector('svg')!
|
|
expect(svg.getAttribute('width')).toBe('24')
|
|
expect(Number(svg.getAttribute('height'))).toBeCloseTo(17.66, 1)
|
|
expect(svg.getAttribute('viewBox')).toBe('0 0 23.16 17.04')
|
|
expect(container.querySelectorAll('path')).toHaveLength(1)
|
|
expect(container.innerHTML).toContain('currentColor')
|
|
expect(container.innerHTML).not.toContain('M0 0L23.16')
|
|
})
|
|
})
|