iter(g223): 非档值按最近档对齐

This commit is contained in:
HIsheR
2026-10-26 20:04:27 +08:00
parent 063b6cb72b
commit 126da0583a
3 changed files with 18 additions and 7 deletions
+14 -5
View File
@@ -20,6 +20,13 @@ export function timePicker(props: TimePickerProps): HTMLElement {
const minutes = Array.from({ length: Math.ceil(60 / step) }, (_, i) => pad(i * step)); // 00..55(按步长取)
const picked = () => { const [hh = '', mm = ''] = value().split(':'); return { hh, mm }; }; // 拆分当前值
/*** 分钟档对齐:值不在步长档上(如 09:07 + 15 分钟档)时取最近档,作为高亮与滚动锚点 ***/
const nearestMinute = (mm: string): string => {
const n = Number(mm);
if (!mm || Number.isNaN(n)) return ''; // 卫语句:没值或脏值不参与对齐
return minutes[Math.min(minutes.length - 1, Math.round(n / step))] ?? '';
};
/*** 写回时间:两段都补齐后调用回调;值未变时不重复派发(选时与选分各写一次) ***/
const commit = (hh: string, mm: string): void => {
const next = `${hh}:${mm}`;
@@ -51,12 +58,13 @@ export function timePicker(props: TimePickerProps): HTMLElement {
/*** 造一列时间格:点击写回,激活格加 is-active 供样式与初始滚动定位 ***/
const column = (label: string, list: string[], isHour: boolean) => {
const activeText = () => (isHour ? picked().hh : nearestMinute(picked().mm)); // 本列该高亮的文案:分列按最近档对齐
const cells = list.map((text) =>
h('button', {
type: 'button',
class: () => `ua-timepicker-cell${(isHour ? picked().hh : picked().mm) === text ? ' is-active' : ''}`,
class: () => `ua-timepicker-cell${activeText() === text ? ' is-active' : ''}`,
role: 'option',
'aria-selected': () => String((isHour ? picked().hh : picked().mm) === text),
'aria-selected': () => String(activeText() === text),
onClick: () => {
const cur = picked();
if (isHour) return commit(text, cur.mm || minutes[0]); // 先选时:分默认落到首个步长值,值立即可用
@@ -129,9 +137,10 @@ export function timePicker(props: TimePickerProps): HTMLElement {
if (open()) {
releaseEsc ??= pushOverlay(() => { open(false); trigger.focus(); }); // 入 Esc 栈:与弹窗/抽屉共用逐层关闭
requestAnimationFrame(() => {
const now = new Date(); // 未选值时的锚点:打开就停在「此刻」附近,省得从 00:00 开始翻
reveal(hourCol.col, hourCol.buttons, now.getHours());
reveal(minuteCol.col, minuteCol.buttons, Math.floor(now.getMinutes() / step));
const now = new Date(); // 无值时的锚点:打开就停在「此刻」附近,省得从 00:00 开始翻
const { hh, mm } = picked();
reveal(hourCol.col, hourCol.buttons, hh ? Number(hh) : now.getHours()); // 有值先滚到值上
reveal(minuteCol.col, minuteCol.buttons, mm ? minutes.indexOf(nearestMinute(mm)) : Math.floor(now.getMinutes() / step));
}); // 布局就绪后再量
} else {
releaseEsc?.();