iter(g126): 数字输入补 precision 小数位
This commit is contained in:
@@ -1364,6 +1364,14 @@
|
||||
"acceptance": "SwitchProps 新增 loading(布尔或信号):加载中锁定交互(disabled 同值语义)、滑块换成转圈(reduced-motion 静态化为实心环)、input 挂 aria-busy;与 disabled 同时生效且不双写竞争;文档参数表 / api 说明 / 手把手与 llms-full.txt 同步;npm run check 全绿",
|
||||
"notes": "自补:组件能力补齐;loading 接管时 disabled 不再走 h() 绑定,单一 effect 写入避免竞争",
|
||||
"status": "done"
|
||||
},
|
||||
{
|
||||
"id": "g126",
|
||||
"title": "数字输入补 precision 小数位",
|
||||
"motivation": "金额、比例、权重这类小数场景:step 0.1 步进会累积出 0.30000000000000004 这样的浮点尾差直接写进信号,显示位数也无法约束,调用方只能自己在 onChange 里 toFixed 再写回",
|
||||
"acceptance": "InputNumberProps 新增 precision(缺省不处理):写回与显示都按 toFixed(p) 归一(写回量化 + 输入框定长显示),步进浮点尾差消除;min/max 夹取语义不变;文档参数表 / api 说明 / 手把手与 llms-full.txt 同步;npm run check 全绿",
|
||||
"notes": "自补:组件能力补齐;量化收敛在 emit/sync 单点,不改夹取与连发逻辑",
|
||||
"status": "open"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+8
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "ui-arch-registry-index/0.1",
|
||||
"generatedAt": "2026-10-26T06:44:14.161Z",
|
||||
"generatedAt": "2026-10-26T06:49:03.720Z",
|
||||
"repoRoot": ".",
|
||||
"packages": [
|
||||
{
|
||||
@@ -144,7 +144,7 @@
|
||||
"exports": [
|
||||
"button(props):按钮,variant = primary | ghost | danger,disabled 支持布尔或信号禁用;type 缺省 button(表单内不隐式提交)",
|
||||
"textField(props):文本输入,value 信号双向绑定,disabled 支持布尔或信号,onInput 输入回调;prefix/suffix 可选渲染为输入框内侧附加块,clearable 开启后有值即显一键清空按钮,maxCount 设原生上限并实时显示字数",
|
||||
"inputNumber(props):数字输入,−/+ 按钮与键盘 ↑↓ 调节(长按连发步进),min/max/step 夹取;prefix/suffix 可选渲染为整组前后附加块",
|
||||
"inputNumber(props):数字输入,−/+ 按钮与键盘 ↑↓ 调节(长按连发步进),min/max/step 夹取,precision 小数位归一;prefix/suffix 可选渲染为整组前后附加块",
|
||||
"textarea(props):多行输入,value 信号双向绑定,disabled 支持布尔或信号,rows 控行数;prefix/suffix 可选渲染为上下附加块,maxCount 显示实时字数并设原生上限",
|
||||
"slider(props):滑块,value 信号双向绑定,min/max/step 可配,原生 range 承载键盘交互,右侧可显示当前值",
|
||||
"checkbox(props):复选框,checked 信号双向绑定,indeterminate 半选态(读屏播报 mixed),disabled 支持布尔或信号禁用",
|
||||
@@ -429,6 +429,11 @@
|
||||
"d": "步长;缺省 1",
|
||||
"df": "1"
|
||||
},
|
||||
{
|
||||
"n": "precision",
|
||||
"t": "number",
|
||||
"d": "小数位数:写回与显示都按 toFixed(p) 归一(消除步进浮点尾差,step 0.1 也干净);缺省不处理"
|
||||
},
|
||||
{
|
||||
"n": "disabled",
|
||||
"t": "boolean | Signal<boolean>",
|
||||
@@ -456,6 +461,7 @@
|
||||
"用 signal(1) 创建数字信号并传入 value 完成双向绑定",
|
||||
"点击 −/+ 按钮或在输入框聚焦时按 ↑↓ 以 step 调节;直接输入在失焦或回车时解析",
|
||||
"非法输入自动回滚为当前值;min/max 超界自动夹取,disabled 支持布尔或信号禁用",
|
||||
"金额、比例这类小数场景传 precision:值与显示都固定小数位,步进不再出现 0.30000000000000004",
|
||||
"需要图标、货币符、单位等前后缀时传 prefix/suffix(字符串或 DOM),控件会包进带边框的附加组,聚焦光环由组统一承载"
|
||||
]
|
||||
},
|
||||
|
||||
+5
-3
@@ -1,6 +1,6 @@
|
||||
# @ui-arch 组件库 Agent 文档(无图形版)
|
||||
|
||||
> 自动生成于 2026-10-26T06:44:14.161Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||
> 自动生成于 2026-10-26T06:49:03.720Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
||||
|
||||
## 快速上手
|
||||
@@ -137,6 +137,7 @@ const name = signal(''); const el = textField({ value: name, placeholder: '输
|
||||
- min:number —— 最小值;缺省无下限
|
||||
- max:number —— 最大值;缺省无上限
|
||||
- step(默认 1):number —— 步长;缺省 1
|
||||
- precision:number —— 小数位数:写回与显示都按 toFixed(p) 归一(消除步进浮点尾差,step 0.1 也干净);缺省不处理
|
||||
- disabled:boolean | Signal<boolean> —— 禁用态:布尔直接置位,传信号则动态同步
|
||||
- onChange(回调):(value: number) => void —— 值变化回调(已夹取到合法区间)
|
||||
- prefix:string | HTMLElement —— 前置附加块(textField/inputNumber 在输入框内侧前、textarea 在上方);缺省不渲染
|
||||
@@ -153,7 +154,8 @@ const qty = signal(1); const el = inputNumber({ value: qty, min: 1, max: 99, onC
|
||||
1. 用 signal(1) 创建数字信号并传入 value 完成双向绑定
|
||||
2. 点击 −/+ 按钮或在输入框聚焦时按 ↑↓ 以 step 调节;直接输入在失焦或回车时解析
|
||||
3. 非法输入自动回滚为当前值;min/max 超界自动夹取,disabled 支持布尔或信号禁用
|
||||
4. 需要图标、货币符、单位等前后缀时传 prefix/suffix(字符串或 DOM),控件会包进带边框的附加组,聚焦光环由组统一承载
|
||||
4. 金额、比例这类小数场景传 precision:值与显示都固定小数位,步进不再出现 0.30000000000000004
|
||||
5. 需要图标、货币符、单位等前后缀时传 prefix/suffix(字符串或 DOM),控件会包进带边框的附加组,聚焦光环由组统一承载
|
||||
|
||||
现场演示:apps/docs/demo.html#sec-inputnumber
|
||||
|
||||
@@ -1670,7 +1672,7 @@ API 速览:
|
||||
|
||||
- button(props):按钮,variant = primary | ghost | danger,disabled 支持布尔或信号禁用;type 缺省 button(表单内不隐式提交)
|
||||
- textField(props):文本输入,value 信号双向绑定,disabled 支持布尔或信号,onInput 输入回调;prefix/suffix 可选渲染为输入框内侧附加块,clearable 开启后有值即显一键清空按钮,maxCount 设原生上限并实时显示字数
|
||||
- inputNumber(props):数字输入,−/+ 按钮与键盘 ↑↓ 调节(长按连发步进),min/max/step 夹取;prefix/suffix 可选渲染为整组前后附加块
|
||||
- inputNumber(props):数字输入,−/+ 按钮与键盘 ↑↓ 调节(长按连发步进),min/max/step 夹取,precision 小数位归一;prefix/suffix 可选渲染为整组前后附加块
|
||||
- textarea(props):多行输入,value 信号双向绑定,disabled 支持布尔或信号,rows 控行数;prefix/suffix 可选渲染为上下附加块,maxCount 显示实时字数并设原生上限
|
||||
- slider(props):滑块,value 信号双向绑定,min/max/step 可配,原生 range 承载键盘交互,右侧可显示当前值
|
||||
- checkbox(props):复选框,checked 信号双向绑定,indeterminate 半选态(读屏播报 mixed),disabled 支持布尔或信号禁用
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
- API:
|
||||
- button(props):按钮,variant = primary | ghost | danger,disabled 支持布尔或信号禁用;type 缺省 button(表单内不隐式提交)
|
||||
- textField(props):文本输入,value 信号双向绑定,disabled 支持布尔或信号,onInput 输入回调;prefix/suffix 可选渲染为输入框内侧附加块,clearable 开启后有值即显一键清空按钮,maxCount 设原生上限并实时显示字数
|
||||
- inputNumber(props):数字输入,−/+ 按钮与键盘 ↑↓ 调节(长按连发步进),min/max/step 夹取;prefix/suffix 可选渲染为整组前后附加块
|
||||
- inputNumber(props):数字输入,−/+ 按钮与键盘 ↑↓ 调节(长按连发步进),min/max/step 夹取,precision 小数位归一;prefix/suffix 可选渲染为整组前后附加块
|
||||
- textarea(props):多行输入,value 信号双向绑定,disabled 支持布尔或信号,rows 控行数;prefix/suffix 可选渲染为上下附加块,maxCount 显示实时字数并设原生上限
|
||||
- slider(props):滑块,value 信号双向绑定,min/max/step 可配,原生 range 承载键盘交互,右侧可显示当前值
|
||||
- checkbox(props):复选框,checked 信号双向绑定,indeterminate 半选态(读屏播报 mixed),disabled 支持布尔或信号禁用
|
||||
|
||||
@@ -3,15 +3,16 @@ import { button } from './button.js';
|
||||
import { addonWrap } from './addons.js';
|
||||
import type { InputNumberProps } from './types.js';
|
||||
|
||||
/*** 数字输入:−/+ 按钮 + 输入框三段式,value 信号双向绑定,min/max/step 超界自动夹取,键盘 ↑↓ 调节,长按连发步进 ***/
|
||||
/*** 数字输入:−/+ 按钮 + 输入框三段式,value 信号双向绑定,min/max/step 超界自动夹取,precision 小数位归一,键盘 ↑↓ 调节,长按连发步进 ***/
|
||||
export function inputNumber(props: InputNumberProps): HTMLElement {
|
||||
const min = props.min ?? -Infinity; // 无下限缺省
|
||||
const max = props.max ?? Infinity; // 无上限缺省
|
||||
const step = props.step ?? 1; // 步长缺省 1
|
||||
const clamp = (v: number): number => Math.min(max, Math.max(min, v)); // 任何来源的值都夹回合法区间
|
||||
const emit = (v: number): void => { const n = clamp(v); props.value(n); if (props.onChange) props.onChange(n); }; // 写回信号并回调
|
||||
const quantize = (n: number): number => (props.precision === undefined ? n : Number(n.toFixed(props.precision))); // precision 归一(顺带消除步进浮点尾差)
|
||||
const emit = (v: number): void => { const n = quantize(clamp(v)); props.value(n); if (props.onChange) props.onChange(n); }; // 写回信号并回调
|
||||
const input = h('input', { class: 'ua-input ua-input-number-field', inputmode: 'decimal', disabled: props.disabled, 'aria-label': '数字输入' }) as HTMLInputElement;
|
||||
const sync = (): void => { const text = String(props.value()); if (input.value !== text) input.value = text; }; // 外部变化写回输入框
|
||||
const sync = (): void => { const text = props.precision === undefined ? String(props.value()) : props.value().toFixed(props.precision); if (input.value !== text) input.value = text; }; // 外部变化写回输入框(precision 定长显示)
|
||||
effect(sync);
|
||||
input.addEventListener('change', () => { const n = parseFloat(input.value); if (Number.isNaN(n)) sync(); else emit(n); }); // 非法输入回滚当前值
|
||||
input.addEventListener('keydown', (e: KeyboardEvent) => {
|
||||
|
||||
@@ -201,6 +201,7 @@ export interface InputNumberProps {
|
||||
min?: number; // 最小值;缺省无下限
|
||||
max?: number; // 最大值;缺省无上限
|
||||
step?: number; // 步长;缺省 1
|
||||
precision?: number; // 小数位数:写回与显示都按 toFixed(p) 归一(消除步进浮点尾差);缺省不处理
|
||||
disabled?: boolean | Signal<boolean>; // 禁用态:布尔直接置位,传信号则动态同步
|
||||
onChange?: (value: number) => void; // 值变化回调(已夹取到合法区间)
|
||||
prefix?: string | HTMLElement; // −/+ 按钮前的附加块(如货币符);缺省不渲染
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"exports": [
|
||||
"button(props):按钮,variant = primary | ghost | danger,disabled 支持布尔或信号禁用;type 缺省 button(表单内不隐式提交)",
|
||||
"textField(props):文本输入,value 信号双向绑定,disabled 支持布尔或信号,onInput 输入回调;prefix/suffix 可选渲染为输入框内侧附加块,clearable 开启后有值即显一键清空按钮,maxCount 设原生上限并实时显示字数",
|
||||
"inputNumber(props):数字输入,−/+ 按钮与键盘 ↑↓ 调节(长按连发步进),min/max/step 夹取;prefix/suffix 可选渲染为整组前后附加块",
|
||||
"inputNumber(props):数字输入,−/+ 按钮与键盘 ↑↓ 调节(长按连发步进),min/max/step 夹取,precision 小数位归一;prefix/suffix 可选渲染为整组前后附加块",
|
||||
"textarea(props):多行输入,value 信号双向绑定,disabled 支持布尔或信号,rows 控行数;prefix/suffix 可选渲染为上下附加块,maxCount 显示实时字数并设原生上限",
|
||||
"slider(props):滑块,value 信号双向绑定,min/max/step 可配,原生 range 承载键盘交互,右侧可显示当前值",
|
||||
"checkbox(props):复选框,checked 信号双向绑定,indeterminate 半选态(读屏播报 mixed),disabled 支持布尔或信号禁用",
|
||||
@@ -300,6 +300,11 @@
|
||||
"d": "步长;缺省 1",
|
||||
"df": "1"
|
||||
},
|
||||
{
|
||||
"n": "precision",
|
||||
"t": "number",
|
||||
"d": "小数位数:写回与显示都按 toFixed(p) 归一(消除步进浮点尾差,step 0.1 也干净);缺省不处理"
|
||||
},
|
||||
{
|
||||
"n": "disabled",
|
||||
"t": "boolean | Signal<boolean>",
|
||||
@@ -327,6 +332,7 @@
|
||||
"用 signal(1) 创建数字信号并传入 value 完成双向绑定",
|
||||
"点击 −/+ 按钮或在输入框聚焦时按 ↑↓ 以 step 调节;直接输入在失焦或回车时解析",
|
||||
"非法输入自动回滚为当前值;min/max 超界自动夹取,disabled 支持布尔或信号禁用",
|
||||
"金额、比例这类小数场景传 precision:值与显示都固定小数位,步进不再出现 0.30000000000000004",
|
||||
"需要图标、货币符、单位等前后缀时传 prefix/suffix(字符串或 DOM),控件会包进带边框的附加组,聚焦光环由组统一承载"
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user