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,55 @@
/*
* 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 { ErrorBoundary, type FallbackProps } from 'react-error-boundary';
import ReactDOM from 'react-dom';
import React, { useEffect } from 'react';
import { nanoid } from 'nanoid';
import { useRefresh } from '@coze-project-ide/core';
import { type ReactWidget, ReactWidgetContext } from '../widget/react-widget';
export const createPortal = (
widget: ReactWidget,
OriginRenderer: () => React.ReactElement<any, any> | null,
ErrorFallbackRender: React.FC<FallbackProps & { widget: ReactWidget }>,
) => {
function PlaygroundReactLayerPortal(): JSX.Element {
const refresh = useRefresh();
useEffect(() => {
const dispose = widget.onUpdate(() => refresh());
return () => dispose.dispose();
}, []);
const result = (
<ErrorBoundary
fallbackRender={props => (
<ErrorFallbackRender {...props} widget={widget} />
)}
>
<ReactWidgetContext.Provider value={widget}>
<OriginRenderer />
</ReactWidgetContext.Provider>
</ErrorBoundary>
);
return ReactDOM.createPortal(result, widget.node!);
}
return {
key: widget.getResourceURI()?.toString?.() || nanoid(),
comp: React.memo(PlaygroundReactLayerPortal) as any,
};
};

View File

@@ -0,0 +1,29 @@
/*
* 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.
*/
const ACTION_ITEM = 'action-label';
export function codicon(name: string, actionItem = false): string {
return `codicon codicon-${name}${actionItem ? ` ${ACTION_ITEM}` : ''}`;
}
export function codiconArray(name: string, actionItem = false): string[] {
const array = ['codicon', `codicon-${name}`];
if (actionItem) {
array.push(ACTION_ITEM);
}
return array;
}

View File

@@ -0,0 +1,21 @@
/*
* 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 * from './tools';
export { codicon, codiconArray } from './icon';
export { createPortal } from './create-portal';
export { isURIMatch } from './uri';
export { createBoxLayout, createSplitLayout } from './layout';

View File

@@ -0,0 +1,59 @@
/*
* 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 Widget,
BoxPanel,
BoxLayout,
SplitLayout,
SplitPanel,
} from '../lumino/widgets';
export const createBoxLayout = (
widgets: Widget[],
stretch?: number[],
options?: BoxPanel.IOptions,
): BoxLayout => {
const boxLayout = new BoxLayout(options);
for (let i = 0; i < widgets.length; i++) {
if (stretch !== undefined && i < stretch.length) {
BoxPanel.setStretch(widgets[i], stretch[i]);
}
boxLayout.addWidget(widgets[i]);
}
return boxLayout;
};
export const createSplitLayout = (
widgets: Widget[],
stretch?: number[],
options?: Partial<SplitLayout.IOptions>,
): SplitLayout => {
let optParam: SplitLayout.IOptions = {
renderer: SplitPanel.defaultRenderer,
};
if (options) {
optParam = { ...optParam, ...options };
}
const splitLayout = new SplitLayout(optParam);
for (let i = 0; i < widgets.length; i++) {
if (stretch !== undefined && i < stretch.length) {
SplitPanel.setStretch(widgets[i], stretch[i]);
}
splitLayout.addWidget(widgets[i]);
}
return splitLayout;
};

View File

@@ -0,0 +1,58 @@
/*
* 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 function isFunction<T extends (...args: unknown[]) => unknown>(
value: unknown,
): value is T {
return typeof value === 'function';
}
function is(userAgent: string, platform: string): boolean {
if (typeof navigator !== 'undefined') {
if (navigator.userAgent && navigator.userAgent.indexOf(userAgent) >= 0) {
return true;
}
}
if (typeof process !== 'undefined') {
return process.platform === platform;
}
return false;
}
export const isWindows = is('Windows', 'win32');
export const isOSX = is('Mac', 'darwin');
export function parseCssMagnitude(
value: string | null,
defaultValue: number,
): number;
export function parseCssMagnitude(
value: string | null,
defaultValue?: number,
): number | undefined {
if (value) {
let parsed: number;
if (value.endsWith('px')) {
parsed = parseFloat(value.substring(0, value.length - 2));
} else {
parsed = parseFloat(value);
}
if (!isNaN(parsed)) {
return parsed;
}
}
return defaultValue;
}

View File

@@ -0,0 +1,20 @@
/*
* 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 URI } from '@coze-project-ide/core';
export const isURIMatch = (uriA: URI, uriB: URI) =>
uriA.withoutQuery().toString() === uriB.withoutQuery().toString();