button — 实现与 components.md 对照
对照基准:
- 规格:docs/refs/components.md#button
- AI 限制:不支持所有
open-type(及配套属性 / 回调) - 实现:
packages/flexui-frontend/src/components/button/button.tsflexui-engine/driver/js/packages/flexui-backend/src/adapters/button-adapter.ts- Demo:
demos/ascf-ai-demo/.../button-demo/
模板使用 kebab-case(如 hover-class),组件 properties 为 camelCase(如 hoverClass)。
结论摘要
| 维度 | 结论 |
|---|---|
| 规格纳入属性 | 9/10 已实现(loading 暂不实现) |
| AI 冲突 | open-type 及全部配套 不声明 |
| Skyline / WebView | button 节无分项 |
| 与规格默认值 | 已实现项与规格一致(含 hover 默认 button-hover / 20 / 70) |
| 默认尺寸(ASCF) | padding L/R 14、font 16、height/line-height 40、radius 30、max-width:448 |
| 默认色 | 字 #0A59F7、底 rgba(0,0,0,0.047) |
| primary | 字 #FFFFFF、底 #0A59F7 |
| plain | 透明底 + 1px solid:type=default / primary 字边 #0A59F7;warn #E84026(type 默认 default) |
| mini | font 14、height/line-height 28、padding L/R 8、radius 50、width:auto、alignSelf:flex-start、margin L/R:0(清掉默认 margin:auto,横排不拉开) |
| disabled | opacity: 0.4 |
属性对照
| 属性(模板) | 类型 | 规格默认 | components.md | 当前实现 | 说明 |
|---|---|---|---|---|---|
size |
string | default |
✅ 纳入 | ✅ size |
default / mini |
type |
string | default |
✅ 纳入 | ✅ type |
primary / default / warn;非法值按 default 样式 |
plain |
boolean | false |
✅ 纳入 | ✅ plain |
镂空;!!"false"→true |
disabled |
boolean | false |
✅ 纳入 | ✅ disabled |
样式 + attr;builtin/原生均保持 type 色 + opacity:0.4 |
loading |
boolean | false |
✅ 纳入 | ⏭️ 暂不实现 | 不声明 property;原生 spinner 效果未定 |
form-type |
string | — | ✅ 纳入(按需) | ✅ formType |
写 host attr;与 form 联动 submit/reset。运行时移除后逻辑不再触发 form,但 NBE tap→click 注册 sticky(与 bindtap 共享,见 form-vs-components LOW-1) |
hover-class |
string | button-hover |
✅ 纳入 | ✅ hoverClass |
none 关闭;默认类在 button.css |
hover-stop-propagation |
boolean | false |
✅ 纳入 | ✅ | 宿主监听 + 祖先取消;字符串 "false" 按 !! 仍为 true |
hover-start-time |
number | 20 |
✅ 纳入 | ✅ | ms |
hover-stay-time |
number | 70 |
✅ 纳入 | ✅ | ms |
open-type 及配套 |
— | — | ⏭️ AI 冲突 | ⏭️ 不声明 | 见 components.md 冲突表 |
事件对照
| 事件 | components.md | 当前实现 | 备注 |
|---|---|---|---|
bindtap |
(基础) | ✅ tap→click |
button-adapter |
| touch 系列 | (基础) | ✅ | 坐标写入 touches[0] |
| open-type 回调 | ⏭️ AI 冲突 | ⏭️ 不实现 | — |
宿主长按联动:button 的
bindtap→click使按钮成为「有 JS 监听」节点 → 引擎父长按抑制挂载(SetTouchTestDoneCallback,见capabilities/09-event-system.md§4.7)——宿主父容器parallelGesture(LongPress)长按按钮被抑制(引擎自身/内置长按放行、其余长按压制,无需宿主打标),按钮自身 click/longclick 与页面滚动不受影响;长按空白/无监听区宿主长按照常。
实现要点
- 视觉(方案一):Native 上
type/size/plain/disabled只经宿主 attr → adapterresolveDefaultStyle(StyleResolver default 层);builtin 不再写 TEMP_EXTRA 主题,避免压过 class/style。Domlike(Web)仍用buttonHostStyleCss→ TEMP_EXTRA(无:host([attr]))。 - Hover:宿主
addListener(非 shadowRoot);toggleNodeClass;默认.button-hover { opacity:0.7; background-color:rgba(0,0,0,0.1) }。 - disabled:组件写 attr;builtin / 原生共用主题表(
button-theme.ts):非 plain 保留 type 底色 +opacity:0.4(不用灰底#f7f7f7);plain 禁用改灰字/灰边。 - 原生视觉:
defaultNativeStyle+resolveDefaultStyle;尺寸 padding14 / font16 / h40 / r30 / maxW448;色 default 蓝字浅底、primary 白字蓝底、warn 红字浅底。 - 原生:button → native
View+ syntheticText子节点(无独立 Button 控件)。
Demo 覆盖
正向:size / type / plain / disabled / form-type / hover 四属性。
回归:class / style 覆盖 type=primary 主题色(验 resolveDefaultStyle 在 default 层、可被 CSS/inline 盖掉)。
异常:plain|disabled="false" 字符串、hover-start-time 非法串/boolean、hover-stop-propagation="false"、非法 type/size。
(不含 loading)
参考路径
| 角色 | 路径 |
|---|---|
| 交付规格 | components.md#button |
| 组件定义 | packages/flexui-frontend/src/components/button/button.ts |
| Native 适配 | flexui-engine/.../adapters/button-adapter.ts |
| Demo | demos/ascf-ai-demo/.../button-demo/ |