iter(g349): listbox 与 radiogroup 容器补可访问名

This commit is contained in:
HIsheR
2026-10-27 02:34:06 +08:00
parent 0a6beb898b
commit a0e4eeb479
6 changed files with 33 additions and 6 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ export function autoComplete(props: AutoCompleteProps): HTMLElement {
},
}) as HTMLInputElement;
const list = h('ul', { class: 'ua-autocomplete-list', role: 'listbox', id: `ua-ac-${(seq += 1)}` }) as HTMLElement;
const list = h('ul', { class: 'ua-autocomplete-list', role: 'listbox', 'aria-label': '输入建议', id: `ua-ac-${(seq += 1)}` }) as HTMLElement;
input.setAttribute('aria-controls', list.id);
const pop = h('div', { class: () => `ua-autocomplete-pop${open() ? ' ua-open' : ''}${place() === 'top' ? ' is-flip' : ''}` }, list) as HTMLElement;
const root = h('div', { class: 'ua-autocomplete' }, input, pop) as HTMLElement;
+1 -1
View File
@@ -33,7 +33,7 @@ export function mentions(props: MentionsProps): HTMLElement {
'aria-expanded': 'false',
}) as HTMLTextAreaElement;
input.value = value();
const list = h('div', { class: 'ua-mentions-pop', role: 'listbox', id: uid });
const list = h('div', { class: 'ua-mentions-pop', role: 'listbox', 'aria-label': '提及建议', id: uid });
const wrap = h('div', { class: 'ua-mentions' }, input, list);
// 候选:空过滤词给全量,否则按名字 / 关键词做包含匹配
+1 -1
View File
@@ -65,7 +65,7 @@ export function multiSelect(props: MultiSelectProps): HTMLElement {
},
}) as HTMLInputElement;
box.append(tagWrap, input); // 标签区在前、输入框在后,横向排布
const list = h('ul', { class: 'ua-multiselect-list', role: 'listbox', 'aria-multiselectable': 'true' }) as HTMLElement;
const list = h('ul', { class: 'ua-multiselect-list', role: 'listbox', 'aria-label': '选项列表', 'aria-multiselectable': 'true' }) as HTMLElement;
const pop = h('div', { class: () => `ua-multiselect-pop${open() ? ' ua-open' : ''}${place() === 'top' ? ' is-flip' : ''}` }, list) as HTMLElement;
const clearBtn = h('button', { type: 'button', class: 'ua-select-clear', 'aria-label': '清空所选', hidden: true, onClick: (e: Event) => { e.stopPropagation(); update([]); input.focus(); } }, '×') as HTMLElement; // 复用 select 清空钮样式;阻止冒泡免得清完又展开
const root = h('div', { class: () => `ua-multiselect${open() ? ' ua-open' : ''}` }, box, props.clearable ? clearBtn : null, pop) as HTMLElement;
+1 -1
View File
@@ -7,7 +7,7 @@ export function segmented(props: SegmentedProps): HTMLElement {
// —— 状态集中声明 ——
const buttons: HTMLButtonElement[] = []; // 分段按钮,顺序与 options 一致
const thumb = h('span', { class: 'ua-seg-thumb', 'aria-hidden': 'true' }); // 滑块:仅装饰,不参与可访问性树
const root = h('div', { class: `ua-segmented ua-segmented-${props.size ?? 'md'}`, role: 'radiogroup' }, thumb);
const root = h('div', { class: `ua-segmented ua-segmented-${props.size ?? 'md'}`, role: 'radiogroup', 'aria-label': '分段选择' }, thumb);
/*** 整组禁用判定:布尔直接取,信号在此读取以纳入 effect 依赖 ***/
const groupOff = (): boolean => (typeof props.disabled === 'function' ? props.disabled() : props.disabled === true);
+1 -1
View File
@@ -87,7 +87,7 @@ export function select(props: SelectProps): HTMLElement {
const blank = h('div', { class: 'ua-select-blank' }, '无匹配选项'); // 过滤空结果提示
const pop = h(
'div',
{ class: () => `ua-select-pop${open() ? ' ua-open' : ''}${place() === 'top' ? ' is-flip' : ''}`, role: 'listbox' },
{ class: () => `ua-select-pop${open() ? ' ua-open' : ''}${place() === 'top' ? ' is-flip' : ''}`, role: 'listbox', 'aria-label': '选项列表' },
props.searchable ? search : null,
...nodes,
blank,