自定义复合控件
自定义控件是例外,而不是一套替代的组件库。
准入判据
只有满足以下全部条件,自定义控件才会被接受:
- PrimeVue 无法提供或组合出预期的语义、交互和可供性。
- 该例外记录了被否决的 PrimeVue 组合方案。
- 它指明了确切的、生成的 PrimeVue 同级契约及契约哈希。
- 该同级契约归类为
shared-runtime的每个属性都有确切的来源映射。 - 只有当同级契约把该确切属性归类为
platform-invariant时,固定实用类才被接受。 - 新颖的几何形状和行为被隔离并有文档记载。
- 无障碍与视觉证据通过。
数据形状等价并不等于可供性等价。多选项的 SelectButton 可以表示三个值,但它的外观和行为都不像一个可滑动的三档开关。反过来,也不要为 ToggleSwitch 臆造一个 positions prop。只有当可供性需求真实存在时,才构建一个经过评审的自定义同级控件。
模块契约
把经过评审的例外保存在模块根目录的 wippy-fe.contract.json 中:
{
"schemaVersion": "generated-by-selected-contract-tool",
"exceptions": [
{
"id": "module.control.example",
"source": "src/components/ExampleControl.vue",
"sourceSha256": "generated-from-source",
"semanticRole": "documented-role",
"requiredAffordance": "documented-affordance",
"rejectedPrimeVueCompositions": [
{
"components": ["SelectButton"],
"reason": "The reviewed sliding affordance cannot be preserved."
}
],
"visualSibling": {
"component": "ToggleSwitch",
"contractId": "primevue.toggleswitch.portable-appearance",
"contractHash": "generated-from-selected-theme-contract"
},
"sharedAppearanceMappings": [
{
"contractProperty": "root.width",
"part": "root",
"selector": ".example-control",
"source": {
"kind": "css-variable",
"name": "--p-toggleswitch-width"
}
}
],
"platformInvariantUtilities": [],
"moduleLocalProperties": [],
"accessibilityEvidence": {
"manifest": ".local/evidence/accessibility-manifest.json",
"scenarioId": "module.control.example.keyboard",
"resultId": "module.control.example.keyboard.passed",
"build": {
"head": "generated-candidate-commit",
"trackedFrontendDiffSha256": "generated-diff-hash"
}
},
"visualEvidence": {
"manifest": ".local/evidence/visual-manifest.json",
"scenarioId": "module.control.example.light.default",
"captureId": "module.control.example.light.default.component",
"build": {
"head": "generated-candidate-commit",
"trackedFrontendDiffSha256": "generated-diff-hash"
}
}
}
]
}
上面展示的值是 schema 占位符,而不是有效证据。完整的映射由所选同级契约生成;单行摘录本身不构成有效的例外。工具会生成源哈希和契约哈希。源哈希或同级契约哈希发生变化会使评审失效。
本页定义规范字段;它不是 JSON Schema,文档检查器只验证该示例保持了必需的结构。wippy-fe-compliance 会用所选主题清单校验真实的模块契约,验证哈希和完整的属性集合,并检查每个证据引用都能解析到来自同一候选构建的、指定名称的通过结果或捕获。无障碍证据绑定组件的 sourceSha256、经哈希的文件、零意外控制台错误,以及一个通过的结果。视觉证据绑定标准的变更前/变更后/差异文件、哈希、重新计算的指标和判定,以及匹配的候选构建。字符串、缺失文件、缺失的场景/结果/捕获、过期的构建哈希、pending 或未经评审的结果,都不满足证据要求。
platformInvariantUtilities 和 moduleLocalProperties 可以为空。绝不要仅仅为了让契约字段非空而臆造 gap-2、w-10、rounded-md 或其他固定实用类。特别是,当 ToggleSwitch 同级控件所选的同级契约把宽度、高度、圆角、焦点几何或动效归类为 shared-runtime 时,它不能把这些属性重新标注为不变量。
同级清单把属性归为以下几类:
shared-runtime:每个自定义同级控件都要映射并消费已发布的 token 或由运行时支撑的语义实用类。platform-invariant:仅对这一确切属性允许使用固定值。implementation-private:PrimeVue 内部机制不会成为自定义同级控件的要求。
如果所需的运行时语义不存在,请先修正共享主题契约。绝不要照抄当前同级控件的尺寸,也不要臆造 token 名称。
sharedAppearanceMappings 是穷尽的,而非示意性的:它为所选同级契约中的每个 shared-runtime 属性恰好包含一条映射,不含额外的属性 ID,并包含契约部件、稳定的模块选择器,以及确切的已发布来源种类和名称。合规工具使用选择器、部件、CSS 属性和已发布来源,通过 PostCSS 从结构上证明该映射;注释或无关选择器中的 token 名称不算数。基于 Tailwind 的映射还要记录唯一且确切的 utilityClasses;归一化之后,该集合必须与所选同级契约的来源集合相等。platformInvariantUtilities 包含 { "contractProperty": "...", "utility": "..." } 形式的记录,其 utility 等于所选同级契约的来源。moduleLocalProperties 非空时,包含结构化的属性 ID 和评审理由,而不是自由形式的 CSS 集合。
不会为单个例外创建共享的 @wippy-fe/ui 包。只有当第二个独立消费方证明了同样的行为和可移植性需求之后,才具备提升条件。