textarea — 实现与 components.md 对照

对照基准:

  • 规格:docs/refs/components.md#textarea
  • AI 限制:支持(无冲突项);fixed / show-confirm-bar 等 ⏭️ WebView
  • 实现:
    • packages/flexui-frontend/src/components/textarea/textarea.ts
    • flexui-engine/driver/js/packages/flexui-backend/src/adapters/textarea-adapter.ts
    • Native:TextInput + multiline: true(focusTextInput / blurTextInput / placeholderTextColor)
    • Demo:demos/ascf-ai-demo/.../textarea-demo/

模板使用 kebab-case(如 confirm-type、placeholder-style),组件 properties 为 camelCase;adapter / host attribute 仅 kebab-case,不双写 camelCase 别名。

包名说明:内置组件源码在 @openflexui/frontend(packages/flexui-frontend);原生 adapter 在 flexui-backend。


结论摘要

维度 结论
规格纳入(✅) value / placeholder / placeholder-style / placeholder-class / disabled / maxlength / focus / auto-height / confirm-type + bindinput / bindfocus / bindblur / bindconfirm → 已声明
事件 detail 与 input 对齐:bindinput { value, cursor, keyCode };bindfocus { value, height };bindblur { value, cursor };bindconfirm { value }
规格「⚠️」 focus Native callUIFunction;placeholder-style / placeholder-class Native 以 color 为主;auto-height 仅 OHOS Native 测高 + UpdateNodeSize(Android 未实现回写)
规格「⏭️」 fixed / show-confirm-bar / auto-focus / Skyline composition → 未声明
暂不声明 bindlinechange / 键盘推挤类 → ⚠️ 按需
默认值 disabled=false、maxlength=140、focus=false、auto-height=false、confirm-type=return;Native multiline=true(不设 numberOfLines;auto-height=true 时 OHOS 忽略固定 height、放开 maxLines);defaultNativeStyle.minHeight=54(对齐 host min-height:3em @ 18px;原生不跑 :host CSS)

属性对照

通用(可交付)

属性(模板) 类型 规格默认 components.md 当前实现 说明
value string — ✅ ✅ → value host attr + Domlike native.value
name string — ✅(form 字段) ✅ → host name 供 form 收集;空串不收集
placeholder string — ✅ ✅ → placeholder 占位符文案
placeholder-style string — ✅ ⚠️ ✅ → 解析 color → placeholderTextColor;Domlike ::placeholder
placeholder-class string textarea-placeholder ✅ ⚠️ ✅ host attr;Domlike probe class;Native CSSManager → color 空串回退默认类名
disabled boolean false ✅ ✅ Domlike;Native editable;"false"→仍禁用
maxlength number 140 ✅ ✅ → maxLength 非法 → 140;-1 Domlike 大数 / Native ResetMaxLength
focus boolean false ✅ ⚠️ ✅ Domlike;Native callUIFunction;"false"→仍聚焦 不写入事件监听 prop focus
auto-height boolean false ✅ ⚠️ ✅ → autoHeight;为 true 时忽略 style.height;"false"→仍开启 Domlike:scrollHeight;Native 测高回写仅 OHOS(Android adapter 透传 prop,无 UpdateNodeSize)
confirm-type string return ✅ ✅ → returnKeyType 含 return;kebab only

事件对照

事件 components.md 当前实现 detail / 备注
bindinput ✅ { value, cursor, keyCode } ✅ input → changetext 与 input 同链路
bindfocus ✅ { value, height } ✅ height = 键盘高度(未弹出可为 0)
bindblur ✅ { value, cursor } ✅
bindconfirm ✅ { value } ✅ confirm → endediting 须 bindconfirm;confirm-type=return 时 Enter 换行不发 confirm;非 return 不插行(Domlike preventDefault);Shift+Enter Domlike 仍换行
bindlinechange ⚠️ 按需 ❌ 未声明 Native 有 contentsizechange,语义不完全等价,暂不映射

事件 detail 字段

事件 detail Domlike Native(OHOS) Native(Android)
bindinput value / cursor / keyCode ✅ / ✅ / ✅(keydown) ✅ / ✅ / ✅(WillInsert/Delete) ✅ / ✅ / ✅(TextWatcher onTextChanged)
bindfocus value / height ✅ / ✅ ✅ / ✅ ✅ / height 暂 0
bindblur value / cursor ✅ / ✅ ✅ / ✅ ✅ / ✅
bindconfirm value ✅ ✅ ✅

实现要点

  1. TS:交付属性经 this._$.setAttribute(kebab)写入 host;Domlike 另同步 HTMLTextAreaElement。
  2. 事件须 bind 前缀连写:模板用 bindinput / bindfocus / bindblur / bindconfirm。
  3. 非受控 value:与 input 同策略分层——NBE/Domlike 聚焦态更短前缀丢弃;C++/ETS 聚焦且 value_ != lastJsValue_ 时全丢弃冲突 prop(含父组件主动格式化);EventDispatcher 回写 attributes.value。详见 input 对照「实现要点 §3」。
  4. focus:adapter propsValue 恒 undefined;NativeBackendElement 对 input 与 textarea 走同一套 callUIFunction。
  5. Boolean(disabled / focus / auto-height):isAttrPresenceOn——字符串 "false" 仍为 true。
  6. auto-height:host auto-height → Native autoHeight;为 true 时 resolveNativeProps 剔除 style.height。测高回写仅 OHOS(GetTextContentRect + OnSizeChanged2);Android 仅透传 prop / 去掉固定 height,不回写 Dom 高度。Domlike 用 scrollHeight 同步。测高下限:max(3em, CSS minHeight)(NBE 经 layoutMinHeight 传入),避免空内容塌成一行、超长 placeholder 被裁切。NBE 仅首帧用 minHeight 占位 height,后续 flush 不得再写(blur/setData 会覆盖测高);RootNode 保留 UpdateNodeSize 高度;失焦后 CONTENT_RECT 裁切不得向下回写(否则变矮并可内部滚动)。
  7. 默认高度:hostCSS min-height:3em 在原生 不生效(registerStyleSheetContent 只吃 JSON 规则);由 adapter defaultNativeStyle.minHeight=54 兜底。业务 min-height: Nem 经 StyleResolver 按 font-size 折算。
  8. confirm-type:return → OHOS EnterKeyType.NEW_LINE / Android IME_FLAG_NO_ENTER_ACTION(Enter 换行,不发 confirm)。非 return:Native 走 onSubmit/endediting 不插行;Domlike Enter(无 Shift)preventDefault() 后发 confirm。Shift+Enter Domlike 仍插入换行、不发 confirm(浏览器默认)。
  9. cursor 单位:统一 UTF-16 code unit(与 JS string.length / Domlike selectionStart / ETS insertValue.length 一致);C++ OnWillInsert 用 Utf8ToUtf16CodeUnitCount,补充平面按 surrogate pair 计 2。
  10. 无 type / password:textarea 规格不交付键盘类型 / 密文。
  11. 验证:改 adapter / NativeBackendElement → build-jsfwk;改 C++/ETS → assembleHap / build-engine;仅 frontend → pnpm --filter @openflexui/frontend run build。

Demo 覆盖(textarea-demo)

类型 覆盖项
正向 value / placeholder / placeholder-style / placeholder-class / style 优先 class;disabled / maxlength(含 -1) / focus(含首屏 true) / auto-height(含固定 height 应被忽略) / confirm-type + 事件
异常 disabled/focus/auto-height="false"→仍为 true;maxlength="abc"→140

complex 页 Tab:Textarea。


默认值审计

属性 规格默认 TS / adapter / native 状态
disabled false TS false ✅
maxlength 140 TS 140 ✅
focus false TS false ✅
auto-height false TS false;Native 测高回写 仅 OHOS ✅(Android 缺口见上)
confirm-type return TS / adapter return ✅
placeholder-class textarea-placeholder TS 默认同规格 ✅
multiline — adapter nativeProps.multiline=true ✅
numberOfLines — 不设(避免 ArkUI TextArea 按行截断) ✅
默认高度 host min-height:3em adapter minHeight:54(原生 :host 不生效) ✅

参考路径

角色 路径
交付规格 components.md#textarea
组件定义 packages/flexui-frontend/src/components/textarea/textarea.ts
Native 适配 flexui-engine/.../adapters/textarea-adapter.ts
Host focus NativeBackendElement._focusTextInputNow(input + textarea)
Demo demos/ascf-ai-demo/.../textarea-demo/