Skip to content

Commit bfbf6e0

Browse files
committed
feat: update to React 18 Beta
1 parent 78e6fb6 commit bfbf6e0

100 files changed

Lines changed: 3429 additions & 1819 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package.json

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,80 +28,79 @@
2828
"dependencies": {
2929
"bootstrap": "^5.1.3",
3030
"core-js": "^3.19.1",
31-
"i18next": "^21.4.1",
32-
"immer": "^9.0.6",
31+
"i18next": "^21.5.3",
32+
"immer": "^9.0.7",
3333
"lodash": "^4.17.21",
34-
"react": "^17.0.2",
35-
"react-dom": "^17.0.2",
36-
"react-i18next": "^11.14.2",
37-
"react-router-dom": "^6.0.0",
34+
"react": "^18.0.0-beta-0cc724c77-20211125",
35+
"react-dom": "^18.0.0-beta-0cc724c77-20211125",
36+
"react-i18next": "^11.14.3",
37+
"react-router-dom": "^6.0.2",
3838
"regenerator-runtime": "^0.13.9",
3939
"rfs": "^9.0.6",
4040
"rxjs": "^7.4.0",
41-
"tslib": "^2.3.1",
42-
"use-immer": "^0.6.0"
41+
"tslib": "^2.3.1"
4342
},
4443
"devDependencies": {
45-
"@commitlint/cli": "^14.1.0",
46-
"@commitlint/config-conventional": "^14.1.0",
47-
"@nrwl/cli": "^13.1.3",
48-
"@nrwl/cypress": "^13.1.3",
49-
"@nrwl/eslint-plugin-nx": "^13.1.3",
50-
"@nrwl/jest": "^13.1.3",
51-
"@nrwl/linter": "^13.1.3",
44+
"@commitlint/cli": "^15.0.0",
45+
"@commitlint/config-conventional": "^15.0.0",
46+
"@nrwl/cli": "^13.2.2",
47+
"@nrwl/cypress": "^13.2.2",
48+
"@nrwl/eslint-plugin-nx": "^13.2.2",
49+
"@nrwl/jest": "^13.2.2",
50+
"@nrwl/linter": "^13.2.2",
5251
"@nrwl/nx-cloud": "latest",
53-
"@nrwl/react": "^13.1.3",
54-
"@nrwl/tao": "^13.1.3",
55-
"@nrwl/web": "^13.1.3",
56-
"@nrwl/workspace": "^13.1.3",
52+
"@nrwl/react": "^13.2.2",
53+
"@nrwl/tao": "^13.2.2",
54+
"@nrwl/web": "^13.2.2",
55+
"@nrwl/workspace": "^13.2.2",
5756
"@testing-library/react": "^12.1.2",
5857
"@testing-library/react-hooks": "7.0.2",
5958
"@types/enzyme": "^3.10.10",
6059
"@types/fs-extra": "^9.0.13",
61-
"@types/jest": "^27.0.2",
62-
"@types/lodash": "^4.14.176",
60+
"@types/jest": "^27.0.3",
61+
"@types/lodash": "^4.14.177",
6362
"@types/marked": "^3.0.1",
64-
"@types/node": "^16.11.6",
65-
"@types/react": "^17.0.34",
63+
"@types/node": "^16.11.10",
64+
"@types/react": "^17.0.37",
6665
"@types/react-dom": "^17.0.11",
67-
"@typescript-eslint/eslint-plugin": "^5.3.1",
68-
"@typescript-eslint/parser": "^5.3.1",
66+
"@typescript-eslint/eslint-plugin": "^5.4.0",
67+
"@typescript-eslint/parser": "^5.4.0",
6968
"babel-jest": "^27.3.1",
70-
"cypress": "^8.7.0",
69+
"cypress": "^9.1.0",
7170
"dotenv": "^10.0.0",
7271
"enzyme": "^3.11.0",
7372
"enzyme-adapter-react-16": "^1.15.6",
7473
"eslint": "^7.22.0",
7574
"eslint-config-prettier": "^8.3.0",
7675
"eslint-plugin-cypress": "^2.12.1",
77-
"eslint-plugin-import": "^2.25.2",
78-
"eslint-plugin-jsx-a11y": "^6.4.1",
76+
"eslint-plugin-import": "^2.25.3",
77+
"eslint-plugin-jsx-a11y": "^6.5.1",
7978
"eslint-plugin-markdown": "^2.2.1",
8079
"eslint-plugin-prettier": "^4.0.0",
81-
"eslint-plugin-react": "^7.26.1",
82-
"eslint-plugin-react-hooks": "^4.2.0",
80+
"eslint-plugin-react": "^7.27.1",
81+
"eslint-plugin-react-hooks": "^4.3.0",
8382
"fs-extra": "^10.0.0",
8483
"highlight.js": "^11.3.1",
85-
"husky": "^7.0.0",
84+
"husky": "^7.0.4",
8685
"jest": "^27.3.1",
8786
"marked": "^3.0.4",
88-
"postcss-html": "^1.2.0",
89-
"postcss-markdown": "^1.1.0",
90-
"prettier": "^2.4.1",
87+
"postcss-html": "^1.3.0",
88+
"postcss-markdown": "^1.2.0",
89+
"prettier": "^2.5.0",
9190
"react-test-renderer": "17.0.2",
92-
"rxjs-for-await": "^0.0.2",
93-
"sass": "^1.43.4",
91+
"rxjs-for-await": "^1.0.0",
92+
"sass": "^1.43.5",
9493
"standard-version": "^9.3.2",
9594
"stylelint": "^14.1.0",
9695
"stylelint-config-prettier": "^9.0.3",
9796
"stylelint-config-rational-order": "^0.1.2",
98-
"stylelint-config-recommended-scss": "^5.0.1",
97+
"stylelint-config-recommended-scss": "^5.0.2",
9998
"stylelint-config-standard": "^24.0.0",
10099
"stylelint-order": "^5.0.0",
101100
"stylelint-scss": "^4.0.0",
102101
"ts-jest": "^27.0.7",
103102
"ts-node": "^10.4.0",
104-
"typescript": "~4.4.4",
103+
"typescript": "~4.5.2",
105104
"yaml-front-matter": "^4.1.1"
106105
}
107106
}

