Skip to content

Commit

Permalink
feat: update to React 18 Beta
Browse files Browse the repository at this point in the history
  • Loading branch information
xiejay97 committed Nov 28, 2021
1 parent 78e6fb6 commit bfbf6e0
Show file tree
Hide file tree
Showing 100 changed files with 3,429 additions and 1,819 deletions.
75 changes: 37 additions & 38 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,80 +28,79 @@
"dependencies": {
"bootstrap": "^5.1.3",
"core-js": "^3.19.1",
"i18next": "^21.4.1",
"immer": "^9.0.6",
"i18next": "^21.5.3",
"immer": "^9.0.7",
"lodash": "^4.17.21",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-i18next": "^11.14.2",
"react-router-dom": "^6.0.0",
"react": "^18.0.0-beta-0cc724c77-20211125",
"react-dom": "^18.0.0-beta-0cc724c77-20211125",
"react-i18next": "^11.14.3",
"react-router-dom": "^6.0.2",
"regenerator-runtime": "^0.13.9",
"rfs": "^9.0.6",
"rxjs": "^7.4.0",
"tslib": "^2.3.1",
"use-immer": "^0.6.0"
"tslib": "^2.3.1"
},
"devDependencies": {
"@commitlint/cli": "^14.1.0",
"@commitlint/config-conventional": "^14.1.0",
"@nrwl/cli": "^13.1.3",
"@nrwl/cypress": "^13.1.3",
"@nrwl/eslint-plugin-nx": "^13.1.3",
"@nrwl/jest": "^13.1.3",
"@nrwl/linter": "^13.1.3",
"@commitlint/cli": "^15.0.0",
"@commitlint/config-conventional": "^15.0.0",
"@nrwl/cli": "^13.2.2",
"@nrwl/cypress": "^13.2.2",
"@nrwl/eslint-plugin-nx": "^13.2.2",
"@nrwl/jest": "^13.2.2",
"@nrwl/linter": "^13.2.2",
"@nrwl/nx-cloud": "latest",
"@nrwl/react": "^13.1.3",
"@nrwl/tao": "^13.1.3",
"@nrwl/web": "^13.1.3",
"@nrwl/workspace": "^13.1.3",
"@nrwl/react": "^13.2.2",
"@nrwl/tao": "^13.2.2",
"@nrwl/web": "^13.2.2",
"@nrwl/workspace": "^13.2.2",
"@testing-library/react": "^12.1.2",
"@testing-library/react-hooks": "7.0.2",
"@types/enzyme": "^3.10.10",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.0.2",
"@types/lodash": "^4.14.176",
"@types/jest": "^27.0.3",
"@types/lodash": "^4.14.177",
"@types/marked": "^3.0.1",
"@types/node": "^16.11.6",
"@types/react": "^17.0.34",
"@types/node": "^16.11.10",
"@types/react": "^17.0.37",
"@types/react-dom": "^17.0.11",
"@typescript-eslint/eslint-plugin": "^5.3.1",
"@typescript-eslint/parser": "^5.3.1",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"babel-jest": "^27.3.1",
"cypress": "^8.7.0",
"cypress": "^9.1.0",
"dotenv": "^10.0.0",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.6",
"eslint": "^7.22.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-markdown": "^2.2.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.26.1",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"fs-extra": "^10.0.0",
"highlight.js": "^11.3.1",
"husky": "^7.0.0",
"husky": "^7.0.4",
"jest": "^27.3.1",
"marked": "^3.0.4",
"postcss-html": "^1.2.0",
"postcss-markdown": "^1.1.0",
"prettier": "^2.4.1",
"postcss-html": "^1.3.0",
"postcss-markdown": "^1.2.0",
"prettier": "^2.5.0",
"react-test-renderer": "17.0.2",
"rxjs-for-await": "^0.0.2",
"sass": "^1.43.4",
"rxjs-for-await": "^1.0.0",
"sass": "^1.43.5",
"standard-version": "^9.3.2",
"stylelint": "^14.1.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-rational-order": "^0.1.2",
"stylelint-config-recommended-scss": "^5.0.1",
"stylelint-config-recommended-scss": "^5.0.2",
"stylelint-config-standard": "^24.0.0",
"stylelint-order": "^5.0.0",
"stylelint-scss": "^4.0.0",
"ts-jest": "^27.0.7",
"ts-node": "^10.4.0",
"typescript": "~4.4.4",
"typescript": "~4.5.2",
"yaml-front-matter": "^4.1.1"
}
}
174 changes: 174 additions & 0 deletions packages/site/next.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/* eslint-disable */

