feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { mergeConfig } from 'vite';
|
||||
import svgr from 'vite-plugin-svgr';
|
||||
|
||||
/** @type { import('@storybook/react-vite').StorybookConfig } */
|
||||
const config = {
|
||||
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.tsx'],
|
||||
addons: [
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-onboarding',
|
||||
'@storybook/addon-interactions',
|
||||
],
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {},
|
||||
},
|
||||
docs: {
|
||||
autodocs: 'tag',
|
||||
},
|
||||
viteFinal: config =>
|
||||
mergeConfig(config, {
|
||||
plugins: [
|
||||
svgr({
|
||||
svgrOptions: {
|
||||
native: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
};
|
||||
export default config;
|
||||
@@ -0,0 +1,14 @@
|
||||
/** @type { import('@storybook/react').Preview } */
|
||||
const preview = {
|
||||
parameters: {
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default preview;
|
||||
@@ -0,0 +1,5 @@
|
||||
const { defineConfig } = require('@coze-arch/stylelint-config');
|
||||
|
||||
module.exports = defineConfig({
|
||||
extends: [],
|
||||
});
|
||||
16
frontend/packages/workflow/adapter/code-editor/README.md
Normal file
16
frontend/packages/workflow/adapter/code-editor/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# @coze-workflow/code-editor-adapter
|
||||
|
||||
> Project template for react component with storybook.
|
||||
|
||||
## Features
|
||||
|
||||
- [x] eslint & ts
|
||||
- [x] esm bundle
|
||||
- [x] umd bundle
|
||||
- [x] storybook
|
||||
|
||||
## Commands
|
||||
|
||||
- init: `rush update`
|
||||
- dev: `npm run dev`
|
||||
- build: `npm run build`
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"operationSettings": [
|
||||
{
|
||||
"operationName": "test:cov",
|
||||
"outputFolderNames": ["coverage"]
|
||||
},
|
||||
{
|
||||
"operationName": "ts-check",
|
||||
"outputFolderNames": ["dist"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const { defineConfig } = require('@coze-arch/eslint-config');
|
||||
|
||||
module.exports = defineConfig({
|
||||
packageRoot: __dirname,
|
||||
preset: 'web',
|
||||
rules: {},
|
||||
});
|
||||
47
frontend/packages/workflow/adapter/code-editor/package.json
Normal file
47
frontend/packages/workflow/adapter/code-editor/package.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "@coze-workflow/code-editor-adapter",
|
||||
"version": "0.0.1",
|
||||
"description": "code editor",
|
||||
"license": "Apache-2.0",
|
||||
"author": "liji.leej@bytedance.com",
|
||||
"maintainers": [],
|
||||
"main": "src/index.tsx",
|
||||
"scripts": {
|
||||
"build": "exit 0",
|
||||
"lint": "eslint ./ --cache",
|
||||
"test": "vitest --run --passWithNoTests",
|
||||
"test:cov": "npm run test -- --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.4.1",
|
||||
"@codemirror/view": "^6.34.1",
|
||||
"@coze-arch/coze-design": "0.0.6-alpha.346d77",
|
||||
"@coze-arch/i18n": "workspace:*",
|
||||
"@coze-editor/editor": "0.1.0-alpha.d92d50",
|
||||
"@coze-workflow/base": "workspace:*",
|
||||
"classnames": "^2.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@coze-arch/bot-typings": "workspace:*",
|
||||
"@coze-arch/eslint-config": "workspace:*",
|
||||
"@coze-arch/stylelint-config": "workspace:*",
|
||||
"@coze-arch/ts-config": "workspace:*",
|
||||
"@coze-arch/vitest-config": "workspace:*",
|
||||
"@testing-library/jest-dom": "^6.1.5",
|
||||
"@testing-library/react": "^14.1.2",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@types/react": "18.2.37",
|
||||
"@types/react-dom": "18.2.15",
|
||||
"@vitest/coverage-v8": "~3.0.5",
|
||||
"react": "~18.2.0",
|
||||
"react-dom": "~18.2.0",
|
||||
"stylelint": "^15.11.0",
|
||||
"vite-plugin-svgr": "~3.3.0",
|
||||
"vitest": "~3.0.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18.2.0",
|
||||
"react-dom": ">=18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useRef, useState } from 'react';
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozWarningCircleFill } from '@coze-arch/coze-design/icons';
|
||||
import { Modal } from '@coze-arch/coze-design';
|
||||
|
||||
import { Layout } from '../layout';
|
||||
import { type EditorProps, type LanguageType } from '../../interface';
|
||||
import { Editor } from './editor';
|
||||
|
||||
export const BizEditor = (props: EditorProps) => {
|
||||
const editorApi = useRef<undefined | { getValue?: () => string }>(undefined);
|
||||
|
||||
const [language, setLanguage] = useState<LanguageType>(props.defaultLanguage);
|
||||
const [content, setContent] = useState<string | undefined>(
|
||||
props.defaultContent,
|
||||
);
|
||||
|
||||
const handleLanguageChange = (value: LanguageType) => {
|
||||
const langTemplate = props.languageTemplates?.find(
|
||||
e => e.language === value,
|
||||
);
|
||||
|
||||
const preLangTemplate = props.languageTemplates?.find(
|
||||
e => e.language === language,
|
||||
);
|
||||
|
||||
if (preLangTemplate?.template === editorApi.current?.getValue?.()) {
|
||||
setLanguage(value);
|
||||
setContent(langTemplate?.template);
|
||||
props.onChange?.(langTemplate?.template || '', value);
|
||||
return;
|
||||
}
|
||||
|
||||
Modal.warning({
|
||||
icon: (
|
||||
<IconCozWarningCircleFill
|
||||
style={{ color: 'rgba(var(--coze-yellow-5), 1)' }}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('code_node_switch_language'),
|
||||
content: I18n.t('code_node_switch_language_description'),
|
||||
okType: 'warning',
|
||||
okText: I18n.t('Confirm'),
|
||||
cancelText: I18n.t('Cancel'),
|
||||
closable: true,
|
||||
width: 448,
|
||||
height: 160,
|
||||
onOk: () => {
|
||||
setLanguage(value);
|
||||
setContent(langTemplate?.template);
|
||||
props.onChange?.(langTemplate?.template || '', value);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Layout
|
||||
{...props}
|
||||
language={language}
|
||||
onLanguageSelect={handleLanguageChange}
|
||||
>
|
||||
<Editor
|
||||
{...props}
|
||||
defaultContent={content}
|
||||
language={language}
|
||||
didMount={api => {
|
||||
editorApi.current = api;
|
||||
}}
|
||||
/>
|
||||
</Layout>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { type FC, lazy, Suspense, useMemo } from 'react';
|
||||
|
||||
import { type EditorOtherProps, type EditorProps } from '../../interface';
|
||||
|
||||
const LazyPythonEditor: FC<EditorProps> = lazy(async () => {
|
||||
const { PythonEditor } = await import('./python-editor');
|
||||
return { default: PythonEditor };
|
||||
});
|
||||
|
||||
const PythonEditor: FC<EditorProps> = props => (
|
||||
<Suspense>
|
||||
<LazyPythonEditor {...props} />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
const LazyTypescriptEditor: FC<EditorProps> = lazy(async () => {
|
||||
const { TypescriptEditor } = await import('./typescript-editor');
|
||||
return { default: TypescriptEditor };
|
||||
});
|
||||
|
||||
const TypescriptEditor: FC<EditorProps> = props => (
|
||||
<Suspense>
|
||||
<LazyTypescriptEditor {...props} />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
export const Editor = (props: EditorProps & EditorOtherProps) => {
|
||||
const language = useMemo(
|
||||
() => props.language || props.defaultLanguage,
|
||||
[props.defaultLanguage, props.language],
|
||||
);
|
||||
|
||||
if (language === 'python') {
|
||||
return <PythonEditor {...props} />;
|
||||
}
|
||||
|
||||
return <TypescriptEditor {...props} />;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { Editor } from './editor';
|
||||
export { BizEditor } from './biz-editor';
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { api, type InferEditorAPIFromPlugins } from '@coze-editor/editor/react';
|
||||
import preset from '@coze-editor/editor/preset-code';
|
||||
import { type EditorView } from '@codemirror/view';
|
||||
|
||||
// 忽略 readOnly 强制设置值
|
||||
const forceSetValue =
|
||||
({ view }: { view: EditorView }) =>
|
||||
(value: string) => {
|
||||
const { state } = view;
|
||||
view.dispatch(
|
||||
state.update({
|
||||
changes: {
|
||||
from: 0,
|
||||
to: state.doc.length,
|
||||
insert: value ?? '',
|
||||
},
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const customPreset = [...preset, api('forceSetValue', forceSetValue)];
|
||||
|
||||
export type EditorAPI = InferEditorAPIFromPlugins<typeof customPreset>;
|
||||
|
||||
export default customPreset;
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { Renderer, EditorProvider } from '@coze-editor/editor/react';
|
||||
import { languages } from '@coze-editor/editor/preset-code';
|
||||
import { python } from '@coze-editor/editor/language-python';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
|
||||
import { type EditorOtherProps, type EditorProps } from '../../interface';
|
||||
import preset from './preset';
|
||||
|
||||
languages.register('python', python);
|
||||
|
||||
export const PythonEditor = (props: EditorProps & EditorOtherProps) => {
|
||||
const {
|
||||
defaultContent,
|
||||
uuid,
|
||||
readonly,
|
||||
height,
|
||||
didMount,
|
||||
onChange,
|
||||
defaultLanguage,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<EditorProvider>
|
||||
<Renderer
|
||||
plugins={preset}
|
||||
domProps={{
|
||||
style: {
|
||||
height: 'calc(100% - 48px)',
|
||||
},
|
||||
}}
|
||||
didMount={api => {
|
||||
didMount?.(api);
|
||||
api.$on('change', ({ value }) => {
|
||||
onChange?.(value, defaultLanguage);
|
||||
});
|
||||
}}
|
||||
defaultValue={defaultContent}
|
||||
extensions={[
|
||||
EditorView.theme({
|
||||
'&.cm-focused': {
|
||||
outline: 'none',
|
||||
},
|
||||
'&.cm-editor': {
|
||||
height: height || 'unset',
|
||||
},
|
||||
'.cm-content': {
|
||||
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
||||
},
|
||||
'.cm-content *': {
|
||||
fontFamily: 'inherit',
|
||||
},
|
||||
}),
|
||||
]}
|
||||
options={{
|
||||
uri: `file:///py_editor_${uuid}.py`,
|
||||
languageId: 'python',
|
||||
theme: 'code-editor-dark',
|
||||
height,
|
||||
readOnly: readonly,
|
||||
editable: !readonly,
|
||||
fontSize: 12,
|
||||
tabSize: 4,
|
||||
}}
|
||||
/>
|
||||
</EditorProvider>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ViewVariableType } from '@coze-workflow/base';
|
||||
import { languages } from '@coze-editor/editor/preset-code';
|
||||
import { typescript } from '@coze-editor/editor/language-typescript';
|
||||
|
||||
import { type Input, ModuleDetectionKind, type Output } from '../../interface';
|
||||
|
||||
export const initTypescriptServer = () => {
|
||||
languages.register('typescript', typescript);
|
||||
|
||||
const tsWorker = new Worker(
|
||||
new URL('@coze-editor/editor/language-typescript/worker', import.meta.url),
|
||||
{ type: 'module' },
|
||||
);
|
||||
|
||||
typescript.languageService.initialize(tsWorker, {
|
||||
compilerOptions: {
|
||||
// eliminate Promise error
|
||||
lib: ['es2015'],
|
||||
moduleDetection: ModuleDetectionKind.Force,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const mapVariableType = (type?: ViewVariableType): string => {
|
||||
switch (type) {
|
||||
case ViewVariableType.String:
|
||||
return 'string';
|
||||
case ViewVariableType.Integer:
|
||||
return 'number';
|
||||
case ViewVariableType.Boolean:
|
||||
return 'boolean';
|
||||
case ViewVariableType.Number:
|
||||
return 'number';
|
||||
case ViewVariableType.Object:
|
||||
return 'object';
|
||||
case ViewVariableType.Image:
|
||||
case ViewVariableType.File:
|
||||
case ViewVariableType.Doc:
|
||||
case ViewVariableType.Code:
|
||||
case ViewVariableType.Ppt:
|
||||
case ViewVariableType.Txt:
|
||||
case ViewVariableType.Excel:
|
||||
case ViewVariableType.Audio:
|
||||
case ViewVariableType.Zip:
|
||||
case ViewVariableType.Video:
|
||||
case ViewVariableType.Svg:
|
||||
case ViewVariableType.Voice:
|
||||
return 'string'; // Assuming file-like types are represented as strings (e.g., file paths or URLs)
|
||||
case ViewVariableType.Time:
|
||||
return 'Date';
|
||||
case ViewVariableType.ArrayString:
|
||||
return 'string[]';
|
||||
case ViewVariableType.ArrayInteger:
|
||||
return 'number[]';
|
||||
case ViewVariableType.ArrayBoolean:
|
||||
return 'boolean[]';
|
||||
case ViewVariableType.ArrayNumber:
|
||||
return 'number[]';
|
||||
case ViewVariableType.ArrayObject:
|
||||
return 'object[]';
|
||||
case ViewVariableType.ArrayImage:
|
||||
case ViewVariableType.ArrayFile:
|
||||
case ViewVariableType.ArrayDoc:
|
||||
case ViewVariableType.ArrayCode:
|
||||
case ViewVariableType.ArrayPpt:
|
||||
case ViewVariableType.ArrayTxt:
|
||||
case ViewVariableType.ArrayExcel:
|
||||
case ViewVariableType.ArrayAudio:
|
||||
case ViewVariableType.ArrayZip:
|
||||
case ViewVariableType.ArrayVideo:
|
||||
case ViewVariableType.ArraySvg:
|
||||
case ViewVariableType.ArrayVoice:
|
||||
return 'string[]';
|
||||
case ViewVariableType.ArrayTime:
|
||||
return 'Date[]';
|
||||
default:
|
||||
return 'any'; // Fallback type
|
||||
}
|
||||
};
|
||||
|
||||
export function generateTypeDefinition(output: Output, indent = ' '): string {
|
||||
let definition = '';
|
||||
|
||||
if (output.type === ViewVariableType.Object) {
|
||||
definition += `${indent}${output.name}: {\n`;
|
||||
if (output.children && output.children.length > 0) {
|
||||
output.children.forEach(child => {
|
||||
definition += `${indent} ${generateTypeDefinition(child, `${indent} `)}`;
|
||||
});
|
||||
}
|
||||
|
||||
definition += `${indent}}\n`;
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
if (output.type === ViewVariableType.ArrayObject) {
|
||||
definition += `${indent}${output.name}: {\n`;
|
||||
if (output.children && output.children.length > 0) {
|
||||
output.children.forEach(child => {
|
||||
definition += `${indent} ${generateTypeDefinition(child, `${indent} `)}`;
|
||||
});
|
||||
definition += `${indent}}[]\n`;
|
||||
}
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
definition += `${indent}${output.name}: ${mapVariableType(output.type)};\n`;
|
||||
|
||||
definition += '\n';
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
export const initInputAndOutput = async (
|
||||
inputs: Input[] = [],
|
||||
outputs: Output[] = [],
|
||||
uuid = '',
|
||||
): Promise<void> => {
|
||||
const typeDefinition = `
|
||||
declare module '/ts_editor_${uuid}' {
|
||||
interface Args {
|
||||
${generateTypeDefinition(
|
||||
{
|
||||
name: 'params',
|
||||
type: ViewVariableType.Object,
|
||||
children: inputs,
|
||||
},
|
||||
' ',
|
||||
)}
|
||||
}
|
||||
|
||||
interface Output {
|
||||
${outputs.map(output => generateTypeDefinition(output, ' ')).join('\n')}
|
||||
}
|
||||
}
|
||||
|
||||
export {}
|
||||
`;
|
||||
|
||||
await typescript.languageService.addExtraFiles({
|
||||
[`/ts_editor_${uuid}.d.ts`]: typeDefinition,
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { Renderer, EditorProvider } from '@coze-editor/editor/react';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
|
||||
import { type EditorOtherProps, type EditorProps } from '../../interface';
|
||||
import {
|
||||
initInputAndOutput,
|
||||
initTypescriptServer,
|
||||
} from './typescript-editor-utils';
|
||||
import preset from './preset';
|
||||
|
||||
initTypescriptServer();
|
||||
|
||||
export const TypescriptEditor = (props: EditorProps & EditorOtherProps) => {
|
||||
const {
|
||||
defaultContent,
|
||||
uuid,
|
||||
readonly,
|
||||
height,
|
||||
didMount,
|
||||
onChange,
|
||||
defaultLanguage,
|
||||
input,
|
||||
output,
|
||||
} = props;
|
||||
|
||||
const uri = `file:///ts_editor_${uuid}.ts`;
|
||||
|
||||
useEffect(() => {
|
||||
initInputAndOutput(input, output, uuid);
|
||||
}, [uuid]);
|
||||
|
||||
return (
|
||||
<EditorProvider>
|
||||
<Renderer
|
||||
plugins={preset}
|
||||
domProps={{
|
||||
style: {
|
||||
height: 'calc(100% - 48px)',
|
||||
},
|
||||
}}
|
||||
didMount={api => {
|
||||
didMount?.(api);
|
||||
api.$on('change', ({ value }) => {
|
||||
onChange?.(value, defaultLanguage);
|
||||
});
|
||||
}}
|
||||
defaultValue={defaultContent}
|
||||
extensions={[
|
||||
EditorView.theme({
|
||||
'&.cm-focused': {
|
||||
outline: 'none',
|
||||
},
|
||||
'&.cm-editor': {
|
||||
height: height || 'unset',
|
||||
},
|
||||
'.cm-content': {
|
||||
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
||||
},
|
||||
'.cm-content *': {
|
||||
fontFamily: 'inherit',
|
||||
},
|
||||
}),
|
||||
]}
|
||||
options={{
|
||||
uri,
|
||||
languageId: 'typescript',
|
||||
theme: 'code-editor-dark',
|
||||
height,
|
||||
readOnly: readonly,
|
||||
editable: !readonly,
|
||||
fontSize: 12,
|
||||
tabSize: 4,
|
||||
}}
|
||||
/>
|
||||
</EditorProvider>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useMemo, type ReactNode } from 'react';
|
||||
|
||||
import { concatTestId, useNodeTestId } from '@coze-workflow/base';
|
||||
import {
|
||||
IconCozCodeFill,
|
||||
IconCozPlayCircle,
|
||||
IconCozSideCollapse,
|
||||
} from '@coze-arch/coze-design/icons';
|
||||
import {
|
||||
Select,
|
||||
Tooltip,
|
||||
Button,
|
||||
IconButton,
|
||||
Typography,
|
||||
} from '@coze-arch/coze-design';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
import { type EditorProps, type LanguageType } from '../../interface';
|
||||
|
||||
import style from './style.module.less';
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
const HELP_DOCUMENT_LINK = IS_OVERSEA
|
||||
? '/docs/guides/code_node?_lang=en'
|
||||
: '/docs/guides/code_node';
|
||||
|
||||
interface Props extends EditorProps {
|
||||
children: ReactNode;
|
||||
onLanguageSelect?: (language: LanguageType) => void;
|
||||
language: LanguageType;
|
||||
}
|
||||
|
||||
export const Layout = ({
|
||||
children,
|
||||
title,
|
||||
language,
|
||||
onClose,
|
||||
onTestRun,
|
||||
testRunIcon,
|
||||
onLanguageSelect,
|
||||
languageTemplates,
|
||||
}: Props) => {
|
||||
const optionList = useMemo(
|
||||
() =>
|
||||
languageTemplates?.map(e => ({
|
||||
value: e.language,
|
||||
label: e.displayName,
|
||||
})),
|
||||
[languageTemplates],
|
||||
);
|
||||
|
||||
const { getNodeSetterId } = useNodeTestId();
|
||||
const setterTestId = getNodeSetterId('biz-editor-layout');
|
||||
|
||||
return (
|
||||
<div className={style.container}>
|
||||
<div className={style.header}>
|
||||
<div className={style.title}>
|
||||
<div className={style['title-icon']}>
|
||||
<IconCozCodeFill />
|
||||
</div>
|
||||
<div className={style['title-content']}>{title}</div>
|
||||
|
||||
<Tooltip
|
||||
content={
|
||||
<div>
|
||||
{I18n.t('code_node_more_info')}
|
||||
<Text link={{ href: HELP_DOCUMENT_LINK, target: '_blank' }}>
|
||||
{I18n.t('code_node_help_doc')}
|
||||
</Text>
|
||||
</div>
|
||||
}
|
||||
theme={'dark'}
|
||||
>
|
||||
<Select
|
||||
onChange={value => onLanguageSelect?.(value as LanguageType)}
|
||||
value={language}
|
||||
data-testid={concatTestId(setterTestId, 'language-select')}
|
||||
renderSelectedItem={item => (
|
||||
<span
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: 'var(--coz-fg-secondary)',
|
||||
}}
|
||||
>
|
||||
{I18n.t('code_node_language')} {item.label}
|
||||
</span>
|
||||
)}
|
||||
size={'small'}
|
||||
optionList={optionList}
|
||||
></Select>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', gap: 8 }}>
|
||||
<Button
|
||||
color={'highlight'}
|
||||
data-testid={concatTestId(setterTestId, 'test-run')}
|
||||
icon={
|
||||
testRunIcon ? (
|
||||
<span
|
||||
style={{
|
||||
fontSize: 14,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
{testRunIcon}
|
||||
</span>
|
||||
) : (
|
||||
<IconCozPlayCircle style={{ fontSize: 14 }} />
|
||||
)
|
||||
}
|
||||
size={'small'}
|
||||
onClick={onTestRun}
|
||||
>
|
||||
{I18n.t('code_node_test_code')}
|
||||
</Button>
|
||||
|
||||
<IconButton
|
||||
onClick={onClose}
|
||||
color={'secondary'}
|
||||
size={'small'}
|
||||
icon={<IconCozSideCollapse style={{ fontSize: 18 }} />}
|
||||
data-testid={concatTestId(setterTestId, 'expand-button')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
min-width: 214px;
|
||||
height: 48px;
|
||||
margin-bottom: 0;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
|
||||
background-color: #28CAC8;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.title-content {
|
||||
min-width: 0;
|
||||
max-width: calc(100% - 160px);
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--coz-fg-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
import { type EditorAPI } from '../editor/preset';
|
||||
import { Editor } from '../editor';
|
||||
import { type PreviewerProps } from '../../interface';
|
||||
|
||||
export const Previewer = (props: PreviewerProps) => {
|
||||
const apiRef = useRef<EditorAPI | null>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!apiRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (props.content !== apiRef.current.getValue()) {
|
||||
apiRef.current.forceSetValue(props.content);
|
||||
}
|
||||
}, [props.content]);
|
||||
|
||||
return (
|
||||
<Editor
|
||||
uuid={`previewer_${new Date().getTime()}`}
|
||||
height={`${props.height}px`}
|
||||
defaultLanguage={props.language}
|
||||
defaultContent={props.content}
|
||||
readonly
|
||||
didMount={api => {
|
||||
apiRef.current = api;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createTheme } from '@coze-editor/editor/preset-code';
|
||||
import { type Extension } from '@codemirror/state';
|
||||
|
||||
const colors = {
|
||||
background: '#151B27',
|
||||
};
|
||||
|
||||
export const createDarkTheme: () => Extension = () =>
|
||||
createTheme({
|
||||
variant: 'dark',
|
||||
settings: {
|
||||
background: colors.background,
|
||||
foreground: '#fff',
|
||||
caret: '#AEAFAD',
|
||||
selection: '#d9d9d942',
|
||||
gutterBackground: colors.background,
|
||||
gutterForeground: '#FFFFFF63',
|
||||
gutterBorderColor: 'transparent',
|
||||
gutterBorderWidth: 0,
|
||||
lineHighlight: '#272e3d36',
|
||||
bracketColors: ['#FFEF61', '#DD99FF', '#78B0FF'],
|
||||
tooltip: {
|
||||
backgroundColor: '#363D4D',
|
||||
color: '#fff',
|
||||
border: 'none',
|
||||
},
|
||||
completionItemHover: {
|
||||
backgroundColor: '#FFFFFF0F',
|
||||
},
|
||||
completionItemSelected: {
|
||||
backgroundColor: '#FFFFFF17',
|
||||
},
|
||||
completionItemIcon: {
|
||||
color: '#FFFFFFC9',
|
||||
},
|
||||
completionItemLabel: {
|
||||
color: '#FFFFFFC9',
|
||||
},
|
||||
completionItemDetail: {
|
||||
color: '#FFFFFF63',
|
||||
},
|
||||
},
|
||||
styles: [],
|
||||
});
|
||||
33
frontend/packages/workflow/adapter/code-editor/src/index.tsx
Normal file
33
frontend/packages/workflow/adapter/code-editor/src/index.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { themes } from '@coze-editor/editor/preset-code';
|
||||
|
||||
import { convertSchema } from './utils';
|
||||
import { type PreviewerProps, type EditorProps } from './interface';
|
||||
import { createDarkTheme } from './components/theme';
|
||||
import { Previewer } from './components/previewer';
|
||||
import { BizEditor as Editor } from './components/editor';
|
||||
|
||||
themes.register('code-editor-dark', createDarkTheme());
|
||||
|
||||
export {
|
||||
Previewer,
|
||||
Editor,
|
||||
type PreviewerProps,
|
||||
type EditorProps,
|
||||
convertSchema,
|
||||
};
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
import type {
|
||||
ViewVariableTreeNode,
|
||||
ViewVariableType,
|
||||
} from '@coze-workflow/base';
|
||||
|
||||
import { type EditorAPI } from './components/editor/preset';
|
||||
|
||||
export interface Input {
|
||||
name?: string;
|
||||
type?: ViewVariableType;
|
||||
children?: ViewVariableTreeNode[];
|
||||
}
|
||||
|
||||
export interface Output {
|
||||
name?: string;
|
||||
type?: ViewVariableType;
|
||||
children?: Output[];
|
||||
}
|
||||
|
||||
// javascript 为历史数据,目前只会有 python | typescript
|
||||
export type LanguageType = 'python' | 'typescript' | 'javascript';
|
||||
|
||||
export interface PreviewerProps {
|
||||
content: string;
|
||||
language: LanguageType;
|
||||
height?: number;
|
||||
}
|
||||
|
||||
export interface EditorProps {
|
||||
defaultContent?: string;
|
||||
uuid: string;
|
||||
defaultLanguage: LanguageType;
|
||||
spaceId?: string;
|
||||
height?: string;
|
||||
width?: string;
|
||||
title?: string;
|
||||
readonly?: boolean;
|
||||
input?: Input[];
|
||||
output?: Output[];
|
||||
region?: string;
|
||||
locale?: string;
|
||||
onClose?: () => void;
|
||||
onChange?: (code: string, language: LanguageType) => void;
|
||||
languageTemplates?: Array<{
|
||||
language: 'typescript' | 'python';
|
||||
displayName: string;
|
||||
template: string;
|
||||
}>;
|
||||
onTestRun?: () => void;
|
||||
testRunIcon?: ReactNode;
|
||||
/**
|
||||
* @deprecated onTestRunStateChange 已失效,线上也未使用到
|
||||
*/
|
||||
onTestRunStateChange?: (status: string) => void;
|
||||
}
|
||||
|
||||
export interface EditorOtherProps {
|
||||
didMount?: (api: EditorAPI) => void;
|
||||
language?: LanguageType;
|
||||
}
|
||||
|
||||
export enum ModuleDetectionKind {
|
||||
/**
|
||||
* Files with imports, exports and/or import.meta are considered modules
|
||||
*/
|
||||
Legacy = 1,
|
||||
/**
|
||||
* Legacy, but also files with jsx under react-jsx or react-jsxdev and esm mode files under moduleResolution: node16+
|
||||
*/
|
||||
Auto = 2,
|
||||
/**
|
||||
* Consider all non-declaration files modules, regardless of present syntax
|
||||
*/
|
||||
Force = 3,
|
||||
}
|
||||
18
frontend/packages/workflow/adapter/code-editor/src/typings.d.ts
vendored
Normal file
18
frontend/packages/workflow/adapter/code-editor/src/typings.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/// <reference types='@coze-arch/bot-typings' />
|
||||
declare const IS_OVERSEA: boolean;
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
interface ParamSchemaType {
|
||||
name: string;
|
||||
type: number;
|
||||
children?: ParamSchemaType[];
|
||||
}
|
||||
|
||||
export function convertSchema(object, maxDepth = 20, currentDepth = 1) {
|
||||
if (currentDepth > maxDepth) {
|
||||
throw new Error('Max depth exceeded');
|
||||
}
|
||||
|
||||
const paramSchema: ParamSchemaType[] = [];
|
||||
Object.keys(object).forEach(key => {
|
||||
const value = object[key];
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 1 /* String */,
|
||||
});
|
||||
break;
|
||||
case 'number':
|
||||
if (Number.isInteger(value)) {
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 2 /* Integer */,
|
||||
});
|
||||
} else {
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 4 /* Number */,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'boolean':
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 3 /* Boolean */,
|
||||
});
|
||||
break;
|
||||
case 'object':
|
||||
if (value === null) {
|
||||
break;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length > 0) {
|
||||
switch (typeof value[0]) {
|
||||
case 'string':
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 99 /* ArrayString */,
|
||||
});
|
||||
break;
|
||||
case 'number':
|
||||
if (Number.isInteger(value[0])) {
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 100 /* ArrayInteger */,
|
||||
});
|
||||
} else {
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 102 /* ArrayNumber */,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'boolean':
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 101 /* ArrayBoolean */,
|
||||
});
|
||||
break;
|
||||
case 'object':
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 103 /* ArrayObject */,
|
||||
children: convertSchema(value[0], maxDepth, currentDepth + 1),
|
||||
});
|
||||
break;
|
||||
default:
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 99 /* ArrayString */,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 99 /* ArrayString */,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
paramSchema.push({
|
||||
name: key,
|
||||
type: 6 /* Object */,
|
||||
children: convertSchema(value, maxDepth, currentDepth + 1),
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log('value,to default', value);
|
||||
throw new Error('ContainsInvalidValue');
|
||||
}
|
||||
});
|
||||
return paramSchema;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { convertSchema } from './convert-schema';
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DemoComponent } from '../src';
|
||||
|
||||
export default {
|
||||
title: 'Example/Demo',
|
||||
component: DemoComponent,
|
||||
parameters: {
|
||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
|
||||
layout: 'centered',
|
||||
},
|
||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
|
||||
tags: ['autodocs'],
|
||||
// More on argTypes: https://storybook.js.org/docs/api/argtypes
|
||||
argTypes: {},
|
||||
};
|
||||
|
||||
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
|
||||
export const Base = {
|
||||
args: {
|
||||
name: 'tecvan',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Meta } from "@storybook/blocks";
|
||||
|
||||
<Meta title="Hello world" />
|
||||
|
||||
<div className="sb-container">
|
||||
<div className='sb-section-title'>
|
||||
# Hello world
|
||||
|
||||
Hello world
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
{`
|
||||
.sb-container {
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
|
||||
.sb-section {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
img {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.sb-section-title {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"extends": "@coze-arch/ts-config/tsconfig.web.json",
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"jsx": "react-jsx",
|
||||
"lib": ["DOM", "ESNext"],
|
||||
"module": "ESNext",
|
||||
"target": "ES2020",
|
||||
"moduleResolution": "bundler",
|
||||
"tsBuildInfoFile": "dist/tsconfig.build.tsbuildinfo"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../arch/bot-typings/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../arch/i18n/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../base/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../../config/eslint-config/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../../config/stylelint-config/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../../config/ts-config/tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "../../../../config/vitest-config/tsconfig.build.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
15
frontend/packages/workflow/adapter/code-editor/tsconfig.json
Normal file
15
frontend/packages/workflow/adapter/code-editor/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"exclude": ["**/*"],
|
||||
"compilerOptions": {
|
||||
"composite": true
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.build.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.misc.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "@coze-arch/ts-config/tsconfig.web.json",
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./",
|
||||
"outDir": "./dist",
|
||||
"jsx": "react-jsx",
|
||||
"lib": ["DOM", "ESNext"],
|
||||
"module": "ESNext",
|
||||
"target": "ES2020",
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"include": ["__tests__", "vitest.config.ts", "stories"],
|
||||
"exclude": ["./dist"],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.build.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineConfig } from '@coze-arch/vitest-config';
|
||||
|
||||
export default defineConfig({
|
||||
dirname: __dirname,
|
||||
preset: 'web',
|
||||
});
|
||||
Reference in New Issue
Block a user