packages/site/next.d.ts

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/* eslint-disable */
2+
3+
/**
4+
* These are types for things that are present in the upcoming React 18 release.
5+
*
6+
* Once React 18 is released they can just be moved to the main index file.
7+
*
8+
* To load the types declared here in an actual project, there are three ways. The easiest one,
9+
* if your `tsconfig.json` already has a `"types"` array in the `"compilerOptions"` section,
10+
* is to add `"react/next"` to the `"types"` array.
11+
*
12+
* Alternatively, a specific import syntax can to be used from a typescript file.
13+
* This module does not exist in reality, which is why the {} is important:
14+
*
15+
* ```ts
16+
* import {} from 'react/next'
17+
* ```
18+
*
19+
* It is also possible to include it through a triple-slash reference:
20+
*
21+
* ```ts
22+
* /// <reference types="react/next" />
23+
* ```
24+
*
25+
* Either the import or the reference only needs to appear once, anywhere in the project.
26+
*/
27+
28+
// See https://github.com/facebook/react/blob/master/packages/react/src/React.js to see how the exports are declared,
29+
30+
import React = require('.');
31+
32+
export {};
33+
34+
declare const UNDEFINED_VOID_ONLY: unique symbol;
35+
type VoidOrUndefinedOnly = void | { [UNDEFINED_VOID_ONLY]: never };
36+
37+
declare module '.' {
38+
export interface SuspenseProps {
39+
/**
40+
* The presence of this prop indicates that the content is computationally expensive to render.
41+
* In other words, the tree is CPU bound and not I/O bound (e.g. due to fetching data).
42+
* @see {@link https://github.com/facebook/react/pull/19936}
43+
*/
44+
unstable_expectedLoadTime?: number;
45+
}
46+
47+
export type SuspenseListRevealOrder = 'forwards' | 'backwards' | 'together';
48+
export type SuspenseListTailMode = 'collapsed' | 'hidden';
49+
50+
export interface SuspenseListCommonProps {
51+
/**
52+
* Note that SuspenseList require more than one child;
53+
* it is a runtime warning to provide only a single child.
54+
*
55+
* It does, however, allow those children to be wrapped inside a single
56+
* level of `<React.Fragment>`.
57+
*/
58+
children: ReactElement | Iterable<ReactElement>;
59+
}
60+
61+
interface DirectionalSuspenseListProps extends SuspenseListCommonProps {
62+
/**
63+
* Defines the order in which the `SuspenseList` children should be revealed.
64+
*/
65+
revealOrder: 'forwards' | 'backwards';
66+
/**
67+
* Dictates how unloaded items in a SuspenseList is shown.
68+
*
69+
* - By default, `SuspenseList` will show all fallbacks in the list.
70+
* - `collapsed` shows only the next fallback in the list.
71+
* - `hidden` doesn’t show any unloaded items.
72+
*/
73+
tail?: SuspenseListTailMode;
74+
}
75+
76+
interface NonDirectionalSuspenseListProps extends SuspenseListCommonProps {
77+
/**
78+
* Defines the order in which the `SuspenseList` children should be revealed.
79+
*/
80+
revealOrder?: Exclude<SuspenseListRevealOrder, DirectionalSuspenseListProps['revealOrder']>;
81+
/**
82+
* The tail property is invalid when not using the `forwards` or `backwards` reveal orders.
83+
*/
84+
tail?: never;
85+
}
86+
87+
export type SuspenseListProps = DirectionalSuspenseListProps | NonDirectionalSuspenseListProps;
88+
89+
/**
90+
* `SuspenseList` helps coordinate many components that can suspend by orchestrating the order
91+
* in which these components are revealed to the user.
92+
*
93+
* When multiple components need to fetch data, this data may arrive in an unpredictable order.
94+
* However, if you wrap these items in a `SuspenseList`, React will not show an item in the list
95+
* until previous items have been displayed (this behavior is adjustable).
96+
*
97+
* @see https://reactjs.org/docs/concurrent-mode-reference.html#suspenselist
98+
* @see https://reactjs.org/docs/concurrent-mode-patterns.html#suspenselist
99+
*/
100+
export const SuspenseList: ExoticComponent<SuspenseListProps>;
101+
102+
// must be synchronous
103+
export type TransitionFunction = () => VoidOrUndefinedOnly;
104+
// strange definition to allow vscode to show documentation on the invocation
105+
export interface TransitionStartFunction {
106+
/**
107+
* State updates caused inside the callback are allowed to be deferred.
108+
*
109+
* **If some state update causes a component to suspend, that state update should be wrapped in a transition.**
110+
*
111+
* @param callback A _synchronous_ function which causes state updates that can be deferred.
112+
*/
113+
(callback: TransitionFunction): void;
114+
}
115+
116+
/**
117+
* Returns a deferred version of the value that may “lag behind” it for at most `timeoutMs`.
118+
*
119+
* This is commonly used to keep the interface responsive when you have something that renders immediately
120+
* based on user input and something that needs to wait for a data fetch.
121+
*
122+
* A good example of this is a text input.
123+
*
124+
* @param value The value that is going to be deferred
125+
*
126+
* @see https://reactjs.org/docs/concurrent-mode-reference.html#usedeferredvalue
127+
*/
128+
export function useDeferredValue<T>(value: T): T;
129+
130+
/**
131+
* Allows components to avoid undesirable loading states by waiting for content to load
132+
* before transitioning to the next screen. It also allows components to defer slower,
133+
* data fetching updates until subsequent renders so that more crucial updates can be
134+
* rendered immediately.
135+
*
136+
* The `useTransition` hook returns two values in an array.
137+
*
138+
* The first is boolean, React’s way of informing us whether we’re waiting for the transition to finish.
139+
* The seconda is a function that takes a callback. We can use it to tell React which state we want to defer.
140+
*
141+
* **If some state update causes a component to suspend, that state update should be wrapped in a transition.**
142+
*
143+
* @param config An optional object with `timeoutMs`
144+
*
145+
* @see https://reactjs.org/docs/concurrent-mode-reference.html#usetransition
146+
*/
147+
export function useTransition(): [boolean, TransitionStartFunction];
148+
149+
/**
150+
* Similar to `useTransition` but allows uses where hooks are not available.
151+
*
152+
* @param callback A _synchronous_ function which causes state updates that can be deferred.
153+
*/
154+
export function startTransition(scope: TransitionFunction): void;
155+
156+
const opaqueIdentifierBranding: unique symbol;
157+
/**
158+
* WARNING: Don't use this as a `string`.
159+
*
160+
* This is an opaque type that is not supposed to type-check structurally.
161+
* It is only valid if returned from React methods and passed to React e.g. `<button aria-labelledby={opaqueIdentifier} />`
162+
*/
163+
// We can't create a type that would be rejected for string concatenation or `.toString()` calls.
164+
// So in order to not have to add `string | OpaqueIdentifier` to every react-dom host prop we intersect it with `string`.
165+
type OpaqueIdentifier = string & {
166+
readonly [opaqueIdentifierBranding]: unknown;
167+
// While this would cause `const stringified: string = opaqueIdentifier.toString()` to not type-check it also adds completions while typing.
168+
// It would also still allow string concatenation.
169+
// Unsure which is better. Not type-checking or not suggesting.
170+
// toString(): void;
171+
};
172+
173+
export function unstable_useOpaqueIdentifier(): OpaqueIdentifier;
174+
}
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
1+
import { useCallback } from 'react';
12
import { useTranslation } from 'react-i18next';
23

