mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-08 08:36:37 +08:00
feat(a11y): 设置页无障碍审计并修复开关可访问名称
axe 结构性规则扩展到设置页(安全 Tab + 其他 Tab): - security-tab 8 个 Switch/SelectTrigger 补可访问名称(Label htmlFor 关联 + aria-label) - other-tab / auth-source-modal 各 1 个未命名 Switch 补 aria-label - 新增 2 个 axe 测试,vitest 126 全绿 - 翻译键 loginCaptchaEnabled 加入 fragments(admin.zh-CN/en)
This commit is contained in:
@@ -180,6 +180,7 @@ export function AuthSourceModal({
|
||||
</div>
|
||||
</div>
|
||||
<Switch
|
||||
aria-label={t('enableAuthSource')}
|
||||
checked={form.is_active}
|
||||
onCheckedChange={(checked) =>
|
||||
setForm((prev) => ({ ...prev, is_active: checked }))
|
||||
|
||||
@@ -314,6 +314,7 @@ export function OtherTab({ configs }: OtherTabProps) {
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<Switch
|
||||
aria-label={tNav(item.labelKey)}
|
||||
checked={checked}
|
||||
disabled={
|
||||
isReadOnly || updateMenuConfigMutation.isPending
|
||||
|
||||
@@ -329,15 +329,19 @@ export function SecurityTab({ configs, systemConfigsQuery }: SecurityTabProps) {
|
||||
<div className='space-y-1'>
|
||||
<div className='flex items-center gap-2'>
|
||||
{Icon && <Icon className='size-4 text-primary' />}
|
||||
<span className='font-medium text-sm text-foreground'>
|
||||
<Label
|
||||
htmlFor={item.key}
|
||||
className='font-medium text-sm text-foreground'
|
||||
>
|
||||
{t(item.titleKey)}
|
||||
</span>
|
||||
</Label>
|
||||
</div>
|
||||
<p className='text-xs text-muted-foreground leading-relaxed pr-2'>
|
||||
{t(item.descKey)}
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
id={item.key}
|
||||
checked={checked}
|
||||
disabled={updateConfigMutation.isPending}
|
||||
onCheckedChange={(value) => handleToggle(item.key, value)}
|
||||
@@ -366,7 +370,10 @@ export function SecurityTab({ configs, systemConfigsQuery }: SecurityTabProps) {
|
||||
disabled={updateTTLMutation.isPending}
|
||||
onValueChange={handleTTLChange}
|
||||
>
|
||||
<SelectTrigger className='w-[180px] bg-card border-dashed text-xs h-8'>
|
||||
<SelectTrigger
|
||||
className='w-[180px] bg-card border-dashed text-xs h-8'
|
||||
aria-label={t('loginSessionTTL')}
|
||||
>
|
||||
<SelectValue placeholder={t('selectRetentionTime')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
@@ -554,15 +561,22 @@ export function SecurityTab({ configs, systemConfigsQuery }: SecurityTabProps) {
|
||||
onCheckedChange={(checked) =>
|
||||
handleToggle('cap_login_enabled', checked)
|
||||
}
|
||||
aria-label={t('loginCaptchaEnabled')}
|
||||
/>
|
||||
</CardHeader>
|
||||
<CardContent className='pt-6'>
|
||||
{/* 自动开始计算 Switch */}
|
||||
<div className='flex items-center justify-between rounded-xl border border-dashed p-4 bg-card mb-4'>
|
||||
<div className='space-y-0.5'>
|
||||
<p className='text-sm font-semibold'>{t('autoStartSolving')}</p>
|
||||
<Label htmlFor='cap_auto_solve' className='text-sm font-semibold'>
|
||||
{t('autoStartSolving')}
|
||||
</Label>
|
||||
</div>
|
||||
<Switch checked={capAutoSolve} onCheckedChange={setCapAutoSolve} />
|
||||
<Switch
|
||||
id='cap_auto_solve'
|
||||
checked={capAutoSolve}
|
||||
onCheckedChange={setCapAutoSolve}
|
||||
/>
|
||||
</div>
|
||||
<form onSubmit={handleCapSave} className='space-y-6'>
|
||||
<div className='grid grid-cols-1 sm:grid-cols-2 gap-4'>
|
||||
|
||||
Reference in New Issue
Block a user