iter(g110): 下拉选择支持清空

This commit is contained in:
HIsheR
2026-10-26 14:03:19 +08:00
parent 9abadf0c4d
commit e042143468
9 changed files with 84 additions and 10 deletions
+19 -1
View File
@@ -24,6 +24,13 @@ export function select(props: SelectProps): HTMLElement {
props.onChange?.(v);
};
/*** 清空:可选筛选项回到「未选」态,信号与回调同源写回 ***/
const clear = () => {
if (!value()) return; // 卫语句:本来就没选,不重复派发回调
value('');
props.onChange?.('');
};
// —— 触发器 ——
const trigger = h(
'button',
@@ -72,7 +79,17 @@ export function select(props: SelectProps): HTMLElement {
blank,
);
const root = h('div', { class: () => `ua-select${open() ? ' ua-open' : ''}` }, trigger, pop); // 根带开合类,供箭头旋转
// —— 清空按钮:clearable 且有值时出现,绝对定位压在触发器右缘(与箭头错开)——
const clearBtn = h('button', {
type: 'button',
class: 'ua-select-clear',
'aria-label': '清空选择',
tabindex: '-1', // 不进 Tab 序:清空是鼠标 / 触屏便利,键盘用 Delete / Backspace
onClick: () => clear(),
}, '×');
effect(() => { clearBtn.hidden = !props.clearable || !value(); }); // 无值或未开启时藏起来(不进 Tab 序,隐藏即失效)
const root = h('div', { class: () => `ua-select${open() ? ' ua-open' : ''}` }, trigger, props.clearable ? clearBtn : null, pop); // 根带开合类,供箭头旋转
// —— 键入快跳缓冲(非 searchable 时生效,逻辑与 menu 一致)——
let typed = ''; // 最近键入的字母串,用于前缀匹配
@@ -90,6 +107,7 @@ export function select(props: SelectProps): HTMLElement {
root.addEventListener('keydown', (e: KeyboardEvent) => {
const list = visibleIdx();
if (props.clearable && !open() && (e.key === 'Backspace' || e.key === 'Delete')) { e.preventDefault(); clear(); return; } // 键盘等价:收起态下 Delete / Backspace 清空
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
e.preventDefault(); // 阻止页面滚动
if (!open()) { open(true); options[list[0] ?? 0]?.focus(); return; } // 未展开:展开并聚焦首个可见选项
+1
View File
@@ -108,6 +108,7 @@ export interface SelectProps {
placeholder?: string; // 未选中时的占位项文案
disabled?: boolean | Signal<boolean>; // 禁用态:布尔直接置位,传信号则动态同步
searchable?: boolean; // 弹层顶部带搜索框,按标签包含匹配过滤;缺省 false
clearable?: boolean; // 有值时触发器右缘出现清空按钮(删除 / Backspace 亦可清);缺省 false
onChange?: (value: string) => void; // 变更回调
}