iter(g145): 滑块支持刻度标注
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
import { effect, h } from '@ui-arch/frame';
|
||||
import type { SliderProps } from './types.js';
|
||||
|
||||
/*** 滑块:原生 range 承载交互与键盘,value 信号双向绑定;轨道配色走 accent-color 令牌 ***/
|
||||
/*** 滑块:原生 range 承载交互与键盘,value 信号双向绑定;marks 在轨道下方标出刻度文案 ***/
|
||||
export function slider(props: SliderProps): HTMLElement {
|
||||
const value = props.value; // 必需信号:组件不持有数值,一律委托调用方
|
||||
const min = props.min ?? 0; // 与 input 的缺省保持一致,供刻度换算百分比
|
||||
const max = props.max ?? 100;
|
||||
const input = h('input', {
|
||||
type: 'range',
|
||||
class: 'ua-slider-input',
|
||||
min: props.min ?? 0,
|
||||
max: props.max ?? 100,
|
||||
min,
|
||||
max,
|
||||
step: props.step ?? 1,
|
||||
disabled: props.disabled, // 布尔或信号禁用,h() 直接透传
|
||||
}) as HTMLInputElement;
|
||||
@@ -23,10 +25,19 @@ export function slider(props: SliderProps): HTMLElement {
|
||||
if (input.value !== next) input.value = next; // 外部赋值同步滑块位置(等值不重写,避免打断拖动)
|
||||
});
|
||||
|
||||
// 刻度:按值算百分比定位,纯装饰不进读屏(数值本身由原生 input 播报)
|
||||
const marks = props.marks?.length
|
||||
? h('div', { class: 'ua-slider-marks', 'aria-hidden': 'true' },
|
||||
...props.marks.map((mark) => h('span', {
|
||||
class: 'ua-slider-mark',
|
||||
style: `left:${((mark.value - min) / (max - min || 1)) * 100}%`, // 分母兜底,避免 min=max 时除零
|
||||
}, mark.label ?? String(mark.value))))
|
||||
: null;
|
||||
|
||||
return h(
|
||||
'div',
|
||||
{ class: 'ua-slider' },
|
||||
input,
|
||||
h('div', { class: 'ua-slider-track' }, input, marks), // 轨道包一层:刻度只跟滑块对齐,不影响右侧数值
|
||||
props.showValue === false ? null : h('span', { class: 'ua-slider-value' }, () => String(value())),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -181,6 +181,7 @@ export interface SliderProps {
|
||||
step?: number; // 步长;缺省 1
|
||||
disabled?: boolean | Signal<boolean>; // 禁用态:布尔直接置位,传信号则动态同步
|
||||
showValue?: boolean; // 是否右侧显示当前值;缺省 true
|
||||
marks?: { value: number; label?: string }[]; // 刻度标注:按值定位在轨道下方,label 缺省显示数值;纯装饰不进读屏
|
||||
onChange?: (value: number) => void; // 拖动回调
|
||||
}
|
||||
|
||||
|
||||
@@ -439,6 +439,11 @@
|
||||
"d": "是否右侧显示当前值;缺省 true",
|
||||
"df": "true"
|
||||
},
|
||||
{
|
||||
"n": "marks",
|
||||
"t": "{ value: number; label?: string }[]",
|
||||
"d": "刻度标注:按值定位在轨道下方,label 缺省显示数值;纯装饰不进读屏(数值由原生 input 播报)"
|
||||
},
|
||||
{
|
||||
"n": "onChange",
|
||||
"t": "(value: number) => void",
|
||||
@@ -452,7 +457,8 @@
|
||||
"用 min / max / step 限定范围与粒度,如 step: 5 只取 5 的倍数",
|
||||
"拖动或按 ←→ 键改变值:原生 range 自带键盘与触屏交互,无需额外处理",
|
||||
"只想看拖动条不显示数字时传 showValue: false;需要自定义展示可自行读 signal",
|
||||
"禁用场景传 disabled(布尔或信号),置灰且不可拖"
|
||||
"禁用场景传 disabled(布尔或信号),置灰且不可拖",
|
||||
"需要在轨道下方标刻度(如 0 / 50 / 100 的档位含义)传 marks:[{ value, label }],按 min-max 换算百分比定位,容器宽度变化时自动跟随"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4461,3 +4461,24 @@ h5.ua-type-title { font-size: var(--ua-font-size-md); }
|
||||
color: var(--ua-color-text);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* —— 滑块轨道与刻度:轨道包一层,刻度按百分比定位在下方 —— */
|
||||
.ua-slider-track {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
.ua-slider-marks {
|
||||
position: relative;
|
||||
height: 14px;
|
||||
}
|
||||
.ua-slider-mark {
|
||||
position: absolute;
|
||||
transform: translateX(-50%);
|
||||
color: var(--ua-color-text-muted);
|
||||
font-size: var(--ua-font-size-sm);
|
||||
line-height: 14px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user