关于 sap-sac-custom-widget
用于开发和验证 SAP Analytics Cloud 自定义 Widget 的技能,帮助以 Web Components 扩展故事和应用的视觉呈现与交互。内容涵盖生成指导、本地脚手架、浏览器预览、打包规则和故障排查。
主要功能
- 01Widget 架构与代码指导
- 02脚手架生成和浏览器预览
- 03SAC 清单与 ZIP 打包指导
- 04验证命令和质量检查钩子
- 05生命周期与生产故障排查
适用场景
- 01创建 SAC 标准功能中没有的可视化
- 02生成交互式 Widget 或 KPI 展示
- 03准备并验证 SAC 导入制品
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ secondsky/ sap-skills --skill sap-sac-custom-widget安装后在 Claude Code 中输入/sap-sac-custom-widget确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdagents/openai.yamlreferences/advanced-topics.mdai-assisted-composite-generation.mdbest-practices-guide.mdbrowser-design-runtime.mdcss-and-styling-compliance.mdecharts-integration.mdintegration-and-migration.mdjson-schema-reference.mdlocal-builder-workflow.mdproduction-widget-lessons.mdproperty-lifecycle.mdsac-import-packaging-lessons.mdsap-sample-widget-lessons.mdscript-api-reference.mdverification-and-artifacts.mdwidget-addon-guide.mdwidget-discovery-intake.mdwidget-templates.mdtemplates/basic-widget.jsbuilder-panel.jsdata-bound-chart.jstemplates/design-runtime/design-runtime.jsonindex.htmlruntime.cssruntime.jstemplates/local-builder/builder-config.jsonbuilder.cssbuilder.js详细介绍
SAP Analytics Cloud 自定义 Widget 开发
相关技能
- sap-sac-scripting:当自定义 Widget 与 SAC 脚本、Widget 或故事/应用 API 交互时使用
- sap-sac-planning:当 Widget 参与规划工作流或规划表交互时使用
- sapui5:用于 Web Component/UI5 前端实现模式和浏览器端质量
- sap-dependency-security:当向 Widget 项目添加第三方图表或构建依赖项时使用
目录
- 概览
- AI 辅助生成
- Widget 发现与证据收集
- 本地自定义 Widget 构建器
- SAP 示例 Widget 的经验
- 浏览器设计运行时
- CSS 与样式合规性
- SAC 导入与打包
- 生产审计经验
- 属性生命周期
- 验证与制品规范
- 插件组件
- 快速入门
- 社区示例 Widget
- 关键概念
- 常见错误与解决方案
- 捆绑资源
概览
此技能支持开发适用于 SAP Analytics Cloud(SAC)的自定义 Widget。自定义 Widget 是 Web Component,可为 SAC 故事和应用扩展自定义可视化、交互元素和专用功能。
何时使用此技能
在以下情况下使用此技能:
- 构建 SAC 标准功能中没有的自定义可视化
- 生成由提示词驱动的 Widget 创意、品牌化 Widget 套件或适用于组合的 Widget 设计
- 集成第三方图表库(ECharts、D3.js、Chart.js)
- 为 SAC 应用创建交互式输入组件
- 实现专用数据展示或 KPI Widget
- 使用自定义功能扩展 Analytics Designer 应用
- 排查自定义 Widget 加载或数据绑定问题
要求:
- 使用 Optimized Story Experience 或 Analytics Designer 的 SAC 租户
- JavaScript/Web Component 知识
- 外部托管(GitHub Pages、AWS S3、Azure)或 SAC 托管资源(QRC Q2 2023+)
AI 辅助生成
创建由提示词驱动的 Widget 时,请先对 Widget 角色和数据源模式进行分类,然后提供 2-3 个考虑角色的选项,再生成所选的完整套件。确保 AI 生成的代码与 SAC 兼容,在使用数据绑定时保留绑定顺序,并在导入前进行验证和修复。有关输出约定、RAG 上下文模式、品牌样式和组合注意事项,请参阅 references/ai-assisted-composite-generation.md。
Widget 发现与证据收集
在生成表格、图表、KPI、菜单、侧边栏、筛选器或混合控件之前,请同时选择 Widget 角色和数据源模式。仅对绑定到 SAC 的 Widget 收集维度、度量/关键指标、日期、版本、筛选条件和 Feed 顺序。对于纯 UI 控件,则应收集交互、导航、状态、方法/事件、无障碍和响应式布局要求。可以将用户提供的屏幕截图、PDF、图像、品牌指南和经过脱敏的数据作为证据,但在生成代码前,请确认技术 ID、Feed 映射、素材权利和许可证。有关 Widget Brief、证据范围和托管工具的安全措施,请参阅 references/widget-discovery-intake.md。
本地自定义 Widget 构建器
对于企业或受限的本地环境,推荐使用 templates/local-builder/ 作为标准的免安装脚手架构建器。它以静态 HTML/CSS/原生 JavaScript 运行,不依赖公共 CDN 或外部软件包,并将 SAC 上传产物分别导出为两个文件:widget.json 和仅包含根目录组件 JavaScript 文件的 Resource-ZIP。若直接通过 file:// 使用受阻,请使用 Node 的 server.mjs 备用方案。当用户明确允许在非敏感桌面原型中使用公共网络时,可酌情推荐 Custom Widget Builder 或在线演示;绝不要发送租户资料,也不要在未经本地验证的情况下信任其导出内容。有关构建器的边界、导出规则、托管工具的防护措施和验证检查,请参阅 references/local-builder-workflow.md。
SAP 示例 Widget 的经验
在生成图表、KPI、层级结构、输入工具、Widget Add-On 或基于构建流程的 Widget 之前,请查阅 references/sap-sample-widget-lessons.md。该文档审查了所有 SAP 示例文件夹,并提炼出可复用的经验,涵盖以数据绑定为先的脚手架、相对于根目录的 Resource-ZIP URL、样式与构建器面板的分离、支持标志、自定义 types、脚本方法/事件、Add-On 的 extensions[] 以及基于构建流程的应用注意事项。仅将这些经验用于结构和风险检查;不要将 SAP 示例代码或资源复制到生成的软件包中。
浏览器设计运行时
生成的 Widget 软件包应包含 templates/design-runtime/,作为免构建、以文件为先的浏览器预览脚手架。生成后,可在 SAP 之外模拟自定义 Widget 的核心功能、调整属性/设计令牌/示例数据/视口、比较多个 Widget,并导出 Agent 迭代载荷。有关运行时边界以及配置/导出约定,请参阅 references/browser-design-runtime.md。使用 templates/local-builder/ 生成/导出脚手架;使用 templates/design-runtime/ 进行预览和迭代。
CSS 和样式合规性
在 Web Component/Shadow DOM 边界内设置自定义 Widget 的样式。不要依赖 SAC 优化故事主题 CSS、SAP shell 选择器或全局故事 CSS 来设置 Widget 内部样式。对于生成的软件包,在将 CSS/HTML 拆分到不同文件之前,请确认托管模式,因为 SAC ZIP 上传软件包仅支持组件 JavaScript 和 PNG/JPG 图标。有关 SAP Help 支持的允许/限制样式规则,请参阅 references/css-and-styling-compliance.md。
SAC 导入与打包
在生成 widget.json 之前,先确定交付方式:SAC Resource-ZIP 上传和外部 HTTPS 托管使用不同的 URL 规则。对于 SAC Resource-ZIP 上传,请单独交付 widget.json,先上传它,然后再上传一个包含根目录组件 JavaScript 文件(如 widget.js、builder.js 和 styling.js)的 Resource-ZIP。不要将 widget.json、子文件夹、测试、README 文件、CSS 或 HTML 放入该 Resource-ZIP。
对于 Resource-ZIP 清单,请使用根目录相对组件 URL,例如 "/widget.js";对于外部托管,请使用完整的 HTTPS URL。除非目标 SAC 流程明确说明了相应的解析模式,否则只在仅用于预览的配置中保留 "widget.js" 这类本地预览路径。简单的可配置颜色应建模为 string 属性,并使用 "#f4f7fa" 这类十六进制默认值;只有在确切的 SAC 租户和目标面板流程接受 Color 类型后,才使用该类型。浏览器预览和 Node 测试很有用,但不能证明组件可导入 SAC。对于带有 builder/styling 面板的 widget,在文本编辑期间保留焦点和折叠状态,让组件 JS 保持自包含,并验证最终的 outputs/ 产物,而不仅是源代码预览。widget 完成后,最终聊天回复必须提供两个已完成的上传产物供下载:widget.json 清单和 Resource-ZIP。有关上传顺序、ZIP 内容检查、最终产物测试、builder/tree 规则、最终下载交付和 SAC 错误排查,请参阅 references/sac-import-packaging-lessons.md。
生产审计经验
如果 widget 在通过本地测试后仍被 SAC 拒绝,请查阅 references/production-widget-lessons.md。其中涵盖 bundle 中的原始控制字符、Analytics Designer 方法体限制、必需的完整性状态、仅客户端的清单验证、图标与字体隔离、用户和语言边界、书签风险、针对不透明错误的二分排查、行为预检防护,以及浏览器预览的局限。请将其中的证据标签视为指导内容的一部分:不得将租户观察结果、SAP 记录的行为和未经确认的假设视为同等证据。
属性生命周期
将 SAC 属性视为外部状态流。SAC 可能逐个传递属性、回显 widget 写入的值,并更改其表示形式。合并更新,通过单一读取路径进行规范化,并根据合并后的状态渲染。不要假定属性顺序,也不要在首次渲染为空时使用 builder 初始化标志。清单方法体使用的是 Analytics Designer 脚本:可以读取或写入已声明的属性,但不能调用私有组件方法。
Builder 和 styling 面板是有状态的编辑器。请让文本编辑尽量精确,以保留焦点、插入光标、选区、搜索和折叠状态。当两个编辑器共用同一文档时,保留未知配置键;并确保一次用户操作只触发一次属性分发和一次撤销步骤。对于结构化导入或导出,请保留稳定 ID,深拷贝嵌套模板,为用户创建的名称使用 null 原型映射,并测试每个语言槽位。请参阅 references/property-lifecycle.md。
验证与产物规范
验证构建后的组件文件和最终 Resource-ZIP,而不仅是源代码辅助工具或浏览器预览。先生成所有输出并进行验证,然后再写入。对最终 bundle 进行独立测试,验证准确的 SRI 字节,扫描原始控制字符,并使用真实浏览器测试布局、焦点、字体、指针和生命周期行为,因为这些行为无法通过 DOM 仿真呈现。请参阅 references/verification-and-artifacts.md。
插件组件
此插件提供专用 Agent、命令和验证钩子,为全面的 widget 开发提供支持。
Agent
| Agent | 颜色 | 用途 | 触发示例 |
|---|---|---|---|
| widget-architect | 蓝色 | 设计组件结构、元数据和集成模式 | “设计自定义组件”、“规划组件架构” |
| widget-debugger | 黄色 | 排查加载、数据绑定、CORS 和运行时问题 | “组件无法加载”、“CORS 错误”、“数据未绑定” |
| widget-api-assistant | 绿色 | 编写 JavaScript 组件代码、生命周期函数和 API 集成 | “编写组件代码”、“实现生命周期函数” |
命令
| 命令 | 用法 | 描述 |
|---|---|---|
/widget-validate | /widget-validate [file] | 验证 widget.json 架构和 widget.js 结构 |
/widget-generate | /widget-generate | 交互式生成组件脚手架,包含 JSON、JS、本地构建器和浏览器设计运行时 |
/widget-lint | /widget-lint [file] | 分析性能、安全性和最佳实践 |
验证钩子
在 Write/Edit 操作时触发的自动质量检查:
- widget.json:必填字段、标签命名、属性类型、数据绑定配置
- widget.js:生命周期函数、Shadow DOM、propertiesChanged 分发
- 性能:调整大小事件防抖、图表释放、XSS 防护
- 上下文提醒:模板建议、命令推荐
模板
templates/ 目录中提供可直接使用的脚手架:
basic-widget.js- 包含所有生命周期函数的最简 Web Componentdata-bound-chart.js- 支持数据绑定的 ECharts 组件styling-panel.js- 运行时自定义面板builder-panel.js- 设计时配置面板local-builder/- 静态本地脚手架构建器和 SAC 工件导出器design-runtime/- 浏览器预览和设计迭代运行时widget.json-minimal- 最精简的元数据widget.json-complete- 包含所有选项的完整功能元数据
快速开始
最简自定义组件结构
自定义组件需要两个文件:
1. widget.json(元数据)
{
"id": "com.company.mywidget",
"version": "1.0.0",
"name": "My Custom Widget",
"description": "A simple custom widget",
"vendor": "Company Name",
"license": "MIT",
"icon": "",
"webcomponents": [
{
"kind": "main",
"tag": "my-custom-widget",
"url": "https://your-host.com/widget.js",
"integrity": "",
"ignoreIntegrity": true
}
],
"properties": {
"title": {
"type": "string",
"default": "My Widget"
}
},
"methods": {},
"events": {}
}
2. widget.js(Web Component)
(function() {
const template = document.createElement("template");
template.innerHTML = `
<style>
:host {
display: block;
width: 100%;
height: 100%;
}
.container {
padding: 16px;
font-family: Arial, sans-serif;
}
</style>
<div class="container">
<h3 id="title">My Widget</h3>
<div id="content"></div>
</div>
`;
class MyCustomWidget extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ mode: "open" });
this._shadowRoot.appendChild(template.content.cloneNode(true));
this._props = {};
}
connectedCallback() {
// Called when element is added to DOM
}
onCustomWidgetBeforeUpdate(changedProperties) {
// Called BEFORE properties are updated
this._props = { ...this._props, ...changedProperties };
}
onCustomWidgetAfterUpdate(changedProperties) {
// Called AFTER properties are updated - render here
if (changedProperties.title !== undefined) {
this._shadowRoot.getElementById("title").textContent = changedProperties.title;
}
}
onCustomWidgetResize() {
// Called when widget is resized
}
onCustomWidgetDestroy() {
// Cleanup when widget is removed
}
// Property getter/setter (required for SAC framework)
get title() {
return this._props.title;
}
set title(value) {
this._props.title = value;
this.dispatchEvent(new CustomEvent("propertiesChanged", {
detail: { properties: { title: value } }
}));
}
}
customElements.define("my-custom-widget", MyCustomWidget);
})();
⚠️ 生产说明:上面的 ignoreIntegrity: true 设置仅适用于开发环境。生产部署时,请生成 SHA256 完整性哈希,并设置 ignoreIntegrity: false。
社区示例组件
SAP 提供了一个社区示例仓库,其中包含 17 个自定义组件示例文件夹:
仓库:SAP-samples/SAC_Custom_Widgets
| 类别 | 组件 |
|---|---|
| 图表 | 漏斗图、帕累托图、桑基图、旭日图、树图、折线图、UI5 甘特图 |
| KPI/仪表 | KPI 环形图、仪表评分、半圆环图、嵌套饼图、自定义饼图 |
| 实用工具 | 文件上传、词云、渐变条形图、组件插件示例 |
要求:大多数示例都假定使用数据绑定,以及优化视图模式(OVM)或优化统一故事体验。
注意:生产使用前请检查第三方库许可证;迁移示例时请调整托管组件路径;实时 SAC 导入和运行时验证需视租户而定。各示例的审查和创建经验请参见 references/sap-sample-widget-lessons.md。
核心概念
生命周期函数
SAC 框架调用的必要函数:
onCustomWidgetBeforeUpdate(changedProperties)- 更新前钩子onCustomWidgetAfterUpdate(changedProperties)- 更新后钩子(在此处渲染)onCustomWidgetResize()- 处理调整大小事件onCustomWidgetDestroy()- 清理资源
数据绑定
在 widget.json 中配置以接收 SAC 模型数据:
{
"dataBindings": {
"myDataBinding": {
"feeds": [
{
"id": "dimensions",
"description": "Dimensions",
"type": "dimension"
},
{
"id": "measures",
"description": "Measures",
"type": "mainStructureMember"
}
]
}
}
}
在 JavaScript 中访问数据:
// Get data binding
const dataBinding = this.dataBindings.getDataBinding("myDataBinding");
// Access result set
const data = this.myDataBinding.data;
const metadata = this.myDataBinding.metadata;
// Iterate over rows
for (let i = 0; i < this.myDataBinding.data.length; i++) {
const row = this.myDataBinding.data[i];
const dimensionValue = row.dimensions_0 ? row.dimensions_0.label : "";
const measureValue = row.measures_0 ? row.measures_0.raw : 0;
}
托管选项
1. SAC 托管(推荐,QRC Q2 2023+)
- 将文件直接上传到 SAC > Files > Public Files
- 对于 Resource-ZIP 上传流程,请先上传
widget.json,然后在 SAC 启用 Resource File 按钮后,再上传单独的 Resource-ZIP - 对于 Resource-ZIP 上传流程,请使用根相对 URL,例如
"/widget.js";生产清单中不要使用本地 Windows 反斜杠或本地预览路径 - 设置
"integrity": ""和"ignoreIntegrity": true
2. GitHub Pages
- 创建包含组件文件的仓库
- 在 Settings 中启用 GitHub Pages
- 使用 URL:
https://username.github.io/repo/widget.js
3. 外部 Web 服务
- AWS S3、Azure Blob 或任何 HTTPS 服务
- 必须包含 CORS 标头:
Access-Control-Allow-Origin: *
安全性:完整性哈希
在生产环境中,使用 Node.js 为 Windows/macOS/Linux 生成 SHA256 完整性值:
# Generate integrity hash for widget.js
node -e "const fs=require('node:fs');const crypto=require('node:crypto');const file=process.argv[1]||'widget.js';console.log('sha256-'+crypto.createHash('sha256').update(fs.readFileSync(file)).digest('base64'));" widget.js
# Update JSON
"integrity": "sha256-abc123...",
"ignoreIntegrity": false
在 macOS/Linux 或 Git Bash 上,也可以使用 OpenSSL;将输出添加到清单前,请在其前面加上 sha256-:
openssl dgst -sha256 -binary widget.js | openssl base64 -A
常见错误与解决方案
| 错误 | 原因 | 解决方案 |
|---|---|---|
| "The system couldn't load the custom widget" | URL 不正确或托管问题 | 确认 URL 可访问,并检查 CORS |
| "Integrity check failed" | 哈希不匹配 | 修改 JS 后重新生成哈希 |
| Widget 未显示 | 缺少 connectedCallback render | 在 onCustomWidgetAfterUpdate 中调用 render |
| 属性未更新 | 缺少 propertiesChanged dispatch | 使用 dispatchEvent 和 propertiesChanged |
| 数据未显示 | 数据绑定配置不正确 | 确认 JSON 中的 feeds 与实际用法一致 |
CUSTOM_WIDGET_SERVICE_EXCEPTION 或含糊的 HTTP 500 | 原始控制字符或易混淆的码点、格式错误的方法体、清单与 ZIP 不匹配,或其他上传限制 | 扫描源代码和构建产物,检查是否含有控制码点、BOM、零宽字符和行分隔符,然后通过一次只更改一个变量的 JSON 和 ZIP 探测进行排查 |
| 方法体因未知函数或类型错误而被拒绝 | 方法体调用了组件内部实现,而非使用已声明的属性 | 将该状态声明为属性,并让方法体读取或写入该属性 |
清单因缺少 integrity 而被拒绝 | webcomponents[] 缺少必需字段 | 添加 integrity,并使用开发模式的 "" 和 ignoreIntegrity: true,或使用真实的 sha256-... 摘要并设为 false |
| 图标显示为空白 | 图标名称未打包或是猜测得出的 | 生成并搜索已提交的图标映射;不要依赖 widget 内的 IconPool |
| Widget 使用了错误的字体 | 表单控件使用其 UA 字体,或面板 CSS 覆盖了 SAC | 让控件继承字体,并避免在设计时面板中使用自定义字体栈 |
| 个人信息或语言值为空或不正确 | Widget 尝试发现用户或 SAC 区域设置上下文 | 通过 story script 中已声明的属性传入 |
"Color" is not a valid type 或默认值必须为 Color | 租户/导入流程拒绝了简单颜色属性 | 简单可配置颜色使用 string,并采用十六进制默认值 |
| 无法加载主组件 | 资源 URL、ZIP 内容或 JS 语法问题 | 检查以根目录为基准的 webcomponents[].url、Resource-ZIP 根目录内容,然后运行 node --check |
| Resource File 上传已禁用 | widget.json 尚未通过验证 | 先上传并验证 widget.json,再上传 Resource-ZIP |
| Resource-ZIP 导入/后续加载失败 | ZIP 包含清单、文件夹、CSS/HTML 或无关文件 | 仅保留根目录下的 JS 组件文件和可选的 PNG/JPG 图标 |
| Builder 输入框失去焦点或折叠状态 | 文本编辑触发了完整渲染 | 直接更新字段/行/JSON 文本;仅在结构变更时进行完整渲染 |
| 预览正常,但 SAC 组件单独运行失败 | 预览依赖打包后的 JS 中不存在的共享源代码辅助脚本 | 不使用仅供预览的辅助脚本,测试最终的 widget.js、builder.js 和 styling.js |
| 重复菜单项发生冲突 | 子树重复操作只重写了根 ID | 重写后代 ID,并测试整棵树中的 ID 是否唯一 |
| 面板显示的值被运行时忽略 | 属性已存储或导出,但运行时从未读取它 | 为每个清单属性添加运行时使用检查和行为测试 |
| 有效的零被替换为默认值 | 数值转换使用了 `Number(value) | |
| Builder 丢失已输入的文本或搜索状态 | 每次更新都会重建面板 | 原位更新字段;需要结构化渲染时,恢复焦点、选区和光标位置 |
| 重命名或重复操作遗留过时状态 | 标识依赖位置,或浅拷贝导致嵌套数据存在别名 | 保留稳定的 id,深拷贝模板,并枚举所有引用持有方 |
| 布局通过 DOM 测试,但在 SAC 中失败 | 测试环境没有布局或字体度量信息 | 在真实浏览器中验证几何布局和依赖字体的行为 |
| 用户自定义名称的行为因大小写而不一致 | 多处成员检查都使用精确比较 | 集中处理匹配规则,并测试仅大小写不同的重命名 |
调试
浏览器开发者工具
- 打开 Chrome 开发者工具(F12)
- 在 Sources 标签页中找到 widget.js 并设置断点
- 在 Console 标签页中查看 console.log 输出
- 在 Network 标签页中检查文件是否加载成功(状态码为 200)
调试模式
onCustomWidgetAfterUpdate(changedProperties) {
console.log("Widget updated:", changedProperties);
console.log("Current props:", this._props);
console.log("Data binding:", this.myDataBinding && this.myDataBinding.data);
this._render();
}
Widget 扩展(QRC Q4 2023+)
Widget 扩展可扩展内置 SAC Widget,无需从头构建。
使用场景:
- 自定义图表工具提示
- 向绘图区添加视觉元素
- 覆盖内置样式
支持的图表:条形图/柱状图、堆叠条形图/柱状图、折线图、堆叠面积图、数值点图
主要区别:
- 只有
main和builder组件(没有styling) - 必须指定扩展目标(
tooltip、plotArea、numericPoint) - SAC 通过方法提供图表上下文数据
完整实现说明请参阅 references/widget-addon-guide.md。
捆绑资源
模板(可直接使用的代码)
templates/basic-widget.js- 最简 Web Component 脚手架(约 60 行)templates/data-bound-chart.js- 带 SAC 数据绑定的 ECharts Widget(约 120 行)templates/styling-panel.js- 用于运行时自定义的样式面板(约 150 行)templates/builder-panel.js- 用于设计时配置的构建器面板templates/local-builder/- 无需安装的本地构建器,支持元数据、数据馈送、属性、方法、事件和 SAC 双文件导出templates/design-runtime/- 无需构建的浏览器预览、设计令牌控件、场景切换和 Agent 迭代导出templates/widget.json-minimal- 最简元数据(约 25 行)templates/widget.json-complete- 完整功能的元数据(约 100 行)
参考文档
references/json-schema-reference.md- 完整的 JSON 架构文档references/widget-templates.md- 其他 Widget 模板模式(6 个模板)references/echarts-integration.md- ECharts 库集成指南references/widget-addon-guide.md- Widget 扩展开发(QRC Q4 2023+)references/best-practices-guide.md- 性能、安全和开发指南references/advanced-topics.md- 自定义类型、脚本 API 类型、安装references/integration-and-migration.md- 脚本集成、内容传输references/script-api-reference.md- DataSource、Selection、MemberInfo APIreferences/ai-assisted-composite-generation.md- 提示词驱动生成、RAG、品牌样式、验证和复合组件就绪输出指南references/local-builder-workflow.md- 企业安全的本地构建器工作流、导出约定和验证清单references/sap-sample-widget-lessons.md- SAP 示例 Widget 审查矩阵、可复用的生成经验,以及扩展/基于构建的路由注意事项references/browser-design-runtime.md- 非 SAP 浏览器预览运行时、sidecar 配置和 Agent 迭代导出references/css-and-styling-compliance.md- 基于 SAP Help 的 CSS、主题、Shadow DOM 和生成 Widget 打包指南references/sac-import-packaging-lessons.md- SAC 托管的 Resource-ZIP 上传顺序、URL 规则、ZIP 规范、构建器/树状态规则、自包含组件检查、最终产物测试和 SAC 错误分类references/widget-discovery-intake.md- Widget 角色/数据源选择、附件接收、Widget 简介和托管工具防护措施references/production-widget-lessons.md- 在租户环境中观察到的上传失败、脚本方法限制、完整性、隔离、二分排查和预检防护references/property-lifecycle.md- SAC 属性规范化、脚本方法边界、有状态编辑器、持久化和结构化数据规则references/verification-and-artifacts.md- 构建包验证、测试盲区、变更证据、上传问题分类和确定性产物检查
官方文档链接
主要参考资料(用于技能更新):
示例微件:
版本历史
未发布
- 根据汇总的自定义微件经验,新增属性生命周期和工件验证指南,包括规范化强制转换、有状态面板编辑、运行时使用检查、真实浏览器边界以及确定性的最终打包检查
- 澄清托管模式 URL 验证、危险 Unicode/控制码点扫描、已声明的区域设置处理,以及缺少工具时的验证结果
- 新增生产审计经验,涵盖控制字符导致的上传失败、仅包含属性的 Analytics Designer 方法体、必需的完整性状态、不透明错误二分法、隔离的图标/字体、书签风险以及行为预检
- 修正 JSON 方法指南,确保清单中的方法体不会调用 Web 组件内部实现
- 新增符合企业安全要求的
templates/local-builder/脚手架,用于本地微件元数据、属性/数据馈送配置,以及 SAC 两文件工件导出 - 新增
templates/builder-panel.js,使构建器面板生成具备打包在内的独立模板 - 新增本地构建器验证覆盖,但不推进
last_verified;SAC 实际上传/运行时验证仍待完成 - 新增 SAP 示例微件经验和本地构建器模式提示,涵盖数据绑定图表、KPI/仪表盘微件、流程/层级微件、输入工具、Widget Add-ons,以及基于构建的应用,且不复制上游示例代码
v2.3.2(2026-07-06)
- 新增来自 Configurable Menu Navigation 项目的 SAC Resource-ZIP 导入经验
- 澄清
widget.json与 Resource-ZIP 的独立上传流程、相对于根目录的 SAC 托管 URL、Resource-ZIP 内容规范,以及简单颜色属性的可移植性 - 新增针对裸 Resource-ZIP 组件 URL 和高风险
Color属性用法的钩子警告 - 扩展 Configurable Menu Navigation 经验,涵盖构建器焦点/折叠状态、树形结构重复 ID 重写、自包含组件 JS、预览一致性、过时面板清理、布局/样式属性同步、安全输出清理以及工件命名
- 要求最终聊天交接时,将
widget.json清单和 Resource-ZIP 作为两个独立的可下载工件提供
v2.1.0(2026-06-12)
- 更新至 SAC 2026 年第 2 季度(版本 2026.8)
- 2026 年 QRC1/QRC2 未对自定义微件框架进行更改;生命周期函数和 JSON 架构保持不变
- 记录此前缺失的根级属性:
eula、imports、supportsMobile、supportsExport、supportsLinkedAnalysisFilterOnSelection、supportsViewportLoading、supportsBookmark、types - 记录用于 ES 模块加载的 webcomponent
type属性 - 记录每个属性的
includeInBookmarks标志,以及boolean[]/integer[]类型 - 在高级主题中新增
serializeCustomWidgetToImage()和customWidgetRenderComplete - 确认:四个生命周期函数均未更改,数据馈送类型未更改,模板有效
v2.0.0(2025-12-27)
- 新增 3 个专用 Agent:widget-architect、widget-debugger、widget-api-assistant
- 新增 3 个斜杠命令:/widget-validate、/widget-generate、/widget-lint
- 新增验证钩子,在 Write/Edit 时自动执行质量检查
- 在 templates/ 目录中新增 5 个经过文档审查的模板
- 增强插件结构,使其符合完整的插件模式
- 更新最后验证日期 v1.2.0(2025-11-26)
- 将 SAC 版本参考更新为 2025.21
- 将 SKILL.md 的长度从 563 行优化至约 200 行
- 为全部 8 个参考文件添加目录
- 改进渐进式披露架构
v1.1.0(2025-11-22)
- 添加 Widget Add-On 功能文档(QRC Q4 2023+)
- 添加最佳实践指南(性能、安全、开发)
- 添加高级主题(自定义类型、脚本 API 类型、安装)
- 在描述中添加更多关键词
- 将错误预防覆盖范围扩大至 25+
v1.0.0(2025-11-22)
- 初始版本
- 完整的 JSON 元数据参考
- 生命周期函数文档
- 数据绑定指南
- 样式面板实现
- 托管选项(SAC 托管、GitHub、外部)
- 安全性(完整性哈希、CORS)
- 常见错误和调试
SAC 版本:2026.8