iter(g74): 弹窗与抽屉补 aria-labelledby 标题关联

This commit is contained in:
HIsheR
2026-10-26 12:43:32 +08:00
parent 182158bfd7
commit 640c2860b9
2 changed files with 10 additions and 3 deletions
+5 -1
View File
@@ -2,8 +2,11 @@ import { effect, h } from '@ui-arch/frame';
import type { DrawerProps } from './types.js';
import { lockScroll, pushOverlay } from './overlay.js';
let seq = 0; // 实例序号:给标题生成唯一 id,供 aria-labelledby 关联
/*** 抽屉:open 信号驱动侧滑面板,点遮罩 / × / Esc 关闭;Tab 焦点陷阱 + 关闭归还焦点,与 modal 的分工是不打断主视图、可从侧边保留上下文 ***/
export function drawer(props: DrawerProps, ...children: unknown[]): HTMLElement {
const titleId = `ua-drawer-title-${++seq}`; // 标题 id:抽屉的可访问名
const close = (): void => {
if (!props.open()) return; // 卫语句:已关闭不重复触发回调
props.open(false);
@@ -21,9 +24,10 @@ export function drawer(props: DrawerProps, ...children: unknown[]): HTMLElement
class: `ua-drawer ua-drawer-${props.placement ?? 'right'}`,
style: `width:${props.width ?? 320}px`,
role: 'dialog',
'aria-labelledby': titleId,
'aria-hidden': () => String(!props.open()),
},
h('div', { class: 'ua-drawer-head' }, h('h3', { class: 'ua-drawer-title' }, props.title), h('button', { class: 'ua-drawer-close', 'aria-label': '关闭抽屉', onClick: close }, '×')),
h('div', { class: 'ua-drawer-head' }, h('h3', { class: 'ua-drawer-title', id: titleId }, props.title), h('button', { class: 'ua-drawer-close', 'aria-label': '关闭抽屉', onClick: close }, '×')),
h('div', { class: 'ua-drawer-body' }, ...children),
props.footer ? h('div', { class: 'ua-drawer-foot' }, props.footer) : null,
);
+5 -2
View File
@@ -2,8 +2,11 @@ import { effect, h } from '@ui-arch/frame';
import type { ModalProps } from './types.js';
import { lockScroll, pushOverlay } from './overlay.js';
let seq = 0; // 实例序号:给标题生成唯一 id,供 aria-labelledby 关联
/*** 弹窗:open 信号驱动显隐,点遮罩、× 或 Esc 触发 onClose;Tab 焦点陷阱 + 关闭归还焦点 ***/
export function modal(props: ModalProps, ...children: unknown[]): HTMLElement {
const titleId = `ua-modal-title-${++seq}`; // 标题 id:对话框的可访问名
const close = () => {
if (!props.open()) return; // 卫语句:已关闭不重复触发回调
props.open(false); // 写回信号触发隐藏
@@ -17,8 +20,8 @@ export function modal(props: ModalProps, ...children: unknown[]): HTMLElement {
});
const box = h(
'div',
{ class: `ua-modal ua-modal-${props.size ?? 'md'}`, role: 'dialog', 'aria-modal': 'true' }, // 对话框语义,供读屏识别
h('div', { class: 'ua-modal-head' }, h('h3', { class: 'ua-modal-title' }, props.title), h('button', { type: 'button', class: 'ua-modal-close', 'aria-label': '关闭弹窗', onClick: close }, '×')),
{ class: `ua-modal ua-modal-${props.size ?? 'md'}`, role: 'dialog', 'aria-modal': 'true', 'aria-labelledby': titleId }, // 对话框语义 + 标题关联
h('div', { class: 'ua-modal-head' }, h('h3', { class: 'ua-modal-title', id: titleId }, props.title), h('button', { type: 'button', class: 'ua-modal-close', 'aria-label': '关闭弹窗', onClick: close }, '×')),
h('div', { class: 'ua-modal-body' }, ...children),
props.footer ? h('div', { class: 'ua-modal-foot' }, props.footer) : null, // 底部操作区:右对齐,仅传了才渲染
);