Basic Input
A labelled text input with helper text wired to it via aria-describedby.
6 个框架初级
A textarea that grows to fit its content, with no scrollbar and no drag handle.
<!--
A textarea cannot measure itself while it has a height. The two-line dance in
resize() is the whole technique and the order is not negotiable:
1. height = 'auto' - collapse it so scrollHeight reports the CONTENT
2. height = scrollHeight - grow the box to exactly that
Skip step 1 and scrollHeight just reports the current height back at you, and
the box never shrinks when text is deleted.
-->
<div class="grow-field">
<label class="grow-field__label" for="grow-field-note">Message</label>
<textarea
class="grow-field__input"
id="grow-field-note"
name="note"
rows="1"
placeholder="Write a message…"
aria-describedby="grow-field-note-help"
></textarea>
<p class="grow-field__help" id="grow-field-note-help">The box grows as you type.</p>
</div>
<script>
document.querySelectorAll('.grow-field__input').forEach(function (el) {
function resize() {
el.style.height = 'auto';
el.style.height = el.scrollHeight + 'px';
}
el.addEventListener('input', resize);
// Run once on load - the field may be server-rendered with a value already
// in it, and a pre-filled box that starts at one row defeats the point.
resize();
});
</script>| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
label必填 | string | - | 加载时朗读的无障碍标签。 |
value必填 | string | - | 指标的当前值,需预先格式化。 |
disabled | boolean | false | 禁止交互并将控件置灰。 |
className | string | - | 合并到根元素上的额外类名。 |
A textarea cannot measure itself while it has a height, so the two-line dance is the whole technique and the order is not negotiable: set `height = "auto"` to collapse the box, then `height = scrollHeight` to grow it to the content. Skip the collapse and `scrollHeight` reports the current height back at you - the box grows but never shrinks. `resize-none` because the box sizes itself and a handle would fight the script; `overflow-y-hidden` because the height always equals the content, so a scrollbar could only ever be a phantom stealing horizontal space. The React variants use `useLayoutEffect`, not `useEffect`: the resize must land before paint or the box visibly snaps on every keystroke.