开发指南:从 TypeScript 组件模板到 Storybook 组件库实战)
coze-studio 工作流属性设置器Setters开发指南从 TypeScript 组件模板到 Storybook 组件库实战【免费下载链接】coze-studioAn AI agent development platform with all-in-one visual tools, simplifying agent creation, debugging, and deployment like never before. Coze your way to AI Agent creation.项目地址: https://gitcode.com/GitHub_Trending/co/coze-studio本文以frontend/packages/workflow/setters包的 README.md 为骨架结合其全部源码、配置与测试系统讲解 coze-studio 工作流节点属性设置器Setter的设计模式、七个内置组件的用法与源码实现、单元测试与 Storybook 开发调试流程以及基于脚手架脚本快速新增自定义 Setter 的完整方法。读完本文你将能够在 coze-studio 前端工程中独立开发、测试、调试并集成一个工作流属性设置器。一、包概览coze-workflow/setters 是什么coze-workflow/setters是 coze-studio 前端工作流子仓库frontend/packages/workflow中面向 React 组件的属性设置器Setter开发包。它本质上是一个React 组件 Storybook的项目模板与组件库上层工作流画布如flowgram-adapter/free-layout-editor驱动的节点编辑器在渲染某个节点时会根据节点属性类型选择对应的 Setter 组件把value、onChange、readonly等约定好的 props 注入进去从而把节点属性如何编辑这件事从画布内核中解耦出来。在 coze-studio 中工作流节点如大模型、知识库、代码执行等节点的每个输入参数都对应一个属性编辑控件Setter 包正是这些控件的统一载体。它的命名、结构与约束由 src/types.ts 中定义的Setter类型确立import { type SetterComponentProps } from flowgram-adapter/free-layout-editor; type SetterPropsValue, CustomProps { value?: Value; // 当前属性值受控组件 onChange?: (value: Value) void; // 值变化回调 readonly?: boolean; // 只读模式画布预览/详情场景 children?: React.ReactNode; context?: SetterComponentProps[context]; // 画布注入的节点上下文node/meta 等 testId?: string; } CustomProps; export type SetterValue unknown, CustomOptions NonNullableunknown React.FCSetterPropsValue, CustomOptions;可以看出每个 Setter 都是一个标准受控 React 组件遵循value入、onChange出的约定context直接复用画布编辑器flowgram-adapter/free-layout-editor的SetterComponentProps[context]类型保证了设置器与画布运行时上下文的无缝衔接。这正对应 README 中 Project template for react component with storybook 的定位既是一个可供 Storybook 独立开发调试的组件模板也是可被工作流画布消费的运行时组件库。二、工程特性与命令快速上手开发环境README 的 Features 部分明确列出该包已具备的工程能力仓库配置也逐一印证eslint ts代码规范与类型检查齐备。根目录的 eslint.config.js 提供 lint 规则package.json中lint脚本为eslint ./ --cachetsconfig.json、tsconfig.misc.json与 tsconfig.build.json 提供严格的 TS 构建配置遵循工作区统一的coze-arch/ts-config。esm bundle / umd bundleREADME 宣称支持 esm 与 umd 两种打包产物以适配不同消费方式模块化引入或直接全局引入。从当前 package.json 看build脚本目前为占位实现exit 0构建能力由工作区统一工具链rsbuild/core、vite、vite-plugin-svgr、vite-tsconfig-paths等均在 devDependencies 中提供说明该包作为工作区内的源码直连包main/types均指向src/index.ts被其他包通过 workspace 协议消费。storybookStorybook 7storybook/react、storybook/react-vite、addon-essentials、addon-interactions、addon-links、addon-onboarding、blocks、preview-api、test等完整配置于 .storybook/main.js 与 .storybook/preview.js。包 package.json 提供的核心命令如下表命令脚本说明rush update—初始化安装/更新 workspace 依赖README 中的 init 命令npm run devstorybook dev -p 6006开发模式启动 Storybook监听 6006 端口npm run buildexit 0构建当前为占位实现由工作区工具链统一处理npm run linteslint ./ --cacheESLint 静态检查带缓存加速npm run testvitest --run --passWithNoTests单元测试vitest 单次运行无测试时也通过npm run test:covnpm run test -- --coverage单元测试 v8 覆盖率报告依赖设计上运行时依赖仅有coze-arch/coze-designCoze 统一设计系统、coze-arch/i18n、douyinfe/semi-ui、flowgram-adapter/free-layout-editor画布适配层、tanstack/react-query、classnames与nanoidReact 通过peerDependencies声明18.2.0避免多实例冲突。测试环境由 vitest.config.ts基于coze-arch/vitest-config与testing-library/react、testing-library/jest-dom、testing-library/user-event、vitest、vitest/coverage-v8支撑该包也纳入 config/rush-project.json 的 Rush 工程管理可被rush update/rush build统一编排。使用前提说明以上命令均需在已执行过rush update的 frontend 工作区环境中运行Storybook 开发模式需确保 6006 端口可用。三、内置 Setter 组件族七个组件逐一拆解包入口 src/index.ts 统一导出全部组件与类型export { String } from ./string; export type { StringOptions } from ./string; export { Number } from ./number; export type { NumberOptions } from ./number; export { Text } from ./text; export type { TextOptions } from ./text; export { Boolean } from ./boolean; export { Enum } from ./enum; export type { EnumOptions } from ./enum; export { Array } from ./array; export { useArraySetterItemContext } from ./array/array-context; export type { ArrayOptions } from ./array; export { EnumImageModel } from ./enum-image-model; export type { EnumImageModelOptions } from ./enum-image-model; export { Setter } from ./types;下面按目录逐个解读组件职责、Options 参数与源码实现要点。3.1 String单行文本输入src/stringsrc/string/string.tsx 基于coze-arch/coze-design的Input封装StringOptions参数参数类型默认值说明placeholderstring—输入框占位提示widthnumber \| stringauto控件宽度maxCountnumber—最大输入长度传入后输入框右侧显示已输入/上限计数textModebooleanfalse纯文本展示模式源码注释说明readonly 样式下仍会渲染出文本框某些场景需要只展示文本此时开启该模式直接渲染div文本testIdstring—供自动化测试定位 DOM 的data-testid实现要点handleChange直接透传新值调用onChangetextMode为真时返回带样式的纯文本div否则渲染Input并通过cxclassnames在readonly时追加只读样式类。3.2 Number数字输入 / 滑块src/numbersrc/number/number.tsx 支持两种模式NumberOptions参数类型默认值说明placeholderstring—数字输入框占位widthnumber \| string100%控件宽度stepnumber—步进值max/minnumber—数值上下限modeinput \| sliderinputinput用CozInputNumberslider用Slider滑块sizesmall \| defaultdefault输入框尺寸styleReact.CSSProperties{}附加行内样式实现要点两种模式的handleChange都只接受number类型新值且readonly时拒绝任何修改回调双重防护保证只读语义在数值控件上的严格生效。3.3 Text多行文本域src/textsrc/text/text.tsx 基于TextArea封装TextOptions支持placeholder、width默认100%、maxCount透传给TextArea的maxLength与maxCount用于字数上限与计数展示readonly时同样通过 classnames 追加只读样式。3.4 Boolean开关切换src/booleansrc/boolean/boolean.tsx 是七个组件中最精简的实现——整个组件仅一行 JSXexport const Boolean: Setterboolean ({ value, onChange, readonly }) ( Switch checked{value} onChange{onChange} disabled{readonly} / );直接基于coze-arch/coze-design的Switch开关组件readonly映射为disabled无任何附加 Options。这个极简实现恰好体现了 Setter 约定的价值画布只关心统一 props 契约具体 UI 细节完全封装在组件内部。3.5 Enum下拉单选src/enumsrc/enum/enum.tsx 基于Select封装EnumOptions需要调用方提供options选项列表类型定义于 src/enum/types.tsOptions与EnumValue。核心实现Select placeholder{placeholder} className{cx({ [styles.readonly]: readonly })} optionList{options} style{{ width }} value{value} onChange{v onChange?.(v as EnumValue)} /value与onChange的值类型统一为EnumValuewidth默认100%readonly通过只读样式类呈现。3.6 EnumImageModel带缩略图与 tooltip 的模型选择src/enum-image-modelsrc/enum-image-model/enum-image-model.tsx 是面向模型选择这类场景的增强版下拉选项可携带图片缩略图、禁用态与 tooltip类型定义见 src/enum-image-model/types.ts。其实现把每个 option 的label替换为 enum-image-model-label.tsx 渲染的缩略图 文本 tooltip组合节点并通过renderSelectedItem让已选中项同样展示缩略图还支持showClear清空onClear时回调onChange?.(undefined)与validateStatus校验态。这在工作流中通常用于选择模型/图片类枚举的参数面板。3.7 Array数组/对象列表编辑器src/arraysrc/array/array.tsx 是七个组件中最复杂的容器型 Setter用于编辑数组型属性如工作流节点的输入参数列表通过children插槽把每一条目如何编辑交给上层例如用 String/Number 等子 Setter 拼装自身负责增删管理与列头布局。ArrayOptions参数类型默认值说明disableAddbooleanfalse是否禁用添加按钮getDefaultAppendValue() any—添加新条目时生成默认值的工厂函数fieldsField[][]列定义非空时渲染列头column-titles.tsxmaxItemsnumberNumber.MAX_SAFE_INTEGER最大条目数达到后隐藏添加按钮minItemsnumber0最小条目数达到后禁止删除disableDeleteItem((value, index) boolean) \| boolean() false单条删除开关可传函数按条目动态判断实现要点后端返回的数组值可能为null源码中特别以const originValue value || [];兜底注释明确说明后端返回 null 时不会被赋值为[]此处是最后防线add()调用getDefaultAppendValue?.() || {}生成默认条目并追加到数组末尾remove()通过splice删除指定下标添加按钮的显示条件为!disableAdd !readonly length maxItems删除按钮的显示由calcShowDeleteButton综合readonly、minItems与disableDeleteItem布尔或函数计算每个条目外层用ArraySetterItemContextProvidersrc/array/array-context.ts注入{ currentAddIndex, currentIndex }子 Setter 可通过导出的useArraySetterItemContextHook 感知自己在数组中的下标——这是数组内子条目联动的关键机制。四、从测试到 Storybook双重验证的开发闭环4.1 单元测试vitest Testing Library每个基础组件目录下都带有index.test.tsx单元测试string、number、text、boolean、enum基于 vitest 与testing-library/react编写。以 src/string/index.test.tsx 这类测试为例典型模式如下来自脚手架生成的模板import testing-library/jest-dom; import { describe, it, expect, vi } from vitest; import { render, screen, fireEvent } from testing-library/react; const mockProps { value: , onChange: vi.fn(), readonly: false, }; describe(String Setter, () { it(renders correctly with default props, () { const { container } render(String {...mockProps} /); expect(container.firstChild).toBeInTheDocument(); }); });测试从 Setter 的统一契约出发value/onChange/readonly三件套验证组件能正确渲染与交互配合npm run testvitest --run在 CI 或本地一次性执行。test:cov可输出 v8 覆盖率报告。这是保证每个 Setter 符合画布 props 约定的自动化防线。4.2 Storybook6006 端口的交互式开发Storybook 是本包 README 强调的react component storybook模板核心。每个组件目录下的index.stories.tsx定义交互式 Demo典型模板见 scripts/create-setter.js 生成的 stories 文件import type { StoryObj, Meta } from storybook/react; import { useArgs } from storybook/preview-api; const meta: Metatypeof String { title: workflow setters/String, component: String, tags: [autodocs], parameters: { layout: centered }, render: args { const [, updateArgs] useArgs(); return ( String {...args} onChange{newValue { updateArgs({ ...args, value: newValue }); }} / ); }, }; export default meta; type Story StoryObjtypeof String; export const Base: Story {};要点useArgs把 onChange 的结果同步回 Storybook 的 args实现画布内所见即所得的交互预览tags: [autodocs]启用自动文档生成运行npm run dev后在浏览器打开http://localhost:6006即可按workflow setters/*分组逐个调试组件。五、扩展指南用脚手架快速新增自定义 SetterREADME 虽未展开说明扩展方式但仓库自带的脚手架脚本 scripts/create-setter.js 提供了官方的新增 Setter流程。脚本用法node scripts/create-setter.js setterName执行后会在src/setterName/下自动生成五类文件并自动更新包入口生成文件内容index.tsexport { PascalName } from ./name; export type { PascalNameOptions } ...name.tsx基于Setterstring, PascalNameOptions的最小实现骨架含value/onChange/readonly/options解构与 module.less 样式引用index.stories.tsxStorybook Meta Base故事标题为workflow setters/PascalNameindex.test.tsxvitest Testing Library 的最小渲染冒烟测试mockvalue/onChange/readonlyname.module.less空样式模块注释// Your styles here随后脚本会把export { PascalName } ...追加到 src/index.ts 末尾新 Setter 即刻对全工作区可见。基于生成骨架你可以参考内置组件的实现进一步扩展若为纯展示/简单交互可仿照 Boolean 用一行 JSX 完成若需要复杂 Options仿照 Number/Enum 定义XxxOptions接口并在 src/types.ts 的SetterValue, CustomOptions中声明类型参数若需要操作数组可基于 Array 组合用useArraySetterItemContext感知条目下标实现每个条目独立编辑的表单网格。六、设计模式总结与最佳实践从七个内置组件的源码可以提炼出本包的设计约定供后续扩展遵循统一受控契约所有 Setter 都实现SetterValue, Options通过value/onChange/readonly/context/testId与画布交互见 src/types.ts上层画布无需关心具体 UI 细节。只读语义全局一致Boolean 用disabled禁用Number 在handleChange内拦截String/Text/Enum/EnumImageModel 通过readonly样式类呈现Array 隐藏添加按钮并逐条计算删除按钮——四种策略覆盖交互型、展示型与容器型组件。基础控件统一收敛全部基于coze-arch/coze-designInput、TextArea、Switch、Select、Slider、CozInputNumber、IconButton 等构建保证与 Coze 设计系统一致的外观与无障碍行为。容器组件拥抱插槽Array 通过children Context 机制把条目编辑外包给上层自身专注增删与布局是最易扩展的复合模式。开发闭环标配每个组件配套index.stories.tsxStorybook 交互 Demo autodocs与index.test.tsxvitest 冒烟测试新组件经由 scripts/create-setter.js 一键生成保证工程纪律不因组件增多而退化。如果你需要在 coze-studio 工作流节点面板中增加一种新的属性编辑能力推荐的落地路径是node scripts/create-setter.js yourSetter生成骨架 → 参照上述任一内置组件完善 UI 与 Options → 补充 stories 与单测 →npm run dev在 Storybook 中交互验证 →npm run test跑通回归 → 在 src/index.ts 确认导出后即可在frontend/packages/workflow的节点配置层通过统一契约接入画布。【免费下载链接】coze-studioAn AI agent development platform with all-in-one visual tools, simplifying agent creation, debugging, and deployment like never before. Coze your way to AI Agent creation.项目地址: https://gitcode.com/GitHub_Trending/co/coze-studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考