34
import './Header.scss';
45

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

9+
const changeLanguage = useCallback(() => {
10+
if (i18n.language === 'en-US') {
11+
document.body.classList.add('CJK');
12+
i18n.changeLanguage('zh-Hant');
13+
} else {
14+
document.body.classList.remove('CJK');
15+
i18n.changeLanguage('en-US');
16+
}
17+
}, [i18n]);
18+
819
return (
920
<header className="app-header is-shadow">
1021
<img className="app-header__logo" src="/assets/logo.svg" alt="Logo" width="36" height="36" />
1122
<span className="app-header__title">DevUI</span>
12-
<span onClick={() => i18n.changeLanguage(i18n.language === 'en-US' ? 'zh-Hant' : 'en-US')}>{i18n.language}</span>
23+
<span onClick={changeLanguage}>{i18n.language}</span>
1324
</header>
1425
);
1526
}

packages/site/src/app/components/route/DemoBox.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { useCallback, useEffect } from 'react';
22
import { useTranslation } from 'react-i18next';
3-
import { useImmer } from 'use-immer';
43

54
import { DTooltip, DIcon } from '@react-devui/ui';
6-
import { useAsync } from '@react-devui/ui/hooks';
5+
import { useAsync, useImmer } from '@react-devui/ui/hooks';
76
import { copy, getClassName } from '@react-devui/ui/utils';
87

