前端: 按 Web Interface Guidelines 全面重做
组件: - Button: transition-all→明确属性列表, touch-action, aria-busy - Input: name/spellcheck/inputmode/aria-invalid/aria-describedby, focus-visible ring, label 关联, 暴露 focus() 供错误定位, required 标记 - Modal: Escape 关闭 + focus trap + 焦点归还, overscroll-behavior: contain, aria-labelledby, body 滚动锁, touch-action - 新增 Toast(aria-live polite) + pinia toast store 页面: - ConsoleLayout: skip link, <main> 语义标签, aside/nav aria-label, aria-current, 装饰 SVG aria-hidden, Intl 金额, translate=no 品牌/代码 - Dashboard: Intl.NumberFormat, 骨架屏 loading, aria-live 错误 - Keys: 字段级错误+焦点定位, toast 反馈(复制/吊销), name 属性 - Usage: select 加 label, 分页/筛选同步 URL(可深链), Intl 日期/金额, 表格 caption - Login/Register: 字段级校验+错误定位, spellcheck=false, inputmode, autocomplete - Landing: router-link 替换 href, aria-hidden, text-balance, scroll-mt - index.html: theme-color + color-scheme 验证: playwright 22 项断言全过, WCAG AA 对比度 9 组全过, 零控制台错误
This commit is contained in:
@@ -6,16 +6,22 @@ withDefaults(
|
||||
type?: 'button' | 'submit'
|
||||
loading?: boolean
|
||||
disabled?: boolean
|
||||
ariaLabel?: string
|
||||
}>(),
|
||||
{ variant: 'primary', size: 'md', type: 'button', loading: false, disabled: false },
|
||||
)
|
||||
|
||||
defineEmits<{ (e: 'click', ev: MouseEvent): void }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
:type="type"
|
||||
:disabled="disabled || loading"
|
||||
class="inline-flex items-center justify-center gap-2 font-medium transition-all select-none
|
||||
:aria-label="ariaLabel"
|
||||
:aria-busy="loading || undefined"
|
||||
class="inline-flex touch-manipulation items-center justify-center gap-2 font-medium select-none
|
||||
transition-[background-color,border-color,color,transform,opacity] duration-150
|
||||
active:scale-[0.98] disabled:opacity-50 disabled:pointer-events-none cursor-pointer"
|
||||
:class="[
|
||||
size === 'sm' ? 'h-8 px-3 text-[13px] rounded-md' : 'h-10 px-4 text-sm rounded-md',
|
||||
@@ -24,8 +30,13 @@ withDefaults(
|
||||
variant === 'ghost' && 'text-paper-500 hover:text-paper-100 hover:bg-ink-800',
|
||||
variant === 'danger' && 'bg-ember-500/90 text-white hover:bg-ember-400',
|
||||
]"
|
||||
@click="$emit('click', $event)"
|
||||
>
|
||||
<span v-if="loading" class="h-3.5 w-3.5 animate-spin rounded-full border-2 border-current border-t-transparent" />
|
||||
<span
|
||||
v-if="loading"
|
||||
class="h-3.5 w-3.5 animate-spin rounded-full border-2 border-current border-t-transparent"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<slot />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user