feat(ui): 自绘 Dropdown 替代原生 select(外观设置·临时主题)
全应用唯一的原生 select 换为自绘下拉组件:按钮对齐 .input 样式, 展开层沿用应用菜单语言(选中 --accent-weak、悬停 --hover),复用 useDismiss 点别处/Esc 关闭,支持上下键选行。tests/dropdown 1 例。
This commit is contained in:
40
tests/dropdown.test.tsx
Normal file
40
tests/dropdown.test.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
// 自绘下拉回归:展开/选中/点别处关闭(替代原生 select)。
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import { act } from 'react-dom/test-utils'
|
||||
import { Dropdown } from '../src/components/Dropdown'
|
||||
|
||||
const OPTIONS = [
|
||||
{ value: '', label: '跟随全局主题' },
|
||||
{ value: 'github', label: 'GitHub' },
|
||||
{ value: 'notion', label: 'Notion' },
|
||||
]
|
||||
|
||||
describe('Dropdown', () => {
|
||||
it('展开列出选项且标出选中项;点击选项回调并关闭;点别处关闭', async () => {
|
||||
const container = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
const root = createRoot(container)
|
||||
const onChange = vi.fn()
|
||||
await act(async () => {
|
||||
root.render(<Dropdown value="github" options={OPTIONS} onChange={onChange} />)
|
||||
})
|
||||
const button = container.querySelector('.dropdown-button') as HTMLButtonElement
|
||||
expect(button.textContent).toContain('GitHub')
|
||||
await act(async () => { button.dispatchEvent(new MouseEvent('click', { bubbles: true })) })
|
||||
const menu = container.querySelector('.dropdown-menu')
|
||||
expect(menu).not.toBeNull()
|
||||
expect(menu?.querySelector('button.selected')?.textContent).toBe('GitHub')
|
||||
const notion = [...menu!.querySelectorAll('button')].find((b) => b.textContent === 'Notion')
|
||||
await act(async () => { notion?.dispatchEvent(new MouseEvent('click', { bubbles: true })) })
|
||||
expect(onChange).toHaveBeenCalledWith('notion')
|
||||
expect(container.querySelector('.dropdown-menu')).toBeNull()
|
||||
// 再次展开,点别处关闭
|
||||
await act(async () => { button.dispatchEvent(new MouseEvent('click', { bubbles: true })) })
|
||||
expect(container.querySelector('.dropdown-menu')).not.toBeNull()
|
||||
await act(async () => { document.body.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })) })
|
||||
expect(container.querySelector('.dropdown-menu')).toBeNull()
|
||||
await act(async () => { root.unmount() })
|
||||
container.remove()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user