/**
* These are types for things that are present in the upcoming React 18 release.
*
* Once React 18 is released they can just be moved to the main index file.
*
* To load the types declared here in an actual project, there are three ways. The easiest one,
* if your `tsconfig.json` already has a `"types"` array in the `"compilerOptions"` section,
* is to add `"react/next"` to the `"types"` array.
*
* Alternatively, a specific import syntax can to be used from a typescript file.
* This module does not exist in reality, which is why the {} is important:
*
* ```ts
* import {} from 'react/next'
* ```
*
* It is also possible to include it through a triple-slash reference:
*
* ```ts
* /// <reference types="react/next" />
* ```
*
* Either the import or the reference only needs to appear once, anywhere in the project.
*/

// See https://github.com/facebook/react/blob/master/packages/react/src/React.js to see how the exports are declared,

import React = require('.');

export {};

declare const UNDEFINED_VOID_ONLY: unique symbol;
type VoidOrUndefinedOnly = void | { [UNDEFINED_VOID_ONLY]: never };

declare module '.' {
export interface SuspenseProps {
/**
* The presence of this prop indicates that the content is computationally expensive to render.
* In other words, the tree is CPU bound and not I/O bound (e.g. due to fetching data).
* @see {@link https://github.com/facebook/react/pull/19936}
*/
unstable_expectedLoadTime?: number;
}

export type SuspenseListRevealOrder = 'forwards' | 'backwards' | 'together';
export type SuspenseListTailMode = 'collapsed' | 'hidden';

export interface SuspenseListCommonProps {
/**
* Note that SuspenseList require more than one child;
* it is a runtime warning to provide only a single child.
*
* It does, however, allow those children to be wrapped inside a single
* level of `<React.Fragment>`.
*/
children: ReactElement | Iterable<ReactElement>;
}

interface DirectionalSuspenseListProps extends SuspenseListCommonProps {
/**
* Defines the order in which the `SuspenseList` children should be revealed.
*/
revealOrder: 'forwards' | 'backwards';
/**
* Dictates how unloaded items in a SuspenseList is shown.
*
* - By default, `SuspenseList` will show all fallbacks in the list.
* - `collapsed` shows only the next fallback in the list.
* - `hidden` doesn’t show any unloaded items.
*/
tail?: SuspenseListTailMode;
}

interface NonDirectionalSuspenseListProps extends SuspenseListCommonProps {
/**
* Defines the order in which the `SuspenseList` children should be revealed.
*/
revealOrder?: Exclude<SuspenseListRevealOrder, DirectionalSuspenseListProps['revealOrder']>;
/**
* The tail property is invalid when not using the `forwards` or `backwards` reveal orders.
*/
tail?: never;
}

export type SuspenseListProps = DirectionalSuspenseListProps | NonDirectionalSuspenseListProps;

/**
* `SuspenseList` helps coordinate many components that can suspend by orchestrating the order
* in which these components are revealed to the user.
*
* When multiple components need to fetch data, this data may arrive in an unpredictable order.
* However, if you wrap these items in a `SuspenseList`, React will not show an item in the list
* until previous items have been displayed (this behavior is adjustable).
*
* @see https://reactjs.org/docs/concurrent-mode-reference.html#suspenselist
* @see https://reactjs.org/docs/concurrent-mode-patterns.html#suspenselist
*/
export const SuspenseList: ExoticComponent<SuspenseListProps>;

// must be synchronous
export type TransitionFunction = () => VoidOrUndefinedOnly;
// strange definition to allow vscode to show documentation on the invocation
export interface TransitionStartFunction {
/**
* State updates caused inside the callback are allowed to be deferred.
*
* **If some state update causes a component to suspend, that state update should be wrapped in a transition.**
*
* @param callback A _synchronous_ function which causes state updates that can be deferred.
*/
(callback: TransitionFunction): void;
}

/**
* Returns a deferred version of the value that may “lag behind” it for at most `timeoutMs`.
*
* This is commonly used to keep the interface responsive when you have something that renders immediately
* based on user input and something that needs to wait for a data fetch.
*
* A good example of this is a text input.
*
* @param value The value that is going to be deferred
*
* @see https://reactjs.org/docs/concurrent-mode-reference.html#usedeferredvalue
*/
export function useDeferredValue<T>(value: T): T;

/**
* Allows components to avoid undesirable loading states by waiting for content to load
* before transitioning to the next screen. It also allows components to defer slower,
* data fetching updates until subsequent renders so that more crucial updates can be
* rendered immediately.
*
* The `useTransition` hook returns two values in an array.
*
* The first is boolean, React’s way of informing us whether we’re waiting for the transition to finish.
* The seconda is a function that takes a callback. We can use it to tell React which state we want to defer.
*
* **If some state update causes a component to suspend, that state update should be wrapped in a transition.**
*
* @param config An optional object with `timeoutMs`
*
* @see https://reactjs.org/docs/concurrent-mode-reference.html#usetransition
*/
export function useTransition(): [boolean, TransitionStartFunction];

/**
* Similar to `useTransition` but allows uses where hooks are not available.
*
* @param callback A _synchronous_ function which causes state updates that can be deferred.
*/
export function startTransition(scope: TransitionFunction): void;

const opaqueIdentifierBranding: unique symbol;
/**
* WARNING: Don't use this as a `string`.
*
* This is an opaque type that is not supposed to type-check structurally.
* It is only valid if returned from React methods and passed to React e.g. `<button aria-labelledby={opaqueIdentifier} />`
*/
// We can't create a type that would be rejected for string concatenation or `.toString()` calls.
// So in order to not have to add `string | OpaqueIdentifier` to every react-dom host prop we intersect it with `string`.
type OpaqueIdentifier = string & {
readonly [opaqueIdentifierBranding]: unknown;
// While this would cause `const stringified: string = opaqueIdentifier.toString()` to not type-check it also adds completions while typing.
// It would also still allow string concatenation.
// Unsure which is better. Not type-checking or not suggesting.
// toString(): void;
};

export function unstable_useOpaqueIdentifier(): OpaqueIdentifier;
}
13 changes: 12 additions & 1 deletion packages/site/src/app/components/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';

