+
);
};
-
-PreviewNav.propTypes = {
- owner: PropTypes.shape({
- username: PropTypes.string.isRequired
- }).isRequired,
- project: PropTypes.shape({
- name: PropTypes.string.isRequired,
- id: PropTypes.string.isRequired
- }).isRequired
-};
-
-export default PreviewNav;
diff --git a/client/components/RootPage.jsx b/client/components/RootPage.tsx
similarity index 81%
rename from client/components/RootPage.jsx
rename to client/components/RootPage.tsx
index 7cb3b35cc4..24e35b0dc2 100644
--- a/client/components/RootPage.jsx
+++ b/client/components/RootPage.tsx
@@ -1,7 +1,11 @@
import styled from 'styled-components';
import { prop } from '../theme';
-const RootPage = styled.div`
+interface RootPageProps {
+ fixedHeight?: string;
+}
+
+export const RootPage = styled.div
`
min-height: 100vh;
height: ${({ fixedHeight }) => fixedHeight || '100vh'};
display: flex;
@@ -21,5 +25,3 @@ const RootPage = styled.div`
}
}
`;
-
-export default RootPage;
diff --git a/client/components/SkipLink.test.tsx b/client/components/SkipLink.test.tsx
index 692a08a616..8cf2e40052 100644
--- a/client/components/SkipLink.test.tsx
+++ b/client/components/SkipLink.test.tsx
@@ -1,15 +1,7 @@
-import { render, screen, fireEvent } from '@testing-library/react';
import React from 'react';
-import { useTranslation } from 'react-i18next';
-import '@testing-library/jest-dom';
+import { render, screen, fireEvent } from '../test-utils';
import { SkipLink } from './SkipLink';
-jest.mock('react-i18next', () => ({
- useTranslation: () => ({
- t: (key: string) => key
- })
-}));
-
describe('SkipLink', () => {
const defaultProps = {
targetId: 'main-content',
diff --git a/client/components/useAsModal.jsx b/client/components/useAsModal.jsx
deleted file mode 100644
index 1ea8d71aa7..0000000000
--- a/client/components/useAsModal.jsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import React from 'react';
-import styled from 'styled-components';
-import { useModalBehavior } from '../modules/IDE/hooks/custom-hooks';
-
-const BackgroundOverlay = styled.div`
- position: fixed;
- z-index: 2;
- width: 100% !important;
- height: 100% !important;
-
- background: black;
- opacity: 0.3;
-`;
-
-export default (Element, hasOverlay = false) => {
- const [visible, toggle, setRef] = useModalBehavior();
-
- const wrapper = () =>
- visible && (
-
- {hasOverlay &&
}
-
- {typeof Element === 'function' ? Element(toggle) : Element}
-
-
- );
-
- return [toggle, wrapper];
-};
diff --git a/client/custom.d.ts b/client/custom.d.ts
new file mode 100644
index 0000000000..216fa99ad4
--- /dev/null
+++ b/client/custom.d.ts
@@ -0,0 +1,8 @@
+declare module '*.svg' {
+ import * as React from 'react';
+
+ const ReactComponent: React.FunctionComponent<
+ React.SVGProps & { title?: string }
+ >;
+ export default ReactComponent;
+}
diff --git a/client/modules/About/pages/About.jsx b/client/modules/About/pages/About.jsx
index 5690aba0a0..ab069f5812 100644
--- a/client/modules/About/pages/About.jsx
+++ b/client/modules/About/pages/About.jsx
@@ -21,7 +21,7 @@ import {
import { ContactSectionLinks, AboutSectionInfo } from '../statics/aboutData';
import Nav from '../../IDE/components/Header/Nav';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
import packageData from '../../../../package.json';
import HeartIcon from '../../../images/heart.svg';
diff --git a/client/modules/App/components/Overlay.jsx b/client/modules/App/components/Overlay.jsx
index 2dedc82656..6ae400add7 100644
--- a/client/modules/App/components/Overlay.jsx
+++ b/client/modules/App/components/Overlay.jsx
@@ -4,7 +4,7 @@ import MediaQuery from 'react-responsive';
import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
-import useModalClose from '../../../common/useModalClose';
+import { useModalClose } from '../../../common/useModalClose';
import ExitIcon from '../../../images/exit.svg';
diff --git a/client/modules/IDE/components/AssetListRow.jsx b/client/modules/IDE/components/AssetListRow.jsx
index 7e7af8f013..756f5a2d79 100644
--- a/client/modules/IDE/components/AssetListRow.jsx
+++ b/client/modules/IDE/components/AssetListRow.jsx
@@ -4,8 +4,8 @@ import { Link } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { useTranslation } from 'react-i18next';
import prettyBytes from 'pretty-bytes';
-import MenuItem from '../../../components/Dropdown/MenuItem';
-import TableDropdown from '../../../components/Dropdown/TableDropdown';
+import { MenuItem } from '../../../components/Dropdown/MenuItem';
+import { TableDropdown } from '../../../components/Dropdown/TableDropdown';
import { deleteAssetRequest } from '../actions/assets';
const AssetMenu = ({ item: asset }) => {
diff --git a/client/modules/IDE/components/CollectionList/CollectionListRow.jsx b/client/modules/IDE/components/CollectionList/CollectionListRow.jsx
index 35b0ae6b09..6ae24e74e9 100644
--- a/client/modules/IDE/components/CollectionList/CollectionListRow.jsx
+++ b/client/modules/IDE/components/CollectionList/CollectionListRow.jsx
@@ -5,8 +5,8 @@ import { Link } from 'react-router-dom';
import { bindActionCreators } from 'redux';
import { withTranslation } from 'react-i18next';
import styled from 'styled-components';
-import MenuItem from '../../../../components/Dropdown/MenuItem';
-import TableDropdown from '../../../../components/Dropdown/TableDropdown';
+import { MenuItem } from '../../../../components/Dropdown/MenuItem';
+import { TableDropdown } from '../../../../components/Dropdown/TableDropdown';
import * as ProjectActions from '../../actions/project';
import * as CollectionsActions from '../../actions/collections';
import * as IdeActions from '../../actions/ide';
diff --git a/client/modules/IDE/components/Editor/index.jsx b/client/modules/IDE/components/Editor/index.jsx
index 76bf2f03f2..4e4b7c784d 100644
--- a/client/modules/IDE/components/Editor/index.jsx
+++ b/client/modules/IDE/components/Editor/index.jsx
@@ -71,7 +71,7 @@ import EditorAccessibility from '../EditorAccessibility';
import UnsavedChangesIndicator from '../UnsavedChangesIndicator';
import { EditorContainer, EditorHolder } from './MobileEditor';
import { FolderIcon } from '../../../../common/icons';
-import IconButton from '../../../../common/IconButton';
+import { IconButton } from '../../../../common/IconButton';
emmet(CodeMirror);
diff --git a/client/modules/IDE/components/Header/MobileNav.jsx b/client/modules/IDE/components/Header/MobileNav.jsx
index fb13dec9ef..ce4a4cd49d 100644
--- a/client/modules/IDE/components/Header/MobileNav.jsx
+++ b/client/modules/IDE/components/Header/MobileNav.jsx
@@ -6,12 +6,12 @@ import { Link } from 'react-router-dom';
import { sortBy } from 'lodash';
import classNames from 'classnames';
import { ParentMenuContext } from '../../../../components/Menubar/contexts';
-import Menubar from '../../../../components/Menubar/Menubar';
+import { Menubar } from '../../../../components/Menubar/Menubar';
import { useMenuProps } from '../../../../components/Menubar/MenubarSubmenu';
-import ButtonOrLink from '../../../../common/ButtonOrLink';
+import { ButtonOrLink } from '../../../../common/ButtonOrLink';
import { prop, remSize } from '../../../../theme';
import AsteriskIcon from '../../../../images/p5-asterisk.svg';
-import IconButton from '../../../../common/IconButton';
+import { IconButton } from '../../../../common/IconButton';
import {
AccountIcon,
AddIcon,
diff --git a/client/modules/IDE/components/Header/Nav.jsx b/client/modules/IDE/components/Header/Nav.jsx
index f8f19cdb9f..511b70adc4 100644
--- a/client/modules/IDE/components/Header/Nav.jsx
+++ b/client/modules/IDE/components/Header/Nav.jsx
@@ -4,14 +4,14 @@ import { sortBy } from 'lodash';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
-import MenubarSubmenu from '../../../../components/Menubar/MenubarSubmenu';
-import MenubarItem from '../../../../components/Menubar/MenubarItem';
+import { MenubarSubmenu } from '../../../../components/Menubar/MenubarSubmenu';
+import { MenubarItem } from '../../../../components/Menubar/MenubarItem';
import { availableLanguages, languageKeyToLabel } from '../../../../i18n';
import { getConfig } from '../../../../utils/getConfig';
import { parseBoolean } from '../../../../utils/parseStringToType';
import { showToast } from '../../actions/toast';
import { setLanguage } from '../../actions/preferences';
-import Menubar from '../../../../components/Menubar/Menubar';
+import { Menubar } from '../../../../components/Menubar/Menubar';
import CaretLeftIcon from '../../../../images/left-arrow.svg';
import LogoIcon from '../../../../images/p5js-logo-small.svg';
import { selectRootFile } from '../../selectors/files';
diff --git a/client/modules/IDE/components/Header/Nav.unit.test.jsx b/client/modules/IDE/components/Header/Nav.unit.test.jsx
index a15df02f4f..d5c2465c0c 100644
--- a/client/modules/IDE/components/Header/Nav.unit.test.jsx
+++ b/client/modules/IDE/components/Header/Nav.unit.test.jsx
@@ -3,53 +3,57 @@ import React from 'react';
import { reduxRender } from '../../../../test-utils';
import Nav from './Nav';
+import { MenubarSubmenu } from '../../../../components/Menubar/MenubarSubmenu';
jest.mock('../../../../utils/generateRandomName');
// mock Menubar
-jest.mock(
- '../../../../components/Menubar/Menubar',
- () =>
- function Menubar({ children, className = 'nav__menubar' }) {
- return (
-
- );
- }
-);
+jest.mock('../../../../components/Menubar/Menubar', () => ({
+ Menubar: ({ children, className = 'nav__menubar' }) => (
+
+ )
+}));
// mock MenubarSubmenu
-jest.mock('../../../../components/Menubar/MenubarSubmenu', () => {
- function MenubarSubmenu({ children, title }) {
- return (
-
- {title}
-
-
- );
- }
+jest.mock('../../../../components/Menubar/MenubarSubmenu', () => ({
+ MenubarSubmenu: ({ children, title }) => (
+
+ {title}
+
+
+ )
+}));
+// jest.mock('../../../../components/Menubar/MenubarSubmenu', () => {
+// function MenubarSubmenu({ children, title }) {
+// return (
+//
+// {title}
+//
+//
+// );
+// }
- MenubarSubmenu.useMenuProps = () => ({
- isOpen: false,
- handlers: {}
- });
+// MenubarSubmenu.useMenuProps = () => ({
+// isOpen: false,
+// handlers: {}
+// });
- return MenubarSubmenu;
-});
+// return MenubarSubmenu;
+// });
// mock MenubarItem
-jest.mock(
- '../../../../components/Menubar/MenubarItem',
- () =>
- function MenubarItem({ children, hideIf }) {
- if (hideIf) return null;
-
- return {children};
- }
-);
+jest.mock('../../../../components/Menubar/MenubarItem', () => ({
+ MenubarItem: ({ children, hideIf }) => {
+ if (hideIf) return null;
+ return {children};
+ }
+}));
describe('Nav', () => {
it('renders editor version for desktop', () => {
diff --git a/client/modules/IDE/components/IDEKeyHandlers.jsx b/client/modules/IDE/components/IDEKeyHandlers.jsx
index fc0219f27d..14e3cf2cba 100644
--- a/client/modules/IDE/components/IDEKeyHandlers.jsx
+++ b/client/modules/IDE/components/IDEKeyHandlers.jsx
@@ -13,7 +13,7 @@ import {
} from '../actions/ide';
import { setAllAccessibleOutput } from '../actions/preferences';
import { cloneProject, saveProject } from '../actions/project';
-import useKeyDownHandlers from '../../../common/useKeyDownHandlers';
+import { useKeyDownHandlers } from '../../../common/useKeyDownHandlers';
import {
getAuthenticated,
getIsUserOwner,
diff --git a/client/modules/IDE/components/Modal.jsx b/client/modules/IDE/components/Modal.jsx
index 831527b266..c3456373c0 100644
--- a/client/modules/IDE/components/Modal.jsx
+++ b/client/modules/IDE/components/Modal.jsx
@@ -1,7 +1,7 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
-import useModalClose from '../../../common/useModalClose';
+import { useModalClose } from '../../../common/useModalClose';
import ExitIcon from '../../../images/exit.svg';
// Common logic from NewFolderModal, NewFileModal, UploadFileModal
diff --git a/client/modules/IDE/components/NewFileForm.jsx b/client/modules/IDE/components/NewFileForm.jsx
index 9620e321dc..dda19e343c 100644
--- a/client/modules/IDE/components/NewFileForm.jsx
+++ b/client/modules/IDE/components/NewFileForm.jsx
@@ -5,7 +5,7 @@ import { useDispatch } from 'react-redux';
import { handleCreateFile } from '../actions/files';
import { CREATE_FILE_REGEX } from '../../../../server/utils/fileUtils';
-import Button from '../../../common/Button';
+import { Button, ButtonTypes } from '../../../common/Button';
function NewFileForm() {
const fileNameInput = useRef(null);
@@ -57,7 +57,7 @@ function NewFileForm() {
{() => (
-
{() => (
-
+
{t('NewFolderForm.AddFolderSubmit')}
)}
diff --git a/client/modules/IDE/components/SketchListRowBase.jsx b/client/modules/IDE/components/SketchListRowBase.jsx
index 62eff65c03..4d83ee0304 100644
--- a/client/modules/IDE/components/SketchListRowBase.jsx
+++ b/client/modules/IDE/components/SketchListRowBase.jsx
@@ -6,8 +6,8 @@ import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as ProjectActions from '../actions/project';
import * as IdeActions from '../actions/ide';
-import TableDropdown from '../../../components/Dropdown/TableDropdown';
-import MenuItem from '../../../components/Dropdown/MenuItem';
+import { TableDropdown } from '../../../components/Dropdown/TableDropdown';
+import { MenuItem } from '../../../components/Dropdown/MenuItem';
import { formatDateToString } from '../../../utils/formatDate';
import { getConfig } from '../../../utils/getConfig';
import VisibilityDropdown from '../../User/components/VisibilityDropdown';
diff --git a/client/modules/IDE/components/VersionPicker.jsx b/client/modules/IDE/components/VersionPicker.jsx
index cd891d020c..8b00fcf40d 100644
--- a/client/modules/IDE/components/VersionPicker.jsx
+++ b/client/modules/IDE/components/VersionPicker.jsx
@@ -7,8 +7,8 @@ import styled from 'styled-components';
import { prop } from '../../../theme';
import { useP5Version } from '../hooks/useP5Version';
import { p5Versions } from '../../../../common/p5Versions';
-import MenuItem from '../../../components/Dropdown/MenuItem';
-import DropdownMenu from '../../../components/Dropdown/DropdownMenu';
+import { MenuItem } from '../../../components/Dropdown/MenuItem';
+import { DropdownMenu } from '../../../components/Dropdown/DropdownMenu';
import { updateFileContent } from '../actions/files';
// eslint-disable-next-line import/no-cycle
import { CmControllerContext } from '../pages/IDEView';
diff --git a/client/modules/IDE/pages/FullView.jsx b/client/modules/IDE/pages/FullView.jsx
index 31f58a7df3..bf2e66fdcb 100644
--- a/client/modules/IDE/pages/FullView.jsx
+++ b/client/modules/IDE/pages/FullView.jsx
@@ -3,7 +3,7 @@ import Helmet from 'react-helmet';
import { useDispatch, useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import PreviewFrame from '../components/PreviewFrame';
-import PreviewNav from '../../../components/PreviewNav';
+import { PreviewNav } from '../../../components/PreviewNav';
import { getProject } from '../actions/project';
import { startSketch } from '../actions/ide';
import {
@@ -12,7 +12,7 @@ import {
MessageTypes
} from '../../../utils/dispatcher';
import useInterval from '../hooks/useInterval';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
function FullView() {
const dispatch = useDispatch();
diff --git a/client/modules/IDE/pages/IDEView.jsx b/client/modules/IDE/pages/IDEView.jsx
index 8f253c67d7..f3d869937b 100644
--- a/client/modules/IDE/pages/IDEView.jsx
+++ b/client/modules/IDE/pages/IDEView.jsx
@@ -16,7 +16,7 @@ import {
getProject
} from '../actions/project';
import { getIsUserOwner } from '../selectors/users';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
import Header from '../components/Header';
import FloatingActionButton from '../components/FloatingActionButton';
import Editor from '../components/Editor';
diff --git a/client/modules/Legal/pages/Legal.jsx b/client/modules/Legal/pages/Legal.jsx
index 0e629f789a..4ba5cb5bbc 100644
--- a/client/modules/Legal/pages/Legal.jsx
+++ b/client/modules/Legal/pages/Legal.jsx
@@ -4,8 +4,8 @@ import React, { useEffect, useState } from 'react';
import Helmet from 'react-helmet';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
-import RouterTab from '../../../common/RouterTab';
-import RootPage from '../../../components/RootPage';
+import { RouterTab } from '../../../common/RouterTab';
+import { RootPage } from '../../../components/RootPage';
import { remSize } from '../../../theme';
import Loader from '../../App/components/loader';
import Nav from '../../IDE/components/Header/Nav';
diff --git a/client/modules/User/components/APIKeyForm.jsx b/client/modules/User/components/APIKeyForm.jsx
index eff0ae2d7b..fda5945f87 100644
--- a/client/modules/User/components/APIKeyForm.jsx
+++ b/client/modules/User/components/APIKeyForm.jsx
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
-import Button from '../../../common/Button';
+import { Button, ButtonTypes } from '../../../common/Button';
import { PlusIcon } from '../../../common/icons';
import CopyableInput from '../../IDE/components/CopyableInput';
import { createApiKey, removeApiKey } from '../actions';
@@ -78,7 +78,7 @@ const APIKeyForm = () => {
disabled={keyLabel === ''}
iconBefore={}
label="Create new key"
- type="submit"
+ type={ButtonTypes.SUBMIT}
>
{t('APIKeyForm.CreateTokenSubmit')}
diff --git a/client/modules/User/components/AccountForm.jsx b/client/modules/User/components/AccountForm.jsx
index c738e79db2..4ef40e4298 100644
--- a/client/modules/User/components/AccountForm.jsx
+++ b/client/modules/User/components/AccountForm.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import { Form, Field } from 'react-final-form';
import { useSelector, useDispatch } from 'react-redux';
import { useTranslation } from 'react-i18next';
-import Button from '../../../common/Button';
+import { Button, ButtonTypes } from '../../../common/Button';
import { validateSettings } from '../../../utils/reduxFormUtils';
import { updateSettings, initiateVerification } from '../actions';
import { apiClient } from '../../../utils/apiClient';
@@ -175,7 +175,7 @@ function AccountForm() {
)}
)}
-
+
{t('AccountForm.SaveAccountDetails')}
diff --git a/client/modules/User/components/CollectionCreate.jsx b/client/modules/User/components/CollectionCreate.jsx
index 02d3fb59f0..3b2ccdefed 100644
--- a/client/modules/User/components/CollectionCreate.jsx
+++ b/client/modules/User/components/CollectionCreate.jsx
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import { generateCollectionName } from '../../../utils/generateRandomName';
-import Button from '../../../common/Button';
+import { Button, ButtonTypes } from '../../../common/Button';
import { createCollection } from '../../IDE/actions/collections';
const CollectionCreate = () => {
@@ -74,7 +74,7 @@ const CollectionCreate = () => {
rows="6"
/>
-
+
{t('CollectionCreate.SubmitCollectionCreate')}
diff --git a/client/modules/User/components/CollectionMetadata.jsx b/client/modules/User/components/CollectionMetadata.jsx
index 88dc6d0312..dcb47e0929 100644
--- a/client/modules/User/components/CollectionMetadata.jsx
+++ b/client/modules/User/components/CollectionMetadata.jsx
@@ -4,7 +4,7 @@ import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
-import Button from '../../../common/Button';
+import { Button } from '../../../common/Button';
import Overlay from '../../App/components/Overlay';
import { editCollection } from '../../IDE/actions/collections';
import AddToCollectionSketchList from '../../IDE/components/AddToCollectionSketchList';
diff --git a/client/modules/User/components/CollectionShareButton.jsx b/client/modules/User/components/CollectionShareButton.jsx
index c4fd06bcb6..a5d8705dcd 100644
--- a/client/modules/User/components/CollectionShareButton.jsx
+++ b/client/modules/User/components/CollectionShareButton.jsx
@@ -2,9 +2,9 @@ import PropTypes from 'prop-types';
import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
-import Button from '../../../common/Button';
+import { Button } from '../../../common/Button';
import { DropdownArrowIcon } from '../../../common/icons';
-import useModalClose from '../../../common/useModalClose';
+import { useModalClose } from '../../../common/useModalClose';
import CopyableInput from '../../IDE/components/CopyableInput';
const ShareURL = ({ value }) => {
diff --git a/client/modules/User/components/CookieConsent.jsx b/client/modules/User/components/CookieConsent.jsx
index 0817e10c70..9cfff74ac6 100644
--- a/client/modules/User/components/CookieConsent.jsx
+++ b/client/modules/User/components/CookieConsent.jsx
@@ -10,7 +10,7 @@ import PropTypes from 'prop-types';
import { getConfig } from '../../../utils/getConfig';
import { setUserCookieConsent } from '../actions';
import { remSize, prop, device } from '../../../theme';
-import Button from '../../../common/Button';
+import { Button, ButtonKinds } from '../../../common/Button';
const CookieConsentContainer = styled.div`
position: fixed;
@@ -177,10 +177,7 @@ function CookieConsent({ hide }) {
/>
-
+
{t('Cookies.AllowAll')}
diff --git a/client/modules/User/components/DashboardTabSwitcher.jsx b/client/modules/User/components/DashboardTabSwitcher.jsx
index 6bfdb9bb22..7afbe5aec8 100644
--- a/client/modules/User/components/DashboardTabSwitcher.jsx
+++ b/client/modules/User/components/DashboardTabSwitcher.jsx
@@ -4,8 +4,8 @@ import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import { FilterIcon } from '../../../common/icons';
-import IconButton from '../../../common/IconButton';
-import RouterTab from '../../../common/RouterTab';
+import { IconButton } from '../../../common/IconButton';
+import { RouterTab } from '../../../common/RouterTab';
import { Options } from '../../IDE/components/Header/MobileNav';
import { toggleDirectionForField } from '../../IDE/actions/sorting';
import useIsMobile from '../../IDE/hooks/useIsMobile';
diff --git a/client/modules/User/components/LoginForm.jsx b/client/modules/User/components/LoginForm.jsx
index 6d5d6a1b2e..5bac902ecf 100644
--- a/client/modules/User/components/LoginForm.jsx
+++ b/client/modules/User/components/LoginForm.jsx
@@ -3,10 +3,10 @@ import { useTranslation } from 'react-i18next';
import { Form, Field } from 'react-final-form';
import { useDispatch } from 'react-redux';
import { AiOutlineEye, AiOutlineEyeInvisible } from 'react-icons/ai';
-import Button from '../../../common/Button';
+import { Button, ButtonTypes } from '../../../common/Button';
import { validateLogin } from '../../../utils/reduxFormUtils';
import { validateAndLoginUser } from '../actions';
-import useSyncFormTranslations from '../../../common/useSyncFormTranslations';
+import { useSyncFormTranslations } from '../../../common/useSyncFormTranslations';
function LoginForm() {
const { t, i18n } = useTranslation();
@@ -105,7 +105,7 @@ function LoginForm() {
{t('LoginForm.Errors.invalidCredentials')}
)}
-
+
{t('LoginForm.Submit')}
diff --git a/client/modules/User/components/LoginForm.unit.test.jsx b/client/modules/User/components/LoginForm.unit.test.jsx
index 7ab207fb01..2f4262c16b 100644
--- a/client/modules/User/components/LoginForm.unit.test.jsx
+++ b/client/modules/User/components/LoginForm.unit.test.jsx
@@ -23,7 +23,9 @@ jest.mock('../actions', () => ({
)
}));
-jest.mock('../../../common/useSyncFormTranslations', () => jest.fn());
+jest.mock('../../../common/useSyncFormTranslations', () => ({
+ useSyncFormTranslations: jest.fn()
+}));
const subject = () => {
reduxRender(, {
diff --git a/client/modules/User/components/NewPasswordForm.jsx b/client/modules/User/components/NewPasswordForm.jsx
index 95e96ec4a3..feca326c77 100644
--- a/client/modules/User/components/NewPasswordForm.jsx
+++ b/client/modules/User/components/NewPasswordForm.jsx
@@ -5,7 +5,7 @@ import { useDispatch } from 'react-redux';
import { useTranslation } from 'react-i18next';
import { validateNewPassword } from '../../../utils/reduxFormUtils';
import { updatePassword } from '../actions';
-import Button from '../../../common/Button';
+import { Button, ButtonTypes } from '../../../common/Button';
function NewPasswordForm(props) {
const { resetPasswordToken } = props;
@@ -64,7 +64,10 @@ function NewPasswordForm(props) {
)}
-
+
{t('NewPasswordForm.SubmitSetNewPassword')}
diff --git a/client/modules/User/components/ResetPasswordForm.jsx b/client/modules/User/components/ResetPasswordForm.jsx
index f44e7649bd..fe3752fdf4 100644
--- a/client/modules/User/components/ResetPasswordForm.jsx
+++ b/client/modules/User/components/ResetPasswordForm.jsx
@@ -4,7 +4,7 @@ import { Form, Field } from 'react-final-form';
import { useDispatch, useSelector } from 'react-redux';
import { validateResetPassword } from '../../../utils/reduxFormUtils';
import { initiateResetPassword } from '../actions';
-import Button from '../../../common/Button';
+import { Button, ButtonTypes } from '../../../common/Button';
function ResetPasswordForm(props) {
const { t } = useTranslation();
@@ -45,7 +45,7 @@ function ResetPasswordForm(props) {
)}
)}
-
+
{t('SignupForm.SubmitSignup')}
diff --git a/client/modules/User/components/SocialAuthButton.jsx b/client/modules/User/components/SocialAuthButton.jsx
index ac4a8b3b11..e48c660b67 100644
--- a/client/modules/User/components/SocialAuthButton.jsx
+++ b/client/modules/User/components/SocialAuthButton.jsx
@@ -6,7 +6,7 @@ import { useDispatch } from 'react-redux';
import { remSize } from '../../../theme';
import { GithubIcon, GoogleIcon } from '../../../common/icons';
-import Button from '../../../common/Button';
+import { Button } from '../../../common/Button';
import { unlinkService } from '../actions';
import { persistState } from '../../IDE/actions/project';
diff --git a/client/modules/User/pages/CollectionView.jsx b/client/modules/User/pages/CollectionView.jsx
index e52eb2c279..8207388086 100644
--- a/client/modules/User/pages/CollectionView.jsx
+++ b/client/modules/User/pages/CollectionView.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import { useParams } from 'react-router-dom';
import Nav from '../../IDE/components/Header/Nav';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
import Collection from '../components/Collection';
const CollectionView = () => {
diff --git a/client/modules/User/pages/DashboardView.jsx b/client/modules/User/pages/DashboardView.jsx
index fcde949cd7..1626d0d369 100644
--- a/client/modules/User/pages/DashboardView.jsx
+++ b/client/modules/User/pages/DashboardView.jsx
@@ -3,14 +3,14 @@ import { useDispatch, useSelector } from 'react-redux';
import { useLocation, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
-import Button from '../../../common/Button';
+import { Button } from '../../../common/Button';
import Nav from '../../IDE/components/Header/Nav';
import Overlay from '../../App/components/Overlay';
import AssetList from '../../IDE/components/AssetList';
import AssetSize from '../../IDE/components/AssetSize';
import CollectionList from '../../IDE/components/CollectionList';
import SketchList from '../../IDE/components/SketchList';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
import { newProject } from '../../IDE/actions/project';
import {
CollectionSearchbar,
diff --git a/client/modules/User/pages/EmailVerificationView.jsx b/client/modules/User/pages/EmailVerificationView.jsx
index 7ad9d2fa79..d21d2446b9 100644
--- a/client/modules/User/pages/EmailVerificationView.jsx
+++ b/client/modules/User/pages/EmailVerificationView.jsx
@@ -4,7 +4,7 @@ import { useLocation, useHistory } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { useTranslation } from 'react-i18next';
import { verifyEmailConfirmation } from '../actions';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
import Nav from '../../IDE/components/Header/Nav';
const EmailVerificationView = () => {
diff --git a/client/modules/User/pages/LoginView.jsx b/client/modules/User/pages/LoginView.jsx
index 1847c84b50..b931c50ea8 100644
--- a/client/modules/User/pages/LoginView.jsx
+++ b/client/modules/User/pages/LoginView.jsx
@@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
import LoginForm from '../components/LoginForm';
import SocialAuthButton from '../components/SocialAuthButton';
import Nav from '../../IDE/components/Header/Nav';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
function LoginView() {
const { t } = useTranslation();
diff --git a/client/modules/User/pages/NewPasswordView.jsx b/client/modules/User/pages/NewPasswordView.jsx
index cb9d7cbe1d..2bc310e6a3 100644
--- a/client/modules/User/pages/NewPasswordView.jsx
+++ b/client/modules/User/pages/NewPasswordView.jsx
@@ -7,7 +7,7 @@ import { useParams } from 'react-router-dom';
import NewPasswordForm from '../components/NewPasswordForm';
import { validateResetPasswordToken } from '../actions';
import Nav from '../../IDE/components/Header/Nav';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
function NewPasswordView() {
const { t } = useTranslation();
diff --git a/client/modules/User/pages/ResetPasswordView.jsx b/client/modules/User/pages/ResetPasswordView.jsx
index 9188a5e2c8..e744311b7c 100644
--- a/client/modules/User/pages/ResetPasswordView.jsx
+++ b/client/modules/User/pages/ResetPasswordView.jsx
@@ -5,7 +5,7 @@ import { useSelector } from 'react-redux';
import { Helmet } from 'react-helmet';
import { useTranslation } from 'react-i18next';
import ResetPasswordForm from '../components/ResetPasswordForm';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
import Nav from '../../IDE/components/Header/Nav';
function ResetPasswordView() {
diff --git a/client/modules/User/pages/SignupView.jsx b/client/modules/User/pages/SignupView.jsx
index 6b1e1fff51..16e038c6e0 100644
--- a/client/modules/User/pages/SignupView.jsx
+++ b/client/modules/User/pages/SignupView.jsx
@@ -5,7 +5,7 @@ import { useTranslation, Trans } from 'react-i18next';
import SignupForm from '../components/SignupForm';
import SocialAuthButton from '../components/SocialAuthButton';
import Nav from '../../IDE/components/Header/Nav';
-import RootPage from '../../../components/RootPage';
+import { RootPage } from '../../../components/RootPage';
function SignupView() {
const { t } = useTranslation();
diff --git a/package-lock.json b/package-lock.json
index f968228de1..31ceb6c724 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -158,6 +158,8 @@
"@types/node": "^16.18.126",
"@types/react": "^16.14.0",
"@types/react-dom": "^16.9.25",
+ "@types/react-router-dom": "^5.3.3",
+ "@types/styled-components": "^5.1.34",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"babel-core": "^7.0.0-bridge.0",
@@ -14131,6 +14133,13 @@
"@types/unist": "*"
}
},
+ "node_modules/@types/history": {
+ "version": "4.7.11",
+ "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
+ "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
@@ -14368,6 +14377,29 @@
"redux": "^4.0.0"
}
},
+ "node_modules/@types/react-router": {
+ "version": "5.1.20",
+ "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz",
+ "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/history": "^4.7.11",
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/react-router-dom": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz",
+ "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/history": "^4.7.11",
+ "@types/react": "*",
+ "@types/react-router": "*"
+ }
+ },
"node_modules/@types/react/node_modules/csstype": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz",
@@ -14434,6 +14466,25 @@
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
"dev": true
},
+ "node_modules/@types/styled-components": {
+ "version": "5.1.34",
+ "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.34.tgz",
+ "integrity": "sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hoist-non-react-statics": "*",
+ "@types/react": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/styled-components/node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/testing-library__jest-dom": {
"version": "5.14.0",
"resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.0.tgz",
@@ -50505,6 +50556,12 @@
"@types/unist": "*"
}
},
+ "@types/history": {
+ "version": "4.7.11",
+ "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
+ "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
+ "dev": true
+ },
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
@@ -50746,6 +50803,27 @@
"redux": "^4.0.0"
}
},
+ "@types/react-router": {
+ "version": "5.1.20",
+ "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz",
+ "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==",
+ "dev": true,
+ "requires": {
+ "@types/history": "^4.7.11",
+ "@types/react": "*"
+ }
+ },
+ "@types/react-router-dom": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz",
+ "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==",
+ "dev": true,
+ "requires": {
+ "@types/history": "^4.7.11",
+ "@types/react": "*",
+ "@types/react-router": "*"
+ }
+ },
"@types/redux-devtools-themes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/redux-devtools-themes/-/redux-devtools-themes-1.0.0.tgz",
@@ -50807,6 +50885,25 @@
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
"dev": true
},
+ "@types/styled-components": {
+ "version": "5.1.34",
+ "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.34.tgz",
+ "integrity": "sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA==",
+ "dev": true,
+ "requires": {
+ "@types/hoist-non-react-statics": "*",
+ "@types/react": "*",
+ "csstype": "^3.0.2"
+ },
+ "dependencies": {
+ "csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "dev": true
+ }
+ }
+ },
"@types/testing-library__jest-dom": {
"version": "5.14.0",
"resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.0.tgz",
diff --git a/package.json b/package.json
index a6117f966d..431913dd97 100644
--- a/package.json
+++ b/package.json
@@ -130,6 +130,8 @@
"@types/node": "^16.18.126",
"@types/react": "^16.14.0",
"@types/react-dom": "^16.9.25",
+ "@types/react-router-dom": "^5.3.3",
+ "@types/styled-components": "^5.1.34",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"babel-core": "^7.0.0-bridge.0",