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
+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 跟随内容涨落,对象态钳最小/最大行数,超限内部滚动
}
/*** 数字输入入参 ***/
+6 -1
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: '一句话介绍…' })",
@@ -3628,4 +3633,4 @@
}
]
}
}
}