feat: 新增组件库

This commit is contained in:
Wxw-Gu
2026-08-18 15:29:13 +08:00
parent f93dc539e4
commit 89d388f661
39 changed files with 2630 additions and 141 deletions
@@ -0,0 +1,34 @@
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { describe, expect, it, vi } from 'vitest'
import { AppearancePage } from '../../src/renderer/src/features/settings/pages/AppearancePage'
describe('AppearancePage UI pilot', () => {
it('uses the shared radio and switch controls without changing settings semantics', async () => {
const user = userEvent.setup()
const onNotice = vi.fn()
const onAppearanceChange = vi.fn()
const settings = {
appearanceTheme: 'system' as const,
compactMode: false,
showStartupProgress: true
}
const api = {
getSettings: vi.fn(async () => ({ settings })),
setSettings: vi.fn(async (patch: Partial<typeof settings>) => ({
settings: Object.assign(settings, patch)
}))
}
Object.defineProperty(window, 'api', { configurable: true, value: api })
render(<AppearancePage onNotice={onNotice} onAppearanceChange={onAppearanceChange} />)
expect(await screen.findByRole('heading', { name: '外观与行为' })).toBeVisible()
await user.click(screen.getByRole('radio', { name: /深色/ }))
await user.click(screen.getByRole('switch', { name: '紧凑布局' }))
expect(api.setSettings).toHaveBeenCalledWith({ appearanceTheme: 'dark' })
expect(api.setSettings).toHaveBeenCalledWith({ compactMode: true })
expect(onNotice).toHaveBeenCalledWith('外观设置已保存')
})
})
@@ -0,0 +1,83 @@
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { describe, expect, it } from 'vitest'
import {
Button,
Dialog,
DialogContent,
DialogTitle,
DialogTrigger,
Input,
Popover,
PopoverContent,
PopoverTrigger,
ToastProvider,
TooltipProvider,
useToast
} from '../../src/renderer/src/components/ui'
function ToastDemo(): React.ReactElement {
const { toast } = useToast()
return (
<Button onClick={() => toast({ title: '已保存', description: '设置已更新' })}></Button>
)
}
describe('TraceMemo UI infrastructure', () => {
it('restores focus after a dialog is closed with Escape', async () => {
const user = userEvent.setup()
render(
<Dialog>
<DialogTrigger asChild>
<Button></Button>
</DialogTrigger>
<DialogContent>
<DialogTitle></DialogTitle>
<Input aria-label="测试输入" />
</DialogContent>
</Dialog>
)
const trigger = screen.getByRole('button', { name: '打开对话框' })
await user.click(trigger)
expect(screen.getByRole('dialog', { name: '测试对话框' })).toBeVisible()
await user.keyboard('{Escape}')
expect(screen.queryByRole('dialog', { name: '测试对话框' })).not.toBeInTheDocument()
expect(trigger).toHaveFocus()
})
it('closes a popover when the user clicks outside', async () => {
const user = userEvent.setup()
render(
<Popover>
<PopoverTrigger asChild>
<Button></Button>
</PopoverTrigger>
<PopoverContent>
<p></p>
</PopoverContent>
</Popover>
)
await user.click(screen.getByRole('button', { name: '打开菜单' }))
expect(screen.getByText('菜单内容')).toBeVisible()
await user.click(document.body)
expect(screen.queryByText('菜单内容')).not.toBeInTheDocument()
})
it('renders toast notifications through the shared provider', async () => {
const user = userEvent.setup()
render(
<TooltipProvider>
<ToastProvider>
<ToastDemo />
</ToastProvider>
</TooltipProvider>
)
await user.click(screen.getByRole('button', { name: '显示通知' }))
expect(screen.getByText('已保存')).toBeVisible()
expect(screen.getByText('设置已更新')).toBeVisible()
})
})