feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,152 @@
/*
* 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 { createRenderer, option } from '@coze-editor/editor/react';
import preset, { languages, themes } from '@coze-editor/editor/preset-code';
import { shell } from '@coze-editor/editor/language-shell';
import { json } from '@coze-editor/editor/language-json';
import { mixLanguages } from '@coze-editor/editor';
import { EditorView } from '@codemirror/view';
import { cozeLight } from './themes/coze-light';
import { cozeDark } from './themes/coze-dark';
// 注册语言
languages.register('json', {
// mixLanguages 用于解决 「插值也使用了括号,导致无法正确高亮」的问题
language: mixLanguages({
outerLanguage: json.language,
}),
languageService: json.languageService,
});
languages.register('shell', shell);
// 注册主题
themes.register('coze-light', cozeLight);
themes.register('coze-dark', cozeDark);
const minHeightOption = (value?: string | number) =>
EditorView.theme({
'.cm-content, .cm-gutter, .cm-right-gutter': {
minHeight:
typeof value === 'number'
? `${value}px`
: typeof value === 'string'
? value
: 'unset',
},
'&.cm-editor': {
minHeight:
typeof value === 'number'
? `${value}px`
: typeof value === 'string'
? value
: 'unset',
},
});
const maxHeightOption = (value?: string | number) =>
EditorView.theme({
'&.cm-editor': {
maxHeight:
typeof value === 'number'
? `${value}px`
: typeof value === 'string'
? value
: 'unset',
},
});
const heightOption = (value?: string | number) =>
EditorView.theme({
'&.cm-editor': {
height:
typeof value === 'number'
? `${value}px`
: typeof value === 'string'
? value
: 'unset',
},
});
const paddingOption = (value?: string | number) =>
EditorView.theme({
'&.cm-editor': {
padding:
typeof value === 'number'
? `${value}px`
: typeof value === 'string'
? value
: 'unset',
},
});
const borderRadiusOption = (value?: string | number) =>
EditorView.theme({
'&.cm-editor, .cm-gutters': {
borderRadius:
typeof value === 'number'
? `${value}px`
: typeof value === 'string'
? value
: 'unset',
},
});
const lineHeightOption = (value?: string | number) =>
EditorView.theme({
'.cm-content, .cm-gutter, .cm-right-gutter': {
lineHeight:
typeof value === 'number'
? `${value}px`
: typeof value === 'string'
? value
: 'unset',
},
});
function createStyleOptions() {
return [
option('minHeight', minHeightOption),
option('maxHeight', maxHeightOption),
option('editerHeight', heightOption),
option('borderRadius', borderRadiusOption),
option('padding', paddingOption),
option('lineHeight', lineHeightOption),
];
}
const builtinExtensions = [
EditorView.theme({
'&.cm-focused': {
outline: 'none',
},
'& *': {
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
},
}),
EditorView.theme({
'&.cm-content': {
wordBreak: 'break-all',
},
}),
];
export const CodeEditor = createRenderer(
[...preset, ...createStyleOptions()],
builtinExtensions,
);

View File

@@ -0,0 +1,19 @@
/*
* 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 { EditorProvider } from '@coze-editor/editor/react';
export { CodeEditor } from './code-editor';
export { TextEditor } from './text-editor';

View File

@@ -0,0 +1,71 @@
/*
* 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 { createRenderer, option } from '@coze-editor/editor/react';
import universal from '@coze-editor/editor/preset-universal';
import { mixLanguages } from '@coze-editor/editor';
import { keymap, EditorView } from '@codemirror/view';
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
const RawEditorTheme = EditorView.theme({
'&.cm-editor': {
outline: 'none',
},
'&.cm-content': {
wordBreak: 'break-all',
},
});
const minHeightOption = (value?: string | number) =>
EditorView.theme({
'.cm-content, .cm-gutter, .cm-right-gutter': {
minHeight:
typeof value === 'number'
? `${value}px`
: typeof value === 'string'
? value
: 'unset',
},
});
const lineHeightOption = (value?: string | number) =>
EditorView.theme({
'.cm-content, .cm-gutter, .cm-right-gutter': {
lineHeight:
typeof value === 'number'
? `${value}px`
: typeof value === 'string'
? value
: 'unset',
},
});
const extensions = [
mixLanguages({}),
RawEditorTheme,
// ...其他 extensions
history(),
keymap.of([...defaultKeymap, ...historyKeymap]),
];
export const TextEditor = createRenderer(
[
...universal,
option('minHeight', minHeightOption),
option('lineHeight', lineHeightOption),
],
extensions,
);

View File

@@ -0,0 +1,131 @@
/*
* 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, tags as t } from '@coze-editor/editor/preset-code';
import { EditorView } from '@codemirror/view';
const colors = {
background: '#151B27',
// syntax
comment: '#FFFFFF63',
key: '#39E5D7',
string: '#FF94D2',
number: '#FF9933',
boolean: '#78B0FF',
null: '#78B0FF',
separator: '#FFFFFFC9',
};
export const cozeDark = [
EditorView.theme({
'.cm-completionIcon-property': {
backgroundImage:
'url("' +
'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMWVtIiBoZWlnaHQ9IjFlbSIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMi4zNTc2IDguMTAzNTVDMTIuMTYyMyA3LjkwODI5IDExLjg0NTcgNy45MDgyOSAxMS42NTA1IDguMTAzNTVMOC4xMDM1NSAxMS42NTA1QzcuOTA4MjkgMTEuODQ1NyA3LjkwODI5IDEyLjE2MjMgOC4xMDM1NSAxMi4zNTc2TDExLjY1MDUgMTUuOTA0NUMxMS44NDU3IDE2LjA5OTggMTIuMTYyMyAxNi4wOTk4IDEyLjM1NzYgMTUuOTA0NUwxNS45MDQ1IDEyLjM1NzZDMTYuMDk5OCAxMi4xNjIzIDE2LjA5OTggMTEuODQ1NyAxNS45MDQ1IDExLjY1MDVMMTIuMzU3NiA4LjEwMzU1WiIgZmlsbD0iI0ZGRkZGRkM5Ii8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMS4wMDI2IDEuNDU1NDVDMTEuNjIxNCAxLjA5ODE4IDEyLjM4MzggMS4wOTgxOCAxMy4wMDI2IDEuNDU1NDVMMjAuNjM4IDUuODYzNzRDMjEuMjU2OCA2LjIyMSAyMS42MzggNi44ODEyNiAyMS42MzggNy41OTU3OVYxNi40MTI0QzIxLjYzOCAxNy4xMjY5IDIxLjI1NjggMTcuNzg3MiAyMC42MzggMTguMTQ0NEwxMy4wMDI2IDIyLjU1MjdDMTIuMzgzOCAyMi45MSAxMS42MjE0IDIyLjkxIDExLjAwMjYgMjIuNTUyN0wzLjM2NzE5IDE4LjE0NDRDMi43NDgzOSAxNy43ODcyIDIuMzY3MTkgMTcuMTI2OSAyLjM2NzE5IDE2LjQxMjRWNy41OTU3OUMyLjM2NzE5IDYuODgxMjYgMi43NDgzOSA2LjIyMTAxIDMuMzY3MTkgNS44NjM3NEwxMS4wMDI2IDEuNDU1NDVaTTEyLjAwMjYgMy4xODc1TDE5LjYzOCA3LjU5NTc5VjE2LjQxMjRMMTIuMDAyNiAyMC44MjA3TDQuMzY3MTkgMTYuNDEyNEw0LjM2NzE5IDcuNTk1NzlMMTIuMDAyNiAzLjE4NzVaIiBmaWxsPSIjRkZGRkZGQzkiLz48L3N2Zz4=' +
'")',
backgroundSize: '11px 11px',
backgroundRepeat: 'no-repeat',
width: '11px',
height: '11px',
},
'.cm-completionIcon-property::after': {
content: '""',
},
}),
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: [
// json
{
tag: t.comment,
color: colors.comment,
},
{
tag: [t.propertyName],
color: colors.key,
},
{
tag: [t.string],
color: colors.string,
},
{
tag: [t.number],
color: colors.number,
},
{
tag: [t.bool],
color: colors.boolean,
},
{
tag: [t.null],
color: colors.null,
},
{
tag: [t.separator],
color: colors.separator,
},
// shell
// curl
{
tag: [t.standard(t.variableName)],
color: '#3BEB84',
},
// -X
{
tag: [t.attributeName],
color: '#FF9933',
},
// url in string (includes quotes), e.g.
{
tag: [t.special(t.string)],
color: '#78B0FF',
},
],
}),
];

View File

@@ -0,0 +1,137 @@
/*
* 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, tags as t } from '@coze-editor/editor/preset-code';
import { EditorView } from '@codemirror/view';
const colors = {
background: '#F7F7FC',
// syntax
comment: '#000A298A',
key: '#00818C',
string: '#D1009D',
number: '#C74200',
boolean: '#2B57D9',
null: '#2B57D9',
separator: '#0F1529D1',
};
export const cozeLight = [
EditorView.theme({
'.cm-completionIcon-property': {
backgroundImage:
'url("' +
'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMWVtIiBoZWlnaHQ9IjFlbSIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMi4zNTc2IDguMTAzNTVDMTIuMTYyMyA3LjkwODI5IDExLjg0NTcgNy45MDgyOSAxMS42NTA1IDguMTAzNTVMOC4xMDM1NSAxMS42NTA1QzcuOTA4MjkgMTEuODQ1NyA3LjkwODI5IDEyLjE2MjMgOC4xMDM1NSAxMi4zNTc2TDExLjY1MDUgMTUuOTA0NUMxMS44NDU3IDE2LjA5OTggMTIuMTYyMyAxNi4wOTk4IDEyLjM1NzYgMTUuOTA0NUwxNS45MDQ1IDEyLjM1NzZDMTYuMDk5OCAxMi4xNjIzIDE2LjA5OTggMTEuODQ1NyAxNS45MDQ1IDExLjY1MDVMMTIuMzU3NiA4LjEwMzU1WiIgZmlsbD0iIzA2MDcwOUNDIi8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMS4wMDI2IDEuNDU1NDVDMTEuNjIxNCAxLjA5ODE4IDEyLjM4MzggMS4wOTgxOCAxMy4wMDI2IDEuNDU1NDVMMjAuNjM4IDUuODYzNzRDMjEuMjU2OCA2LjIyMSAyMS42MzggNi44ODEyNiAyMS42MzggNy41OTU3OVYxNi40MTI0QzIxLjYzOCAxNy4xMjY5IDIxLjI1NjggMTcuNzg3MiAyMC42MzggMTguMTQ0NEwxMy4wMDI2IDIyLjU1MjdDMTIuMzgzOCAyMi45MSAxMS42MjE0IDIyLjkxIDExLjAwMjYgMjIuNTUyN0wzLjM2NzE5IDE4LjE0NDRDMi43NDgzOSAxNy43ODcyIDIuMzY3MTkgMTcuMTI2OSAyLjM2NzE5IDE2LjQxMjRWNy41OTU3OUMyLjM2NzE5IDYuODgxMjYgMi43NDgzOSA2LjIyMTAxIDMuMzY3MTkgNS44NjM3NEwxMS4wMDI2IDEuNDU1NDVaTTEyLjAwMjYgMy4xODc1TDE5LjYzOCA3LjU5NTc5VjE2LjQxMjRMMTIuMDAyNiAyMC44MjA3TDQuMzY3MTkgMTYuNDEyNEw0LjM2NzE5IDcuNTk1NzlMMTIuMDAyNiAzLjE4NzVaIiBmaWxsPSIjMDYwNzA5Q0MiLz48L3N2Zz4=' +
'")',
backgroundSize: '11px 11px',
backgroundRepeat: 'no-repeat',
width: '11px',
height: '11px',
},
'.cm-completionIcon-property::after': {
content: '""',
},
}),
createTheme({
variant: 'light',
settings: {
background: colors.background,
foreground: '#4D4D4C',
caret: '#AEAFAD',
selection: '#52649A21',
gutterBackground: colors.background,
gutterForeground: '#000A298A',
gutterBorderColor: 'transparent',
gutterBorderWidth: 0,
lineHighlight: '#efefef78',
bracketColors: ['#E4D129', '#AC05FF', '#2B57D9'],
tooltip: {
backgroundColor: 'var(--coz-bg-max)',
color: 'var(--coz-fg-primary)',
border: 'solid 1px var(--coz-stroke-plus)',
boxShadow: 'var(--coz-shadow-default)',
borderRadius: '8px',
},
tooltipCompletion: {
backgroundColor: '#FFFFFF',
color: '#060709CC',
},
completionItemHover: {
backgroundColor: '#5768A114',
},
completionItemSelected: {
backgroundColor: '#52649A21',
},
completionItemIcon: {
color: '#060709CC',
},
completionItemLabel: {
color: '#060709CC',
},
completionItemDetail: {
color: '#2029459E',
},
},
styles: [
// JSON
{
tag: t.comment,
color: colors.comment,
},
{
tag: [t.propertyName],
color: colors.key,
},
{
tag: [t.string],
color: colors.string,
},
{
tag: [t.number],
color: colors.number,
},
{
tag: [t.bool],
color: colors.boolean,
},
{
tag: [t.null],
color: colors.null,
},
{
tag: [t.separator],
color: colors.separator,
},
// shell
// curl
{
tag: [t.standard(t.variableName)],
color: '#00804A',
},
// -X
{
tag: [t.attributeName],
color: '#C74200',
},
// url in string (includes quotes), e.g.
{
tag: [t.special(t.string)],
color: '#2B57D9',
},
],
}),
];