import './Header.scss';

export function AppHeader() {
const { i18n } = useTranslation();

const changeLanguage = useCallback(() => {
if (i18n.language === 'en-US') {
document.body.classList.add('CJK');
i18n.changeLanguage('zh-Hant');
} else {
document.body.classList.remove('CJK');
i18n.changeLanguage('en-US');
}
}, [i18n]);

return (
<header className="app-header is-shadow">
<img className="app-header__logo" src="/assets/logo.svg" alt="Logo" width="36" height="36" />
<span className="app-header__title">DevUI</span>
<span onClick={() => i18n.changeLanguage(i18n.language === 'en-US' ? 'zh-Hant' : 'en-US')}>{i18n.language}</span>
<span onClick={changeLanguage}>{i18n.language}</span>
</header>
);
}
3 changes: 1 addition & 2 deletions packages/site/src/app/components/route/DemoBox.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { useCallback, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useImmer } from 'use-immer';

import { DTooltip, DIcon } from '@react-devui/ui';
import { useAsync } from '@react-devui/ui/hooks';
import { useAsync, useImmer } from '@react-devui/ui/hooks';
import { copy, getClassName } from '@react-devui/ui/utils';

import './DemoBox.scss';
Expand Down
2 changes: 1 addition & 1 deletion packages/site/src/app/components/sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useCallback, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { useImmer } from 'use-immer';

import { DMenu, DMenuGroup, DMenuItem } from '@react-devui/ui';
import { useImmer } from '@react-devui/ui/hooks';

import menu from '../../configs/menu.json';
import './Sidebar.scss';
Expand Down
28 changes: 27 additions & 1 deletion packages/site/src/app/styles/_app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ body {
border-right: 1px solid var(--d-divider-color);
}

.app-demo-block {
.app-demo-drag {
position: relative;

display: flex;
align-items: center;
justify-content: center;
Expand All @@ -50,4 +52,28 @@ body {
background-color: var(--d-color-primary);

@include font-size(0.8rem);

& + &,
& + .app-demo-drag-placeholder,
.app-demo-drag-placeholder + & {
margin-top: 8px;
}
}

.app-demo-drop {
display: inline-block;
padding: 12px;
border: 1px dashed var(--#{$variable-prefix}divider-color);

&.is-horizontal {
display: inline-flex;
align-items: center;

.app-demo-drag + .app-demo-drag,
.app-demo-drag + .app-demo-drag-placeholder,
.app-demo-drag-placeholder + .app-demo-drag {
margin-top: 0;
margin-left: 8px;
}
}
}
7 changes: 4 additions & 3 deletions packages/site/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import { BrowserRouter } from 'react-router-dom';
import App from './app/App';
import './app/i18n';

ReactDOM.render(
const rootElement = document.getElementById('app-root') as Element;

ReactDOM.createRoot(rootElement).render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
document.getElementById('app-root')
</StrictMode>
);
Loading

0 comments on commit bfbf6e0

Please sign in to comment.