iter(g204): textarea 支持内容自适应高度

This commit is contained in:
HIsheR
2026-10-26 19:13:52 +08:00
parent 197d57b4f8
commit 5bc854b939
5 changed files with 34 additions and 3 deletions
+6 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "ui-arch-registry-index/0.1",
"generatedAt": "2026-10-26T09:56:49.160Z",
"generatedAt": "2026-10-26T11:13:22.375Z",
"repoRoot": ".",
"packages": [
{
@@ -535,6 +535,11 @@
"n": "maxCount",
"t": "number",
"d": "字数上限:同时设原生 maxlength,并在下方附加块显示实时计数;缺省不限"
},
{
"n": "autosize",
"t": "boolean | { minRows?, maxRows? }",
"d": "自适应内容高度:true 跟随内容涨落,对象态钳最小/最大行数,超出 maxRows 内部滚动;缺省固定行数"
}
],
"example": "const bio = signal(''); textarea({ value: bio, rows: 4, placeholder: '一句话介绍…' })",
+2 -1
View File
@@ -1,6 +1,6 @@
# @ui-arch 组件库 Agent 文档(无图形版)
> 自动生成于 2026-10-26T09:56:49.160Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
> 自动生成于 2026-10-26T11:13:22.375Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
## 快速上手
@@ -177,6 +177,7 @@ const qty = signal(1); const el = inputNumber({ value: qty, min: 1, max: 99, onC
- prefix:string | HTMLElement —— 前置附加块(textField/inputNumber 在输入框内侧前、textarea 在上方);缺省不渲染
- suffix:string | HTMLElement —— 后置附加块(textField/inputNumber 在输入框内侧后、textarea 在下方);缺省不渲染
- maxCount:number —— 字数上限:同时设原生 maxlength,并在下方附加块显示实时计数;缺省不限
- autosize:boolean | { minRows?, maxRows? } —— 自适应内容高度:true 跟随内容涨落,对象态钳最小/最大行数,超出 maxRows 内部滚动;缺省固定行数
示例:
+19
View File
@@ -22,5 +22,24 @@ export function textarea(props: TextareaProps): HTMLElement {
effect(() => { if (props.value) props.value(); syncCount(); }); // 初始与外部写回时同步(读信号建依赖)
}
const suffix = counter ? h('span', { class: 'ua-textarea-count-group' }, counter, props.suffix ?? null) : props.suffix; // 计数并入下方附加组
if (props.autosize) {
const cfg = props.autosize === true ? {} : props.autosize; // 对象态带行数钳制
const frame = (): void => { // 量高与钳制共用一帧:行高/内距从 computed style 推导,零硬编码
const cs = getComputedStyle(el);
const lh = parseFloat(cs.lineHeight) || parseFloat(cs.fontSize) * 1.5; // line-height 为 normal 时按 1.5 倍字号退化
const extra = parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom) + parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth); // 盒模型补偿:scrollHeight 不含边框
if (cfg.minRows) el.style.minHeight = `${lh * cfg.minRows + extra}px`;
if (cfg.maxRows) {
el.style.maxHeight = `${lh * cfg.maxRows + extra}px`;
el.style.overflowY = 'auto'; // 超 maxRows 转内部滚动
}
el.style.height = 'auto'; // 先复位再量,scrollHeight 才是内容真实高度
el.style.height = `${el.scrollHeight}px`;
};
el.style.resize = 'none'; // 高度交给自适应,手动拖拽失去意义
el.addEventListener('input', frame); // 输入即重算
effect(() => { if (props.value) props.value(); frame(); }); // 外部写回信号也重算
frame(); // 初始按当前内容定高
}
return addonWrap(el, props.prefix, suffix, true);
}
+1
View File
@@ -202,6 +202,7 @@ export interface TextareaProps {
prefix?: string | HTMLElement; // 上方附加块(如标题、计数说明);缺省不渲染
suffix?: string | HTMLElement; // 下方附加块(如字数提示);缺省不渲染
maxCount?: number; // 字数上限;传了即设原生 maxlength 并在下方显示实时计数
autosize?: boolean | { minRows?: number; maxRows?: number }; // 自适应内容高度:true 跟随内容涨落,对象态钳最小/最大行数,超限内部滚动
}
/*** 数字输入入参 ***/
+5
View File
@@ -406,6 +406,11 @@
"n": "maxCount",
"t": "number",
"d": "字数上限:同时设原生 maxlength,并在下方附加块显示实时计数;缺省不限"
},
{
"n": "autosize",
"t": "boolean | { minRows?, maxRows? }",
"d": "自适应内容高度:true 跟随内容涨落,对象态钳最小/最大行数,超出 maxRows 内部滚动;缺省固定行数"
}
],
"example": "const bio = signal(''); textarea({ value: bio, rows: 4, placeholder: '一句话介绍…' })",