98
import './DemoBox.scss';

packages/site/src/app/components/sidebar/Sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { useCallback, useEffect } from 'react';
22
import { useTranslation } from 'react-i18next';
33
import { useNavigate } from 'react-router-dom';
4-
import { useImmer } from 'use-immer';
54

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

88
import menu from '../../configs/menu.json';
99
import './Sidebar.scss';

packages/site/src/app/styles/_app.scss

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ body {
3838
border-right: 1px solid var(--d-divider-color);
3939
}
4040

41-
.app-demo-block {
41+
.app-demo-drag {
42+
position: relative;
43+
4244
display: flex;
4345
align-items: center;
4446
justify-content: center;
@@ -50,4 +52,28 @@ body {
5052
background-color: var(--d-color-primary);
5153

5254
@include font-size(0.8rem);
55+
56+
& + &,
57+
& + .app-demo-drag-placeholder,
58+
.app-demo-drag-placeholder + & {
59+
margin-top: 8px;
60+
}
61+
}
62+
63+
.app-demo-drop {
64+
display: inline-block;
65+
padding: 12px;
66+
border: 1px dashed var(--#{$variable-prefix}divider-color);
67+
68+
&.is-horizontal {
69+
display: inline-flex;
70+
align-items: center;
71+
72+
.app-demo-drag + .app-demo-drag,
73+
.app-demo-drag + .app-demo-drag-placeholder,
74+
.app-demo-drag-placeholder + .app-demo-drag {
75+
margin-top: 0;
76+
margin-left: 8px;
77+
}
78+
}
5379
}

packages/site/src/main.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import { BrowserRouter } from 'react-router-dom';
55
import App from './app/App';
66
import './app/i18n';
77

8-
ReactDOM.render(
8+
const rootElement = document.getElementById('app-root') as Element;
9+
10+
ReactDOM.createRoot(rootElement).render(
911
<StrictMode>
1012
<BrowserRouter>
1113
<App />
1214
</BrowserRouter>
13-
</StrictMode>,
14-
document.getElementById('app-root')
15+
</StrictMode>
1516
);

0 commit comments

Comments
 (0)