Skip to content

Commit

Permalink
feat: react 18
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaaaash committed May 10, 2022
1 parent 7881e92 commit 0fa5471
Show file tree
Hide file tree
Showing 43 changed files with 308 additions and 262 deletions.
2 changes: 2 additions & 0 deletions jest.setup.jsdom.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ require('jest-canvas-mock');
// packages/extension/__tests__/browser/main.thread.env.test.ts
// MainThreadEnvAPI Test Suites › can read/write text via clipboard
let text = '';
global.IS_REACT_ACT_ENVIRONMENT = true;

window.navigator = Object.assign(window.navigator, {
clipboard: {
writeText(value) {
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"packages": ["packages/*", "tools/dev-tool"],
"command": {
"bootstrap": {
"npmClientArgs": ["--no-package-lock"]
"npmClientArgs": ["--no-package-lock", "--legacy-peer-deps"]
}
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@
"@types/md5": "^2.1.33",
"@types/node": "^10.14.6",
"@types/node-fetch": "^2.5.12",
"@types/react": "^16.9.20",
"@types/react-dom": "^16.9.5",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/react-is": "^16.7.1",
"@types/read-pkg": "^5.1.0",
"@types/socket.io-client": "^1.4.32",
Expand Down
5 changes: 2 additions & 3 deletions packages/comments/src/browser/comments-zone.view.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import clx from 'classnames';
import { observer } from 'mobx-react-lite';
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDOM from 'react-dom/client';

import { INJECTOR_TOKEN, Injectable, Autowired } from '@opensumi/di';
import { ConfigProvider, localize, AppConfig, useInjectable, Event, Emitter } from '@opensumi/ide-core-browser';
Expand Down Expand Up @@ -160,11 +160,10 @@ export class CommentsZoneWidget extends ResizeZoneWidget implements ICommentsZon
this._container.appendChild(this._wrapper);
this.observeContainer(this._wrapper);
const customRender = this.commentsFeatureRegistry.getZoneWidgetRender();
ReactDOM.render(
ReactDOM.createRoot(this._wrapper).render(
<ConfigProvider value={this.appConfig}>
{customRender ? customRender(thread, this) : <CommentsZone thread={thread} widget={this} />}
</ConfigProvider>,
this._wrapper,
);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/components/src/dropdown/dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import RightOutlined from '@ant-design/icons/RightOutlined';
import classNames from 'classnames';
import RcDropdown from 'rc-dropdown';
import React from 'react';
import React, { PropsWithChildren } from 'react';

import { tuple } from '../utils/type';
import { warning } from '../utils/warning';
Expand Down Expand Up @@ -44,7 +44,7 @@ export interface DropDownProps {
openClassName?: string;
}

export default class Dropdown extends React.Component<DropDownProps, any> {
export default class Dropdown extends React.Component<PropsWithChildren<DropDownProps>, any> {
static defaultProps = {
mouseEnterDelay: 0.15,
mouseLeaveDelay: 0.1,
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/icon/iconfont-cn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const svgBaseProps = {
fill: 'currentColor',
};

export function createFromIconfontCN<T>(options: CustomIconOptions = {}): React.SFC<IconFontProps<T>> {
export function createFromIconfontCN<T>(options: CustomIconOptions = {}) {
const { scriptUrl, extraCommonProps = {} } = options;

/**
Expand Down
5 changes: 2 additions & 3 deletions packages/components/src/modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import classNames from 'classnames';
import PropTypes from 'prop-types';
import Dialog from 'rc-dialog';
import addEventListener from 'rc-util/lib/Dom/addEventListener';
import React from 'react';
import React, { PropsWithChildren } from 'react';

import { Button } from '../button';
import type { ButtonType, ButtonProps } from '../button';

import { getConfirmLocale, ModalLocale } from './locale';


let mousePosition: { x: number; y: number } | null;
export const destroyFns: Array<() => void> = [];

Expand Down Expand Up @@ -119,7 +118,7 @@ export type ModalFunc = (props: ModalFuncProps) => {
update: (newConfig: ModalFuncProps) => void;
};

export default class Modal extends React.Component<ModalProps, {}> {
export default class Modal extends React.Component<PropsWithChildren<ModalProps>, {}> {
static info: ModalFunc;

static success: ModalFunc;
Expand Down
4 changes: 2 additions & 2 deletions packages/components/src/overlay/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import clsx from 'classnames';
import React from 'react';
import React, { PropsWithChildren } from 'react';

import { Modal, ModalProps } from '../modal';

Expand All @@ -21,7 +21,7 @@ export interface IOverlayProps {
keyboard?: boolean;
}

export const Overlay: React.FC<IOverlayProps> = ({
export const Overlay: React.FC<PropsWithChildren<IOverlayProps>> = ({
maskClosable = false,
closable = true,
className,
Expand Down
5 changes: 3 additions & 2 deletions packages/components/src/recycle-tree/RecycleTree.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fuzzy from 'fuzzy';
import React from 'react';
import React, { PropsWithChildren } from 'react';
import { FixedSizeList, VariableSizeList, shouldComponentUpdate, ListProps } from 'react-window';

import {
Expand All @@ -18,7 +18,7 @@ import { RenamePromptHandle, PromptHandle } from './prompt';
import { NewPromptHandle } from './prompt/NewPromptHandle';
import { TreeNode, CompositeTreeNode, spliceArray } from './tree';
import { TreeModel } from './tree/model/TreeModel';
import { INodeRendererProps, NodeRendererWrap, INodeRenderer } from './TreeNodeRendererWrap';
import { INodeRendererProps, NodeRendererWrap, INodeRenderer, INodeRendererWrapProps } from './TreeNodeRendererWrap';
import { TreeNodeType, TreeNodeEvent } from './types';

export type IRecycleTreeAlign = 'smart' | 'start' | 'center' | 'end' | 'auto';
Expand All @@ -36,6 +36,7 @@ export interface IRecycleTreeSize {
}

export interface IRecycleTreeProps<T = TreeModel> {
children(props: any): React.ReactNode;
model: T;
/**
* 容器高度
Expand Down
27 changes: 16 additions & 11 deletions packages/components/src/select/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ function getLabelWithChildrenProps<T = string>(
}

export function isDataOptions<T = any>(
options: Array<React.ReactNode | { label: string; value: T }> | undefined,
): options is Array<{ label: string; value: T; iconClass?: string }> {
options: Array<React.ReactNode | IDataOption<T> | IDataOptionGroup<T>> | undefined,
): options is Array<IDataOption<T>> {
if (!options) {
return false;
}
Expand All @@ -184,7 +184,7 @@ export function isDataOptionGroups<T = any>(
}

function isDataOption<T = any>(
option: React.ReactNode | { label: string; value: T },
option: React.ReactNode | IDataOption<T> | IDataOptionGroup<T>,
): option is { label: string; value: T; iconClass?: string } {
return (option as any).value !== undefined;
}
Expand Down Expand Up @@ -261,15 +261,20 @@ export function Select<T = string>({
const selectRef = React.useRef<HTMLDivElement | null>(null);
const overlayRef = React.useRef<HTMLDivElement | null>(null);

const toggleOpen = useCallback(() => {
const target = !open;
if (target) {
if (onBeforeShowOptions && onBeforeShowOptions()) {
return;
const toggleOpen = useCallback(
(e) => {
e.preventDefault();
e.stopPropagation();
const target = !open;
if (target) {
if (onBeforeShowOptions && onBeforeShowOptions()) {
return;
}
}
}
setOpen(target);
}, [open, onBeforeShowOptions, onBeforeShowOptions]);
setOpen(target);
},
[open, onBeforeShowOptions, onBeforeShowOptions],
);

const getSelectedValue = useCallback(() => {
if (options && isDataOptions(options)) {
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/tooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import './style.less';
export const Tooltip: React.FC<{
title: string;
delay?: number;
children: React.ReactChild;
}> = ({ title, children, delay }) => {
const [visible, setVisible] = useState(false);
const targetRef = useRef<HTMLParagraphElement | null>(null);
Expand Down
2 changes: 1 addition & 1 deletion packages/core-browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"onigasm": "2.2.2",
"p-series": "^2.1.0",
"rc-menu": "^9.3.2",
"react": "^16.8.6",
"react": "^18.0.0",
"react-autosize-textarea": "^7.0.0",
"react-ctxmenu-trigger": "^1.0.0",
"react-custom-scrollbars": "^4.2.1",
Expand Down
29 changes: 13 additions & 16 deletions packages/core-browser/src/bootstrap/app.view.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import ReactDom from 'react-dom';
import ReactDom from 'react-dom/client';

import { ComponentContextProvider, IIconResourceOptions } from '@opensumi/ide-components';
import { getDebugLogger, IEventBus, URI } from '@opensumi/ide-core-common';
Expand All @@ -14,7 +14,8 @@ import { getIcon } from '../style/icon/icon';

export interface AppProps {
app: IClientApp;
main: React.ComponentType;
main: React.ComponentType<{ callback?: () => void }>;
callback?: () => void;
overlays?: React.ComponentType[];
}

Expand All @@ -26,6 +27,7 @@ export function App(props: AppProps) {
(uri: string, options: IIconResourceOptions) => labelService.getIcon(URI.parse(uri), options),
[],
);

React.useEffect(() => {
let lastFrame: number | null;
const handle = () => {
Expand All @@ -47,26 +49,21 @@ export function App(props: AppProps) {
return (
<ComponentContextProvider value={{ getIcon, localize, getResourceIcon }}>
<ConfigProvider value={props.app.config}>
{<props.main />}
{<props.main callback={props.callback} />}
{props.overlays && props.overlays.map((Component, index) => <Component key={index} />)}
</ConfigProvider>
</ComponentContextProvider>
);
}

export type IAppRenderer = (app: React.ReactElement) => Promise<void>;
export type IAppRenderer = (app: (props: any) => JSX.Element) => void;

const defaultAppRender =
(dom: HTMLElement, onDidRendered?: () => void): IAppRenderer =>
(app) =>
new Promise((resolve) => {
ReactDom.render(app, dom, () => {
if (onDidRendered && typeof onDidRendered === 'function') {
onDidRendered();
}
resolve();
});
});
(dom: HTMLElement): IAppRenderer =>
(IDEApp: (props: any) => JSX.Element) => {
const root = ReactDom.createRoot(dom);
root.render(<IDEApp />);
};

export function renderClientApp(app: IClientApp, container: HTMLElement | IAppRenderer) {
const Layout = app.config.layoutComponent || DefaultLayout;
Expand All @@ -80,9 +77,9 @@ export function renderClientApp(app: IClientApp, container: HTMLElement | IAppRe
return module.component;
});

const IdeApp = <App app={app} main={Layout} overlays={overlayComponents} />;
const IdeApp = (props) => <App {...props} app={app} main={Layout} overlays={overlayComponents} />;

const render = typeof container === 'function' ? container : defaultAppRender(container, app.config.didRendered);
const render = typeof container === 'function' ? container : defaultAppRender(container);

return render(IdeApp);
}
9 changes: 9 additions & 0 deletions packages/core-browser/src/components/layout/box-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import clsx from 'classnames';
import React from 'react';

import { useInjectable } from '../../react-hooks';
import { AppConfig } from '../../react-providers';

import { Layout } from './layout';
import styles from './styles.module.less';

Expand All @@ -22,9 +25,15 @@ export const BoxPanel: React.FC<{
}> = ({ className, children = [], direction = 'left-to-right', ...restProps }) => {
// convert children to list
const arrayChildren = React.Children.toArray(children);
const appConfig = useInjectable<AppConfig>(AppConfig);

return (
<div
ref={() => {
if (appConfig.didRendered) {
appConfig.didRendered();
}
}}
{...restProps}
className={clsx(styles['box-panel'], className)}
style={{ flexDirection: Layout.getFlexDirection(direction), zIndex: restProps['z-index'] }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const SplitPanel: React.FC<SplitPanelProps> = ({
(accumulator, item) => accumulator + (getProp(item, 'flex') !== undefined ? item['props'].flex : 1),
0,
);
const elements: React.ReactNodeArray = [];
const elements: React.ReactNode[] = [];
const resizeDelegates = React.useRef<IResizeHandleDelegate[]>([]);
const eventBus = useInjectable<IEventBus>(IEventBus);
const rootRef = React.useRef<HTMLElement>();
Expand Down
1 change: 1 addition & 0 deletions packages/core-browser/src/components/portal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { usePortal } from '../../react-hooks';

const Portal: React.FC<{
id: string;
children: React.ReactChild;
}> = ({ id, children }) => {
const target = usePortal(id);
return ReactDOM.createPortal(children, target);
Expand Down
4 changes: 2 additions & 2 deletions packages/core-browser/src/components/scroll/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classnames from 'classnames';
import React from 'react';
import React, { PropsWithChildren } from 'react';
import { MouseEvent, UIEvent } from 'react';

import styles from './scroll.module.less';
Expand Down Expand Up @@ -29,7 +29,7 @@ export interface ScrollSizes {
scrollWidth: number;
}

export class Scroll extends React.Component<ScrollAreaProps, any> {
export class Scroll extends React.Component<PropsWithChildren<ScrollAreaProps>, any> {
public ref: HTMLDivElement;

public container: HTMLDivElement;
Expand Down
5 changes: 3 additions & 2 deletions packages/core-browser/src/layout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { IMenu, IContextMenu } from '../menu/next';
import { useInjectable } from '../react-hooks';
import { SlotLocation, AppConfig } from '../react-providers';


export class VisibleChangedPayload {
constructor(public isVisible: boolean, public slotLocation: SlotLocation) {}
}
Expand Down Expand Up @@ -226,7 +225,9 @@ export const useViewState = (
const resizeObserver = new ResizeObserver(doUpdate);
resizeObserver.observe(containerRef.current);
return () => {
resizeObserver.unobserve(containerRef.current);
if (containerRef.current) {
resizeObserver.unobserve(containerRef.current);
}
};
}
}, []);
Expand Down
9 changes: 6 additions & 3 deletions packages/core-browser/src/react-providers/slot.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { PropsWithChildren } from 'react';

import { Button } from '@opensumi/ide-components';
import { getDebugLogger, localize } from '@opensumi/ide-core-common';
Expand Down Expand Up @@ -59,7 +59,7 @@ export function getTabbarCtxKey(location: string): TabbarContextKeys {
return standardTabbarCtxKeys[location] || 'activeExtendViewlet';
}

export class ErrorBoundary extends React.Component {
export class ErrorBoundary extends React.Component<PropsWithChildren<any>> {
state = { error: null, errorInfo: null };

componentDidCatch(error, errorInfo) {
Expand Down Expand Up @@ -96,7 +96,10 @@ export class ErrorBoundary extends React.Component {

export const allSlot: { slot: string; dom: HTMLElement }[] = [];

export const SlotDecorator: React.FC<{ slot: string; color?: string }> = ({ slot, ...props }) => {
export const SlotDecorator: React.FC<{ slot: string; color?: string; children: React.ReactChild }> = ({
slot,
...props
}) => {
const ref = React.useRef<HTMLElement>();
React.useEffect(() => {
if (ref.current) {
Expand Down
Loading

0 comments on commit 0fa5471

Please sign in to comment.