iter(g216): 时间选择支持清空
This commit is contained in:
@@ -28,6 +28,14 @@ export function timePicker(props: TimePickerProps): HTMLElement {
|
||||
props.onChange?.(next);
|
||||
};
|
||||
|
||||
/*** 清空:回到「未选」态,收起弹层并写回空串(与 select / multiSelect 的清空语义一致) ***/
|
||||
const clear = () => {
|
||||
if (!value()) return; // 卫语句:本来就没选,不重复派发回调
|
||||
value('');
|
||||
props.onChange?.('');
|
||||
open(false);
|
||||
};
|
||||
|
||||
/*** 列内聚焦导航:↑↓ 环形移动、Home/End 直达首末(列内按钮顺序即时间顺序) ***/
|
||||
const navigate = (col: HTMLElement, cells: HTMLButtonElement[]) => {
|
||||
col.addEventListener('keydown', (e: KeyboardEvent) => {
|
||||
@@ -82,13 +90,23 @@ export function timePicker(props: TimePickerProps): HTMLElement {
|
||||
h('span', { class: 'ua-timepicker-arrow', 'aria-hidden': 'true' }, '▾'),
|
||||
);
|
||||
|
||||
// —— 清空按钮:clearable 且有值时出现,压在触发器右缘(与箭头错开)——
|
||||
const clearable = props.clearable ?? false; // 缺省不带清空:没选的场景多,按钮会白占位置
|
||||
const clearBtn = h('button', {
|
||||
type: 'button',
|
||||
class: 'ua-timepicker-clear',
|
||||
'aria-label': '清空时间',
|
||||
tabindex: '-1', // 不进 Tab 序:清空是鼠标 / 触屏便利,键盘用 Delete / Backspace
|
||||
onClick: () => clear(),
|
||||
}, '×') as HTMLElement;
|
||||
|
||||
const pop = h(
|
||||
'div',
|
||||
{ class: () => `ua-timepicker-pop${open() ? ' ua-open' : ''}${place() === 'top' ? ' is-flip' : ''}`, role: 'dialog', 'aria-label': '选择时间' },
|
||||
hourCol.col,
|
||||
minuteCol.col,
|
||||
);
|
||||
const root = h('div', { class: () => `ua-timepicker${open() ? ' is-open' : ''}` }, trigger, pop);
|
||||
const root = h('div', { class: () => `ua-timepicker${open() ? ' is-open' : ''}${props.clearable && value() ? ' has-clear' : ''}` }, trigger, clearable ? clearBtn : null, pop);
|
||||
|
||||
/*** 把激活格滚到列中部:列是独立滚动容器,直接算 scrollTop 不惊动页面 ***/
|
||||
const reveal = (col: HTMLElement, cells: HTMLButtonElement[]) => {
|
||||
@@ -98,6 +116,13 @@ export function timePicker(props: TimePickerProps): HTMLElement {
|
||||
col.scrollTop = Math.max(0, target);
|
||||
};
|
||||
|
||||
effect(() => { clearBtn.hidden = !clearable || !value(); }); // 无值或未开启时藏起来(hidden 一并移出点击区)
|
||||
root.addEventListener('keydown', (e: KeyboardEvent) => {
|
||||
if (open() || !clearable) return; // 卫语句:展开时按键归列内导航,未开启清空则不接管
|
||||
if (e.key !== 'Backspace' && e.key !== 'Delete') return; // 卫语句:只接管这两个键
|
||||
e.preventDefault();
|
||||
clear(); // 键盘等价:不必伸手去点 ×
|
||||
});
|
||||
bindOutside(root, open, () => open(false)); // 点外部收起:仅展开期间挂监听
|
||||
effect(() => {
|
||||
if (open()) {
|
||||
|
||||
Reference in New Issue
Block a user