对照基准:
- 规格:docs/refs/components.md#input
- AI 限制:支持(无冲突项);
safe-password / always-embed / nickname 等 ⏭️
- 实现:
packages/flexui-frontend/src/components/input/input.ts
flexui-engine/driver/js/packages/flexui-backend/src/adapters/input-adapter.ts
- Native:
TextInputView(focusTextInput / blurTextInput / placeholderTextColor)
- Demo:
demos/ascf-ai-demo/.../input-demo/
模板使用 kebab-case(如 confirm-type、placeholder-style),组件 properties 为 camelCase(如 confirmType、placeholderStyle);adapter / host attribute 仅 kebab-case,不双写 camelCase 别名。
包名说明:内置组件源码在 @openflexui/frontend(packages/flexui-frontend);原生 adapter 在 flexui-backend。
结论摘要
| 维度 |
结论 |
| 规格纳入(✅) |
value / type / password / placeholder / placeholder-style / placeholder-class / disabled / maxlength / focus / confirm-type + bindinput / bindfocus / bindblur / bindconfirm(须 bind 前缀)→ 已声明 |
| 事件 detail |
bindinput { value, cursor, keyCode };bindfocus { value, height };bindblur { value, cursor };bindconfirm { value } |
| 规格「⚠️」 |
focus Native callUIFunction;placeholder-style/class Native 以 color 为主 |
| 暂不支持 |
bindchange(非聚焦变更语义;勿当 bindinput 别名) |
| 规格「⏭️」 |
safe-password*、nickname、auto-focus、always-embed、Skyline composition/worklet → 未声明 |
| 默认值 |
type=text、password=false、placeholder-class=input-placeholder、disabled=false、maxlength=140、focus=false、confirm-type=done |
属性对照
通用(可交付)
| 属性(模板) |
类型 |
规格默认 |
components.md |
当前实现 |
说明 |
name |
string |
— |
✅(form 字段) |
✅ → host name |
供 form 收集;空串不收集 |
type |
string |
text |
✅ 见合法值 |
✅ → keyboardType |
仅 text / number;text→default;number→numeric→Number;其余非法回退 text |
password |
boolean |
false |
✅ |
✅ → keyboardType=password |
后写覆盖 type;isAttrPresenceOn:"false"→true(密文) |
placeholder |
string |
— |
✅ |
✅ → placeholder |
占位符文案 |
placeholder-style |
string |
— |
✅ ⚠️ |
✅ → 解析 color → placeholderTextColor;Domlike ::placeholder |
font-size/weight Domlike 可注入 |
placeholder-class |
string |
input-placeholder |
✅ ⚠️ |
✅ host attr;Domlike probe class;Native CSSManager → color |
空串回退默认类名 |
disabled |
boolean |
false |
✅ |
✅ Domlike;Native editable;"false"→仍禁用(同 button) |
|
maxlength |
number |
140 |
✅ |
✅ → maxLength |
非法 → 140;-1 Domlike 大数 / Native ResetMaxLength(不限制) |
focus |
boolean |
false |
✅ ⚠️ |
✅ Domlike;Native callUIFunction;"false"→仍聚焦 |
不写入事件监听 prop focus |
confirm-type |
string |
done |
✅ |
✅ → returnKeyType |
kebab only |
type 合法值
| 值 |
components.md |
当前实现 |
text |
✅ |
✅ → default / InputType.Normal |
number |
✅ |
✅ → numeric / InputType.Number |
digit / idcard |
⏭️ 不纳入 |
❌ 非法值回退 text |
safe-password |
⏭️ WebView |
❌ 未声明;传入回退 text |
nickname |
⏭️ |
❌ 未声明;传入回退 text |
事件对照
| 事件 |
components.md |
当前实现 |
detail / 备注 |
bindinput |
✅ { value, cursor, keyCode } |
✅ input → changetext |
Domlike:keydown 记 keyCode + selectionStart;Native:OnWillInsert/Delete → cursor/keyCode |
bindfocus |
✅ { value, height } |
✅ |
height = 软键盘高度(vp/dp);首焦时键盘未起可为 0 |
bindblur |
✅ { value, cursor } |
✅ |
cursor 来自选区起点 |
bindconfirm |
✅ { value } |
✅ confirm → endediting |
{ value } |
bindchange |
⏭️ 暂不支持 |
❌ 未映射 |
非聚焦态变更语义;已从 eventNamesMap 去掉 change |
事件 detail 字段
| 事件 |
detail |
Domlike |
Native(OHOS) |
Native(Android) |
bindinput |
value / cursor / keyCode |
✅ / ✅ / ✅(keydown) |
✅ / ✅ / ✅(WillInsert/Delete;无按键时 0) |
✅ / ✅ / ✅(TextWatcher;无按键时 0) |
bindfocus |
value / height |
✅ / ✅(visualViewport 近似,不可用则为 0) |
✅ / ✅(lastKeyboardHeight;键盘未弹出时为 0) |
✅ / height 暂 0 |
bindblur |
value / cursor |
✅ / ✅ |
✅ / ✅ |
✅ / ✅ |
bindconfirm |
value |
✅ |
✅ |
✅ |
说明:height 语义为键盘高度(对齐微信);聚焦瞬间键盘尚未上报时可能为 0,后续以 keyboardwillshow 为准。Android:cursor / blur.cursor / bindinput.keyCode 已贯通(focus.height 暂 0)。
实现要点
- TS:交付属性经
this._$.setAttribute(kebab)写入 host;Domlike 另同步 HTMLInputElement。
- 事件须
bind 前缀连写:模板用 bindinput / bindfocus / bindblur / bindconfirm(对齐微信 input 文档;勿省略 bind)。
- 非受控 value 不被 flush 清空(分层防护,策略不完全相同):
flushAndBuild 会重推全部 attributes;C++/ETS 用 lastJsValue_ 仅在 JS prop 变化时 SetTextContent。
- NBE + Domlike(前缀丢弃):聚焦态若
prev/cur 比 next 更长且 prev.startsWith(next),拒绝滞后 setAttribute/_syncValue(防 setData("a") 覆盖 "ab")。空串 next 不走此前缀保护(可主动清空)。Domlike 在 onInput 里把 _lastSyncedValue 同步到 DOM 值,因此不能再用 cur !== _lastSyncedValue 判断滞后。
- C++/ETS(聚焦全丢弃):聚焦且
value_ != lastJsValue_(native 已超前、JS 尚未 ack)时,任何不等于当前 value_ 的 JS value prop 一律丢弃,直到 JS ack 到 value_。这比前缀策略更严——父组件在聚焦期间主动格式化/纠错(非「更短前缀」的合法写入)也会静默失效。业务若需聚焦中改值,应在 blur 后写,或先让 controlled value ack 到当前输入再改。
EventDispatcher 在 changetext 时回写 attributes.value(不 scheduleRender)。
password 优先:先写 type 再写 password,保证 buildProps 中 password 覆盖 keyboardType。
focus:adapter propsValue 恒 undefined(避免与监听 prop 冲突);NativeBackendElement.setAttribute → callUIFunction(已 mount);首屏 focus=true 在 _isMounted 前写入时打 _inputFocusPending,flush 后 microtask 补 focusTextInput(等 flushQueue/SceneBuilder 建好节点)。默认 focus=false 不在 mount 时调 blurTextInput。
placeholder-style / placeholder-class:style 的 color 优先;class 经 Domlike probe 或 Native CSSManager 取 color → placeholderTextColor;空 class 回退 input-placeholder。
- Boolean(
password / disabled / focus):与 button disabled 相同,用 isAttrPresenceOn(packages/flexui-frontend/src/attr_bool.ts)——仅 false/0/'0'/未传为关;字符串 "false" 仍为 true。Native adapter / NBE focus 同步用同语义。
- OHOS 点击拉起键盘:C++
TextInputNode 须 SetFocusable(true) + HIT_TEST_DEFAULT(ArkUINode 默认 TRANSPARENT);FocusTextInput 同时 SetFocusStatus + SetTextEditing(true);C-API UpdateEventListener 仅对 TextInput SetProp 事件名(isListen*),不调 OnSetPropsEnd(避免 Init/hit-test 副作用;对齐 ETS setProp only)。
maxlength=-1:adapter 透传 -1;C++ ResetMaxLength()(reset ArkUI 属性=不限制);ETS 用 0x7FFFFFFF;Domlike 524288。
- 验证:改 adapter /
NativeBackendElement → build-jsfwk;改 C++/ETS → assembleHap;仅 frontend → pnpm --filter @openflexui/frontend run build。
| 类型 |
覆盖项 |
| 正向 |
value / placeholder / placeholder-style / placeholder-class / style 优先 class;type text/number / password / disabled / maxlength(含 -1) / focus(含首屏 true) / confirm-type + 事件 detail(input: value/cursor/keyCode;focus: value/height;blur: value/cursor;confirm: value) |
| 异常 |
type 非法(含 digit);placeholder-class="" 回退;password/disabled/focus="false"→仍为 true;maxlength="abc"→140 |
complex 页 Tab:Input。
默认值审计
| 属性 |
规格默认 |
TS / adapter / native |
状态 |
type |
text |
TS 'text' → default |
✅ |
password |
false |
TS false;false 时 skip 映射 |
✅ |
disabled |
false |
TS false |
✅ |
maxlength |
140 |
TS 140 |
✅ |
focus |
false |
TS false |
✅ |
confirm-type |
done |
TS / adapter done |
✅ |
placeholder-class |
input-placeholder |
TS 默认同规格 |
✅ |
参考路径
| 角色 |
路径 |
| 交付规格 |
components.md#input |
| 组件定义 |
packages/flexui-frontend/src/components/input/input.ts |
| Native 适配 |
flexui-engine/.../adapters/input-adapter.ts |
| Host focus |
NativeBackendElement._focusTextInputNow |
| Demo |
demos/ascf-ai-demo/.../input-demo/ |