diff --git a/package.json b/package.json
index 4474cdbfd..c1a6482fa 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"pnpm": ">=6"
},
"alias": {
- "html-parse-stringify": "html-parse-stringify/dist/html-parse-stringify.module.js"
+ "html-parse-stringify": "html-parse-stringify/dist/html-parse-stringify.module.js",
+ "react-hook-form": "react-hook-form/dist/index.esm.mjs"
}
}
diff --git a/packages/console/package.json b/packages/console/package.json
index df99c94b7..b1d050b85 100644
--- a/packages/console/package.json
+++ b/packages/console/package.json
@@ -25,7 +25,9 @@
"lodash.kebabcase": "^4.1.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
+ "react-hook-form": "^7.27.1",
"react-i18next": "^11.15.4",
+ "react-modal": "^3.14.4",
"react-router-dom": "^6.2.2",
"swr": "^1.2.2"
},
@@ -39,6 +41,7 @@
"@types/lodash.kebabcase": "^4.1.6",
"@types/react": "^17.0.14",
"@types/react-dom": "^17.0.9",
+ "@types/react-modal": "^3.13.1",
"eslint": "^8.10.0",
"lint-staged": "^11.1.1",
"parcel": "^2.3.1",
diff --git a/packages/console/src/components/AppContent/index.module.scss b/packages/console/src/components/AppContent/index.module.scss
index 116f89113..8e03131ff 100644
--- a/packages/console/src/components/AppContent/index.module.scss
+++ b/packages/console/src/components/AppContent/index.module.scss
@@ -1,9 +1,6 @@
.app {
position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- right: 0;
+ inset: 0;
display: flex;
flex-direction: column;
}
@@ -34,8 +31,11 @@
--color-neutral-90: #e0e3e3;
--color-on-secondary-container: #201c00;
--color-component-caption: #747778;
+ --color-component-text: #191c1d;
--color-outline: #78767f;
--color-table-row-selected: rgba(0, 0, 0, 2%);
+ --color-text-default: #202223;
+ --color-foggy: #888;
}
$font-family: 'SF UI Text', 'SF Pro Display', sans-serif;
@@ -43,9 +43,11 @@ $font-family: 'SF UI Text', 'SF Pro Display', sans-serif;
.web {
--font-title-medium: 500 16px/24px #{$font-family};
--font-heading-small: 600 24px/32px #{$font-family};
+ --font-heading: 600 16px/24px #{$font-family};
--font-body: normal 16px/22px #{$font-family};
--font-small-text: normal 12px/16px #{$font-family};
--font-caption: normal 14px/20px #{$font-family};
+ --font-caption-bold: 600 14px/20px #{$font-family};
--font-button: 500 14px/20px #{$font-family};
--font-subhead-2: 500 14px/20px #{$font-family};
}
diff --git a/packages/console/src/components/AppContent/index.tsx b/packages/console/src/components/AppContent/index.tsx
index ba24055e8..5fe800617 100644
--- a/packages/console/src/components/AppContent/index.tsx
+++ b/packages/console/src/components/AppContent/index.tsx
@@ -1,5 +1,4 @@
-import classNames from 'classnames';
-import React, { ReactNode } from 'react';
+import React, { ReactNode, useEffect } from 'react';
import * as styles from './index.module.scss';
@@ -11,7 +10,16 @@ type Props = {
};
const AppContent = ({ children, theme }: Props) => {
- return
{children}
;
+ useEffect(() => {
+ const classes = [styles.web, styles[theme]].filter((value): value is string => Boolean(value));
+ document.body.classList.add(...classes);
+
+ return () => {
+ document.body.classList.remove(...classes);
+ };
+ }, [theme]);
+
+ return {children}
;
};
export default AppContent;
diff --git a/packages/console/src/components/Card/index.tsx b/packages/console/src/components/Card/index.tsx
index 58594e067..88c103d23 100644
--- a/packages/console/src/components/Card/index.tsx
+++ b/packages/console/src/components/Card/index.tsx
@@ -1,13 +1,15 @@
+import classNames from 'classnames';
import React, { ReactNode } from 'react';
import * as styles from './index.module.scss';
type Props = {
children: ReactNode;
+ className?: string;
};
-const Card = ({ children }: Props) => {
- return {children}
;
+const Card = ({ children, className }: Props) => {
+ return {children}
;
};
export default Card;
diff --git a/packages/console/src/components/FormField/index.module.scss b/packages/console/src/components/FormField/index.module.scss
new file mode 100644
index 000000000..0bcb5a0e9
--- /dev/null
+++ b/packages/console/src/components/FormField/index.module.scss
@@ -0,0 +1,21 @@
+@use '@/scss/underscore' as _;
+
+.headline {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: _.unit(1);
+
+ &:not(:first-child) {
+ margin-top: _.unit(6);
+ }
+
+ .title {
+ font: var(--font-caption-bold);
+ color: var(--color-component-text);
+ }
+
+ .required {
+ font: var(--font-body);
+ color: var(--color-component-caption);
+ }
+}
diff --git a/packages/console/src/components/FormField/index.tsx b/packages/console/src/components/FormField/index.tsx
new file mode 100644
index 000000000..f3a7ff148
--- /dev/null
+++ b/packages/console/src/components/FormField/index.tsx
@@ -0,0 +1,27 @@
+import { I18nKey } from '@logto/phrases';
+import React, { ReactNode } from 'react';
+import { useTranslation } from 'react-i18next';
+
+import * as styles from './index.module.scss';
+
+type Props = {
+ title: I18nKey;
+ children: ReactNode;
+ isRequired?: boolean;
+};
+
+const FormField = ({ title, children, isRequired }: Props) => {
+ const { t } = useTranslation();
+
+ return (
+ <>
+
+
{t(title)}
+ {isRequired &&
{t('admin_console.form.required')}
}
+
+ {children}
+ >
+ );
+};
+
+export default FormField;
diff --git a/packages/console/src/components/RadioGroup/Radio.tsx b/packages/console/src/components/RadioGroup/Radio.tsx
new file mode 100644
index 000000000..56aade654
--- /dev/null
+++ b/packages/console/src/components/RadioGroup/Radio.tsx
@@ -0,0 +1,40 @@
+import classNames from 'classnames';
+import React, { ReactNode } from 'react';
+
+import * as styles from './index.module.scss';
+
+const Check = () => (
+
+);
+
+export type Props = {
+ value: string;
+ title: string;
+ name?: string;
+ children?: ReactNode;
+ isChecked?: boolean;
+ onClick?: () => void;
+};
+
+const Radio = ({ value, title, name, children, isChecked, onClick }: Props) => {
+ return (
+
+ );
+};
+
+export default Radio;
diff --git a/packages/console/src/components/RadioGroup/index.module.scss b/packages/console/src/components/RadioGroup/index.module.scss
new file mode 100644
index 000000000..8ecc4485e
--- /dev/null
+++ b/packages/console/src/components/RadioGroup/index.module.scss
@@ -0,0 +1,68 @@
+@use '@/scss/underscore' as _;
+
+.radioGroup {
+ display: flex;
+
+ &:not(:first-child) {
+ margin-top: _.unit(3);
+ }
+
+ svg {
+ opacity: 0%;
+ }
+
+
+ > .radio {
+ position: relative;
+ flex: 1;
+ max-width: 220px;
+ padding: _.unit(5);
+ display: flex;
+ flex-direction: column;
+ border-radius: _.unit(4);
+ border: 1px solid var(--color-neutral-90);
+ outline: none;
+ user-select: none;
+ cursor: pointer;
+
+ &:not(:first-child) {
+ margin-left: _.unit(6);
+ }
+
+ &.checked {
+ border-color: var(--color-primary);
+ outline: 1px solid var(--color-primary);
+
+ svg {
+ opacity: 100%;
+ }
+ }
+
+ .headline {
+ flex: 1;
+ display: flex;
+ justify-content: space-between;
+
+ &.center {
+ align-items: center;
+ }
+
+ > *:not(:first-child) {
+ margin-left: _.unit(3);
+ }
+ }
+
+ .title {
+ font: var(--font-heading);
+ color: var(--color-component-text);
+ }
+
+ input[type='radio'] {
+ appearance: none;
+ position: absolute;
+ margin: 0;
+ width: 0;
+ height: 0;
+ }
+ }
+}
diff --git a/packages/console/src/components/RadioGroup/index.tsx b/packages/console/src/components/RadioGroup/index.tsx
new file mode 100644
index 000000000..98ee75f2f
--- /dev/null
+++ b/packages/console/src/components/RadioGroup/index.tsx
@@ -0,0 +1,34 @@
+import React, { Children, cloneElement, isValidElement, ReactNode } from 'react';
+
+import Radio, { Props as RadioProps } from './Radio';
+import * as styles from './index.module.scss';
+
+type Props = {
+ name: string;
+ children: ReactNode;
+ value: string;
+ onChange?: (value: string) => void;
+};
+
+const RadioGroup = ({ name, children, value, onChange }: Props) => {
+ return (
+
+ {Children.map(children, (child) => {
+ if (!isValidElement(child) || child.type !== Radio) {
+ return child;
+ }
+
+ return cloneElement(child, {
+ name,
+ isChecked: value === child.props.value,
+ onClick: () => {
+ onChange?.(child.props.value);
+ },
+ });
+ })}
+
+ );
+};
+
+export default RadioGroup;
+export { default as Radio } from './Radio';
diff --git a/packages/console/src/icons/Close.tsx b/packages/console/src/icons/Close.tsx
new file mode 100644
index 000000000..41a5d67ee
--- /dev/null
+++ b/packages/console/src/icons/Close.tsx
@@ -0,0 +1,12 @@
+import React, { SVGProps } from 'react';
+
+const Close = (props: SVGProps) => (
+
+);
+
+export default Close;
diff --git a/packages/console/src/index.tsx b/packages/console/src/index.tsx
index 09a8551e3..1ccb3cb4a 100644
--- a/packages/console/src/index.tsx
+++ b/packages/console/src/index.tsx
@@ -1,7 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom';
+import ReactModal from 'react-modal';
import App from './App';
const app = document.querySelector('#app');
+ReactModal.setAppElement('#app');
ReactDOM.render(, app);
diff --git a/packages/console/src/pages/Applications/components/CreateForm/index.module.scss b/packages/console/src/pages/Applications/components/CreateForm/index.module.scss
new file mode 100644
index 000000000..171303508
--- /dev/null
+++ b/packages/console/src/pages/Applications/components/CreateForm/index.module.scss
@@ -0,0 +1,22 @@
+@use '@/scss/underscore' as _;
+
+.card {
+ padding: _.unit(8);
+}
+
+.headline {
+ display: flex;
+ justify-content: space-between;
+
+ > *:not(:first-child) {
+ margin-left: _.unit(3);
+ }
+
+ > svg {
+ cursor: pointer;
+ }
+}
+
+.form {
+ margin-top: _.unit(8);
+}
diff --git a/packages/console/src/pages/Applications/components/CreateForm/index.tsx b/packages/console/src/pages/Applications/components/CreateForm/index.tsx
new file mode 100644
index 000000000..0829cde10
--- /dev/null
+++ b/packages/console/src/pages/Applications/components/CreateForm/index.tsx
@@ -0,0 +1,62 @@
+import { ApplicationType } from '@logto/schemas';
+import React from 'react';
+import { useController, useForm } from 'react-hook-form';
+import { useTranslation } from 'react-i18next';
+
+import Card from '@/components/Card';
+import CardTitle from '@/components/CardTitle';
+import FormField from '@/components/FormField';
+import RadioGroup, { Radio } from '@/components/RadioGroup';
+import Close from '@/icons/Close';
+import { applicationTypeI18nKey } from '@/types/applications';
+
+import TypeDescription from '../TypeDescription';
+import * as styles from './index.module.scss';
+
+type FormData = {
+ type: ApplicationType;
+ name: string;
+ description?: string;
+};
+
+type Props = {
+ onClose?: () => void;
+};
+
+const CreateForm = ({ onClose }: Props) => {
+ const { handleSubmit, control } = useForm();
+ const {
+ field: { onChange, value },
+ } = useController({ name: 'type', control });
+ const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
+
+ const onSubmit = handleSubmit((data) => {
+ console.log(data);
+ });
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default CreateForm;
diff --git a/packages/console/src/pages/Applications/components/TypeDescription/index.module.scss b/packages/console/src/pages/Applications/components/TypeDescription/index.module.scss
new file mode 100644
index 000000000..bc9495a78
--- /dev/null
+++ b/packages/console/src/pages/Applications/components/TypeDescription/index.module.scss
@@ -0,0 +1,17 @@
+@use '@/scss/underscore' as _;
+
+.subtitle,
+.description {
+ margin-top: _.unit(3);
+ flex: 2;
+}
+
+.subtitle {
+ font: var(--font-body);
+ color: var(--color-text-default);
+}
+
+.description {
+ font: var(--font-caption);
+ color: var(--color-foggy);
+}
diff --git a/packages/console/src/pages/Applications/components/TypeDescription/index.tsx b/packages/console/src/pages/Applications/components/TypeDescription/index.tsx
new file mode 100644
index 000000000..61b6b39d7
--- /dev/null
+++ b/packages/console/src/pages/Applications/components/TypeDescription/index.tsx
@@ -0,0 +1,19 @@
+import React from 'react';
+
+import * as styles from './index.module.scss';
+
+type Props = {
+ subtitle: string;
+ description: string;
+};
+
+const TypeDescription = ({ subtitle, description }: Props) => {
+ return (
+ <>
+ {subtitle}
+ {description}
+ >
+ );
+};
+
+export default TypeDescription;
diff --git a/packages/console/src/pages/Applications/index.tsx b/packages/console/src/pages/Applications/index.tsx
index 671305431..e29f75c41 100644
--- a/packages/console/src/pages/Applications/index.tsx
+++ b/packages/console/src/pages/Applications/index.tsx
@@ -1,6 +1,7 @@
import { Application } from '@logto/schemas';
-import React from 'react';
+import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
+import Modal from 'react-modal';
import useSWR from 'swr';
import Button from '@/components/Button';
@@ -9,12 +10,15 @@ import CardTitle from '@/components/CardTitle';
import CopyToClipboard from '@/components/CopyToClipboard';
import ImagePlaceholder from '@/components/ImagePlaceholder';
import ItemPreview from '@/components/ItemPreview';
+import * as modalStyles from '@/scss/modal.module.scss';
import { RequestError } from '@/swr';
import { applicationTypeI18nKey } from '@/types/applications';
+import CreateForm from './components/CreateForm';
import * as styles from './index.module.scss';
const Applications = () => {
+ const [isCreateFormOpen, setIsCreateFormOpen] = useState(false);
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { data, error } = useSWR('/api/applications');
const isLoading = !data && !error;
@@ -23,7 +27,23 @@ const Applications = () => {
-
+
@@ -48,7 +68,7 @@ const Applications = () => {
}
/>
|
diff --git a/packages/console/src/scss/modal.module.scss b/packages/console/src/scss/modal.module.scss
new file mode 100644
index 000000000..c32410973
--- /dev/null
+++ b/packages/console/src/scss/modal.module.scss
@@ -0,0 +1,13 @@
+.content {
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translateX(-50%, -50%);
+ outline: none;
+}
+
+.overlay {
+ position: fixed;
+ background: rgba(0, 0, 0, 40%);
+ inset: 0;
+}
diff --git a/packages/console/src/types/applications.ts b/packages/console/src/types/applications.ts
index 2542799eb..dfa0dcd53 100644
--- a/packages/console/src/types/applications.ts
+++ b/packages/console/src/types/applications.ts
@@ -1,8 +1,7 @@
-import { AdminConsoleKey } from '@logto/phrases';
import { ApplicationType } from '@logto/schemas';
-export const applicationTypeI18nKey: Record = {
+export const applicationTypeI18nKey = Object.freeze({
[ApplicationType.Native]: 'applications.type.native',
[ApplicationType.SPA]: 'applications.type.spa',
- [ApplicationType.Traditional]: 'applications.type.tranditional',
-};
+ [ApplicationType.Traditional]: 'applications.type.traditional',
+} as const);
diff --git a/packages/phrases/src/locales/en.ts b/packages/phrases/src/locales/en.ts
index 8cad89c16..8b9e04278 100644
--- a/packages/phrases/src/locales/en.ts
+++ b/packages/phrases/src/locales/en.ts
@@ -19,6 +19,9 @@ const translation = {
copying: 'Copying',
copied: 'Copied',
},
+ form: {
+ required: 'Required',
+ },
tab_sections: {
overview: 'Overview',
resource_management: 'Resource Management',
@@ -44,11 +47,24 @@ const translation = {
'Setup a mobile, single page or traditional application to use Logto for authentication.',
create: 'Create Application',
application_name: 'Application Name',
+ select_application_type: 'Select an application type',
client_id: 'Client ID',
type: {
- native: 'Native App',
- spa: 'Single Page App',
- tranditional: 'Tranditional Web App',
+ native: {
+ title: 'Native',
+ subtitle: 'Mobile, desktop, CLI and smart device apps running natively.',
+ description: 'E.g.: iOS, Electron, Apple TV apps',
+ },
+ spa: {
+ title: 'Single Page App',
+ subtitle: 'A JavaScript front-end app that uses an API.',
+ description: 'E.g.: Angular, React, Vue',
+ },
+ traditional: {
+ title: 'Tranditional Web',
+ subtitle: 'Traditional web app using redirects.',
+ description: 'E.g.: Node.js, Express, ASP.NET, Java, PHP',
+ },
},
},
api_resources: {
diff --git a/packages/phrases/src/locales/zh-cn.ts b/packages/phrases/src/locales/zh-cn.ts
index 03e4a2c1f..2a35b6ce9 100644
--- a/packages/phrases/src/locales/zh-cn.ts
+++ b/packages/phrases/src/locales/zh-cn.ts
@@ -21,6 +21,9 @@ const translation = {
copying: '拷贝中',
copied: '已拷贝',
},
+ form: {
+ required: '必填',
+ },
tab_sections: {
overview: '概览',
resource_management: '资源管理',
@@ -46,11 +49,24 @@ const translation = {
'Setup a mobile, single page or traditional application to use Logto for authentication.',
create: 'Create Application',
application_name: 'Application Name',
+ select_application_type: 'Select an application type',
client_id: 'Client ID',
type: {
- native: 'Native App',
- spa: 'Single Page App',
- tranditional: 'Tranditional Web App',
+ native: {
+ title: 'Native',
+ subtitle: 'Mobile, desktop, CLI and smart device apps running natively.',
+ description: 'E.g.: iOS, Electron, Apple TV apps',
+ },
+ spa: {
+ title: 'Single Page App',
+ subtitle: 'A JavaScript front-end app that uses an API.',
+ description: 'E.g.: Angular, React, Vue',
+ },
+ traditional: {
+ title: 'Tranditional Web',
+ subtitle: 'Traditional web app using redirects.',
+ description: 'E.g.: Node.js, Express, ASP.NET, Java, PHP',
+ },
},
},
api_resources: {
diff --git a/packages/ui/src/components/AppContent/index.module.scss b/packages/ui/src/components/AppContent/index.module.scss
index 604eb2dae..17bc48658 100644
--- a/packages/ui/src/components/AppContent/index.module.scss
+++ b/packages/ui/src/components/AppContent/index.module.scss
@@ -1,9 +1,6 @@
.content {
position: absolute;
- left: 0;
- top: 0;
- right: 0;
- bottom: 0;
+ inset: 0;
background: var(--color-background);
color: var(--color-body);
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 413cfd9f7..3224953ea 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -32,6 +32,7 @@ importers:
'@types/lodash.kebabcase': ^4.1.6
'@types/react': ^17.0.14
'@types/react-dom': ^17.0.9
+ '@types/react-modal': ^3.13.1
classnames: ^2.3.1
eslint: ^8.10.0
i18next: ^21.6.12
@@ -44,7 +45,9 @@ importers:
prettier: ^2.3.2
react: ^17.0.2
react-dom: ^17.0.2
+ react-hook-form: ^7.27.1
react-i18next: ^11.15.4
+ react-modal: ^3.14.4
react-router-dom: ^6.2.2
stylelint: ^13.13.1
swr: ^1.2.2
@@ -59,7 +62,9 @@ importers:
lodash.kebabcase: 4.1.1
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
+ react-hook-form: 7.27.1_react@17.0.2
react-i18next: 11.15.4_2c37a602a29bb6bd53f3de707a8cfcc5
+ react-modal: 3.14.4_react-dom@17.0.2+react@17.0.2
react-router-dom: 6.2.2_react-dom@17.0.2+react@17.0.2
swr: 1.2.2_react@17.0.2
devDependencies:
@@ -72,6 +77,7 @@ importers:
'@types/lodash.kebabcase': 4.1.6
'@types/react': 17.0.37
'@types/react-dom': 17.0.11
+ '@types/react-modal': 3.13.1
eslint: 8.10.0
lint-staged: 11.2.6
parcel: 2.3.1_postcss@8.4.6
@@ -3566,6 +3572,12 @@ packages:
'@types/react': 17.0.37
dev: true
+ /@types/react-modal/3.13.1:
+ resolution: {integrity: sha512-iY/gPvTDIy6Z+37l+ibmrY+GTV4KQTHcCyR5FIytm182RQS69G5ps4PH2FxtC7bAQ2QRHXMevsBgck7IQruHNg==}
+ dependencies:
+ '@types/react': 17.0.37
+ dev: true
+
/@types/react-router-dom/5.3.2:
resolution: {integrity: sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==}
dependencies:
@@ -6004,6 +6016,10 @@ packages:
clone-regexp: 2.2.0
dev: true
+ /exenv/1.2.2:
+ resolution: {integrity: sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=}
+ dev: false
+
/exit/0.1.2:
resolution: {integrity: sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=}
engines: {node: '>= 0.8.0'}
@@ -11202,6 +11218,15 @@ packages:
scheduler: 0.20.2
dev: false
+ /react-hook-form/7.27.1_react@17.0.2:
+ resolution: {integrity: sha512-N3a7A6zIQ8DJeThisVZGtOUabTbJw+7DHJidmB9w8m3chckv2ZWKb5MHps9d2pPJqmCDoWe53Bos56bYmJms5w==}
+ engines: {node: '>=12.22.0'}
+ peerDependencies:
+ react: ^16.8.0 || ^17
+ dependencies:
+ react: 17.0.2
+ dev: false
+
/react-i18next/11.15.4_2c37a602a29bb6bd53f3de707a8cfcc5:
resolution: {integrity: sha512-jKJNAcVcbPGK+yrTcXhLblgPY16n6NbpZZL3Mk8nswj1v3ayIiUBVDU09SgqnT+DluyQBS97hwSvPU5yVFG0yg==}
peerDependencies:
@@ -11251,6 +11276,25 @@ packages:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
dev: true
+ /react-lifecycles-compat/3.0.4:
+ resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
+ dev: false
+
+ /react-modal/3.14.4_react-dom@17.0.2+react@17.0.2:
+ resolution: {integrity: sha512-8surmulejafYCH9wfUmFyj4UfbSJwjcgbS9gf3oOItu4Hwd6ivJyVBETI0yHRhpJKCLZMUtnhzk76wXTsNL6Qg==}
+ engines: {node: '>=8'}
+ peerDependencies:
+ react: ^0.14.0 || ^15.0.0 || ^16 || ^17
+ react-dom: ^0.14.0 || ^15.0.0 || ^16 || ^17
+ dependencies:
+ exenv: 1.2.2
+ prop-types: 15.8.1
+ react: 17.0.2
+ react-dom: 17.0.2_react@17.0.2
+ react-lifecycles-compat: 3.0.4
+ warning: 4.0.3
+ dev: false
+
/react-refresh/0.9.0:
resolution: {integrity: sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==}
engines: {node: '>=0.10.0'}
@@ -13245,6 +13289,12 @@ packages:
makeerror: 1.0.12
dev: true
+ /warning/4.0.3:
+ resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
+ dependencies:
+ loose-envify: 1.4.0
+ dev: false
+
/wcwidth/1.0.1:
resolution: {integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=}
dependencies: