From 3036f265052cb2877722ffd15e85447f61051958 Mon Sep 17 00:00:00 2001 From: HIsheR Date: Mon, 26 Oct 2026 22:21:04 +0800 Subject: [PATCH] =?UTF-8?q?iter(g258):=20select=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8F=AF=E8=AE=BF=E9=97=AE=E5=90=8D=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ua/index.json | 10 ++++++++-- llms-full.txt | 4 +++- packages/skin/ui/src/select.ts | 1 + packages/skin/ui/src/tablePager.ts | 1 + packages/skin/ui/src/types.ts | 1 + packages/skin/ui/ua.manifest.json | 8 +++++++- 6 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.ua/index.json b/.ua/index.json index cf0f9e4..cae9760 100644 --- a/.ua/index.json +++ b/.ua/index.json @@ -1,6 +1,6 @@ { "$schema": "ui-arch-registry-index/0.1", - "generatedAt": "2026-10-26T14:19:01.143Z", + "generatedAt": "2026-10-26T14:20:50.687Z", "repoRoot": ".", "packages": [ { @@ -770,6 +770,11 @@ "t": "boolean | Signal", "d": "禁用态:布尔直接置位,传信号则动态同步;禁用时触发器置灰且不展开弹层" }, + { + "n": "ariaLabel", + "t": "string", + "d": "触发器的可访问名:没有可见 label 关联时(如表格分页条的「每页条数」)给读屏一个名字;缺省不落 aria-label" + }, { "n": "onChange", "t": "(value: string) => void", @@ -791,7 +796,8 @@ "弹层展开时按 Esc 只收起下拉并回焦触发器;若下拉在弹窗/抽屉内,再按一次 Esc 才关外层(逐层关闭)", "searchable: true 时打开即聚焦搜索框,输入实时过滤;↑↓/Home/End 只在可见项间移动,无命中显示「无匹配选项」", "需要允许「不选」的筛选项就开 clearable:有值时右缘出现 ×,点它把值写成空串并回调 onChange(''),键盘在收起态按 Delete / Backspace 等价", - "候选多时给选项加 group:相邻同组合成一段、组首插灰色小标题(段间有分隔线),过滤后整组无命中时标题一起隐藏——搜索路径与键盘 ↑↓ 仍只走真实选项" + "候选多时给选项加 group:相邻同组合成一段、组首插灰色小标题(段间有分隔线),过滤后整组无命中时标题一起隐藏——搜索路径与键盘 ↑↓ 仍只走真实选项", + "没有可见 label 的场合(工具栏、分页条)传 ariaLabel:触发器只显示当前值文案,读屏需要「这个下拉在选什么" ] }, { diff --git a/llms-full.txt b/llms-full.txt index c0897a6..9075c84 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1,6 +1,6 @@ # @ui-arch 组件库 Agent 文档(无图形版) -> 自动生成于 2026-10-26T14:19:01.143Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 +> 自动生成于 2026-10-26T14:20:50.687Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 > 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。 ## 快速上手 @@ -296,6 +296,7 @@ const night = signal(true); switchButton({ label: '夜间模式', checked: night - searchable:boolean —— 弹层顶部带搜索框,按标签包含匹配过滤;缺省 false - clearable:boolean —— 有值时触发器右缘出现清空按钮(收起态按 Delete / Backspace 也能清);缺省 false,用于「可选筛选项」 - disabled:boolean | Signal —— 禁用态:布尔直接置位,传信号则动态同步;禁用时触发器置灰且不展开弹层 +- ariaLabel:string —— 触发器的可访问名:没有可见 label 关联时(如表格分页条的「每页条数」)给读屏一个名字;缺省不落 aria-label - onChange(回调):(value: string) => void —— 选中回调 - size:'sm' | 'md' | 'lg' —— 高度档位:sm 紧凑 / md 默认 / lg 大触控目标,走 --ua-control-h-* 三档;缺省 md @@ -315,6 +316,7 @@ const city = signal(''); select({ options: [{ value: 'bj', label: '北京' }], v 6. searchable: true 时打开即聚焦搜索框,输入实时过滤;↑↓/Home/End 只在可见项间移动,无命中显示「无匹配选项」 7. 需要允许「不选」的筛选项就开 clearable:有值时右缘出现 ×,点它把值写成空串并回调 onChange(''),键盘在收起态按 Delete / Backspace 等价 8. 候选多时给选项加 group:相邻同组合成一段、组首插灰色小标题(段间有分隔线),过滤后整组无命中时标题一起隐藏——搜索路径与键盘 ↑↓ 仍只走真实选项 +9. 没有可见 label 的场合(工具栏、分页条)传 ariaLabel:触发器只显示当前值文案,读屏需要「这个下拉在选什么 现场演示:apps/docs/demo.html#sec-form diff --git a/packages/skin/ui/src/select.ts b/packages/skin/ui/src/select.ts index d66b106..77467cb 100644 --- a/packages/skin/ui/src/select.ts +++ b/packages/skin/ui/src/select.ts @@ -39,6 +39,7 @@ export function select(props: SelectProps): HTMLElement { class: `ua-select-trigger${props.size && props.size !== 'md' ? ` is-${props.size}` : ''}`, 'aria-haspopup': 'listbox', 'aria-expanded': () => String(open()), + 'aria-label': props.ariaLabel ?? null, // 无可见 label 时由调用方给名字,null 让 h() 不落属性 disabled: props.disabled, // 布尔或信号禁用,h() 直接透传(原生 button 拦截点击) onClick: () => open(!open()), }, diff --git a/packages/skin/ui/src/tablePager.ts b/packages/skin/ui/src/tablePager.ts index a61c2f6..b6718ad 100644 --- a/packages/skin/ui/src/tablePager.ts +++ b/packages/skin/ui/src/tablePager.ts @@ -20,6 +20,7 @@ export function tablePager(props: TablePagerProps): HTMLElement { const sizeSelect = select({ size: 'sm', options: list.map((n) => ({ value: String(n), label: `${n} 条/页` })), + ariaLabel: '每页条数', // 触发器只显示「5 条/页」这类量词,读屏需要主语 value: sizeSig, disabled: () => props.loading(), // 加载中不改页大小:避免与在途结果竞争 onChange: (v) => props.onPageSize(Number(v)), diff --git a/packages/skin/ui/src/types.ts b/packages/skin/ui/src/types.ts index 6bcd534..0a8cffb 100644 --- a/packages/skin/ui/src/types.ts +++ b/packages/skin/ui/src/types.ts @@ -119,6 +119,7 @@ export interface SelectProps { disabled?: boolean | Signal; // 禁用态:布尔直接置位,传信号则动态同步 searchable?: boolean; // 弹层顶部带搜索框,按标签包含匹配过滤;缺省 false clearable?: boolean; // 有值时触发器右缘出现清空按钮(删除 / Backspace 亦可清);缺省 false + ariaLabel?: string; // 触发器的可访问名:无可见 labelfor 关联时(如表格分页条的「每页条数」)用它给读屏一个名字 onChange?: (value: string) => void; // 变更回调 } diff --git a/packages/skin/ui/ua.manifest.json b/packages/skin/ui/ua.manifest.json index 47046ac..915fe59 100644 --- a/packages/skin/ui/ua.manifest.json +++ b/packages/skin/ui/ua.manifest.json @@ -641,6 +641,11 @@ "t": "boolean | Signal", "d": "禁用态:布尔直接置位,传信号则动态同步;禁用时触发器置灰且不展开弹层" }, + { + "n": "ariaLabel", + "t": "string", + "d": "触发器的可访问名:没有可见 label 关联时(如表格分页条的「每页条数」)给读屏一个名字;缺省不落 aria-label" + }, { "n": "onChange", "t": "(value: string) => void", @@ -662,7 +667,8 @@ "弹层展开时按 Esc 只收起下拉并回焦触发器;若下拉在弹窗/抽屉内,再按一次 Esc 才关外层(逐层关闭)", "searchable: true 时打开即聚焦搜索框,输入实时过滤;↑↓/Home/End 只在可见项间移动,无命中显示「无匹配选项」", "需要允许「不选」的筛选项就开 clearable:有值时右缘出现 ×,点它把值写成空串并回调 onChange(''),键盘在收起态按 Delete / Backspace 等价", - "候选多时给选项加 group:相邻同组合成一段、组首插灰色小标题(段间有分隔线),过滤后整组无命中时标题一起隐藏——搜索路径与键盘 ↑↓ 仍只走真实选项" + "候选多时给选项加 group:相邻同组合成一段、组首插灰色小标题(段间有分隔线),过滤后整组无命中时标题一起隐藏——搜索路径与键盘 ↑↓ 仍只走真实选项", + "没有可见 label 的场合(工具栏、分页条)传 ariaLabel:触发器只显示当前值文案,读屏需要「这个下拉在选什么" ] }, {