diff --git a/CHANGELOG.md b/CHANGELOG.md
index c1a2cc7..2a12d14 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
### Releases
+## v1.1.0
+###### *Dec 6, 2020*
+
+- package.json: update `recoil` version to 0.1.2
+- components:
+ - Divider: add property `withoutMargins`, change margins based on `orientation`
+ - Loading: add first class property `position`
+ - NotFound: add 404 gif from `giphy`, move from `Box` to `Fb`
+ - Link: fix `export default` style
+ - Fb: create flexbox component
+
## v1.0.2
###### *Sep 7, 2020*
diff --git a/src/App.js b/src/App.js
index 2db6e2f..2d0c251 100644
--- a/src/App.js
+++ b/src/App.js
@@ -2,12 +2,12 @@ import React from 'react';
import { RecoilRoot } from 'recoil';
import CssBaseline from '@material-ui/core/CssBaseline';
-import Box from '@material-ui/core/Box';
import withErrorHandler from 'errorHandling';
import { App as ErrorBoundaryFallback } from 'errorHandling/Fallbacks';
import Layout from 'sections/Layout';
+import Fb from 'components/Fb';
import { ThemeProvider } from 'theme';
import { BrowserRouter as Router } from 'react-router-dom';
@@ -16,12 +16,12 @@ function App() {
return (
-
+
-
+
);
diff --git a/src/components/Page/styles.js b/src/components/Page/styles.js
index 7af1bb8..5ab1c54 100644
--- a/src/components/Page/styles.js
+++ b/src/components/Page/styles.js
@@ -1,6 +1,6 @@
import { makeStyles } from '@material-ui/core/styles';
-import { isMobile } from 'utils';
+import isMobile from 'utils/isMobile';
const useStyles = makeStyles(theme => ({
root: {
diff --git a/src/errorHandling/Fallbacks/App/Component.js b/src/errorHandling/Fallbacks/App/Component.js
index 446f07b..60493c5 100644
--- a/src/errorHandling/Fallbacks/App/Component.js
+++ b/src/errorHandling/Fallbacks/App/Component.js
@@ -6,7 +6,7 @@ import Button from '@material-ui/core/Button';
import { FaRedo as ResetIcon } from 'react-icons/fa';
-import { resetApp } from 'utils';
+import resetApp from 'utils/resetApp';
import { messages, email } from 'config';
import useStyles from './styles';
diff --git a/src/global.css b/src/global.css
index 1532074..7953e6c 100644
--- a/src/global.css
+++ b/src/global.css
@@ -6,3 +6,16 @@ body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
+
+.full-width {
+ width: 100%;
+}
+
+.full-height {
+ height: 100%;
+}
+
+.full-size {
+ width: 100%;
+ height: 100%;
+}
diff --git a/src/pages/Welcome/Component.js b/src/pages/Welcome/Component.js
index faf5b48..19184fc 100644
--- a/src/pages/Welcome/Component.js
+++ b/src/pages/Welcome/Component.js
@@ -2,18 +2,18 @@ import React from 'react';
import Container from '@material-ui/core/Container';
import Typography from '@material-ui/core/Typography';
-import Box from '@material-ui/core/Box';
import useMediaQuery from '@material-ui/core/useMediaQuery';
import { FaReact as ReactIcon } from 'react-icons/fa';
+import Fb from 'components/Fb';
import Meta from 'components/Meta';
import useStyles from './styles';
function Welcome() {
const matchSmallScreen = useMediaQuery('(max-width: 600px)');
- const classes = useStyles({ isSmallScreen: matchSmallScreen });
+ const classes = useStyles();
return (
<>
@@ -21,16 +21,16 @@ function Welcome() {
title="Welcome"
description="Welcome to React PWA"
/>
-
-
-
+
+
+
React PWA
-
+
>
);
diff --git a/src/pages/Welcome/styles.js b/src/pages/Welcome/styles.js
index 8dfc8a6..9070e32 100644
--- a/src/pages/Welcome/styles.js
+++ b/src/pages/Welcome/styles.js
@@ -1,16 +1,9 @@
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles(theme => ({
- root: {
- display: 'flex',
- 'justify-content': 'center',
- 'align-items': 'center',
- height: '100%',
- },
wrapper: {
- display: 'flex',
+ height: '100%',
'user-select': 'none',
- 'align-items': ({ isSmallScreen }) => isSmallScreen ? 'center' : 'initial',
'text-align': 'center',
},
icon: {
diff --git a/src/routes/index.js b/src/routes/index.js
index 5d115c5..1b74bbc 100644
--- a/src/routes/index.js
+++ b/src/routes/index.js
@@ -1,4 +1,4 @@
-import { asyncComponentLoader } from 'utils';
+import asyncComponentLoader from 'utils/asyncComponentLoader';
const routes = [
{
diff --git a/src/sections/AppBar/Component.js b/src/sections/AppBar/Component.js
index b6c3e89..a510b65 100644
--- a/src/sections/AppBar/Component.js
+++ b/src/sections/AppBar/Component.js
@@ -4,10 +4,7 @@ import Toolbar from '@material-ui/core/Toolbar';
import AppBar from '@material-ui/core/AppBar';
import IconButton from '@material-ui/core/IconButton';
import Button from '@material-ui/core/Button';
-import Box from '@material-ui/core/Box';
-import DividerMU from '@material-ui/core/Divider';
import Tooltip from '@material-ui/core/Tooltip';
-import { withStyles } from '@material-ui/core/styles';
import {
FaBrush as BrushIcon,
@@ -17,6 +14,8 @@ import {
} from 'react-icons/fa';
import Link from 'components/Link';
+import Fb from 'components/Fb';
+import Divider from 'components/Divider';
import useTheme from 'store/theme';
import useSW from 'store/sw';
@@ -25,13 +24,6 @@ import { title, repository } from 'config';
import useStyles from './styles';
-const Divider = withStyles({
- root: {
- 'margin-left': 7,
- 'margin-right': 7,
- },
-})(props => );
-
function AppBar_({ onMenuOpen }) {
const classes = useStyles();
const [, themeActions] = useTheme();
@@ -53,7 +45,7 @@ function AppBar_({ onMenuOpen }) {
elevation={1}
>
-
+
-
-
+
+
{
swState.isUpdated && (
<>
@@ -76,7 +68,7 @@ function AppBar_({ onMenuOpen }) {
-
+
>
)
}
@@ -91,7 +83,7 @@ function AppBar_({ onMenuOpen }) {
-
+
-
+
);
diff --git a/src/sections/Copyright/Component.js b/src/sections/Copyright/Component.js
index 7dfe5bc..17356aa 100644
--- a/src/sections/Copyright/Component.js
+++ b/src/sections/Copyright/Component.js
@@ -1,9 +1,9 @@
import React from 'react';
import Typography from '@material-ui/core/Typography';
-import Box from '@material-ui/core/Box';
import Link from '@material-ui/core/Link';
+import Fb from 'components/Fb';
import { copyright, domain } from 'config';
import useStyles from './styles';
@@ -12,15 +12,15 @@ function Copyright() {
const classes = useStyles();
return (
-
-
+
+
{copyright.title}
{copyright.link}
{' '}
{new Date().getFullYear()}
-
+
);
}
diff --git a/src/sections/Layout/Component.js b/src/sections/Layout/Component.js
index 252041b..19e9fe4 100644
--- a/src/sections/Layout/Component.js
+++ b/src/sections/Layout/Component.js
@@ -1,12 +1,11 @@
import React from 'react';
-import Box from '@material-ui/core/Box';
-
import Content from 'sections/Content';
import Copyright from 'sections/Copyright';
import Navigation from 'sections/Navigation';
import Notifications from 'sections/Notifications';
+import Fb from 'components/Fb';
import useStyles from './styles';
function Layout() {
@@ -16,13 +15,13 @@ function Layout() {
<>
-
-
-
+
+
+
-
-
+
+
>
);
}
diff --git a/src/sections/Layout/styles.js b/src/sections/Layout/styles.js
index 725a185..34fc99a 100644
--- a/src/sections/Layout/styles.js
+++ b/src/sections/Layout/styles.js
@@ -9,10 +9,8 @@ const useStyles = makeStyles(theme => ({
position: 'relative',
},
content: {
- display: 'flex',
- 'flex-direction': 'column',
- 'justify-content': 'space-between',
- height: `calc(100% - ${theme.mixins.toolbar.minHeight + 8}px)`,
+ width: '100%',
+ height: `calc(100% - ${theme.mixins.toolbar + theme.spacing(1)}px)`,
},
}));
diff --git a/src/sections/Menu/Component.js b/src/sections/Menu/Component.js
index 45afc04..86af424 100644
--- a/src/sections/Menu/Component.js
+++ b/src/sections/Menu/Component.js
@@ -19,7 +19,7 @@ import {
FaBug as BugIcon,
} from 'react-icons/fa';
-import { isMobile } from 'utils';
+import isMobile from 'utils/isMobile';
import useStyles from './styles';
diff --git a/src/store/effects/index.js b/src/store/effects/index.js
deleted file mode 100644
index 927dc99..0000000
--- a/src/store/effects/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import { resetApp } from 'utils';
-import { v1 as uuidv1 } from 'uuid';
-
-const SW = {}; // don't keep it in the store
-
-const sw = {
- update() {
- const registrationWaiting = SW.registration && SW.registration.waiting;
-
- if (registrationWaiting) {
- registrationWaiting.postMessage({ type: 'SKIP_WAITING' });
- registrationWaiting.onstatechange = function(e) {
- if (e.target.state === 'activated') {
- resetApp();
- }
- };
- }
- },
- saveRegistration(registration) {
- SW.registration = registration;
- },
-};
-
-const theme = {
- lsSave(mode) {
- localStorage.setItem('theme-mode', mode);
- },
-};
-
-const genUUID = uuidv1;
-
-export { sw, theme, genUUID };
diff --git a/src/store/notifications/index.js b/src/store/notifications/index.js
index a8e66f1..63c5bb5 100644
--- a/src/store/notifications/index.js
+++ b/src/store/notifications/index.js
@@ -1,8 +1,9 @@
-import { atom, useRecoilState } from 'recoil';
+import { useCallback, useMemo } from 'react';
-import * as effects from 'store/effects';
+import { atom, useRecoilState } from 'recoil';
import { notifications as notificationsDefaults } from 'config';
+import { v1 as uuidv1 } from 'uuid';
const notificationsState = atom({
key: 'notificationsState',
@@ -12,33 +13,38 @@ const notificationsState = atom({
function useNotifications() {
const [notifications, setNotifications] = useRecoilState(notificationsState);
- function push(notification) {
+ const push = useCallback(notification => {
+ const id = uuidv1();
setNotifications(notifications => [...notifications, {
...notification,
dismissed: false,
options: {
...notificationsDefaults.options,
...notification.options,
- key: effects.genUUID(),
+ key: id,
},
}]);
- }
- function close(key, dismissAll = !key) {
+ return id;
+ }, [setNotifications]);
+
+ const close = useCallback((key, dismissAll = !key) => {
setNotifications(notifications => notifications.map(
notification => (dismissAll || notification.options.key === key)
? { ...notification, dismissed: true }
- : { ...notification }
+ : { ...notification },
));
- }
+ }, [setNotifications]);
- function remove(key) {
+ const remove = useCallback(key => {
setNotifications(notifications => notifications.filter(
notification => notification.options.key !== key,
));
- }
+ }, [setNotifications]);
+
+ const actions = useMemo(() => ({ push, close, remove }), [push, close, remove]);
- return [notifications, { push, close, remove }];
+ return [notifications, actions];
}
export default useNotifications;
diff --git a/src/store/sw/effects/index.js b/src/store/sw/effects/index.js
new file mode 100644
index 0000000..c9071a6
--- /dev/null
+++ b/src/store/sw/effects/index.js
@@ -0,0 +1,26 @@
+import resetApp from 'utils/resetApp';
+import state from 'state-local';
+
+const [getSW, setSW] = state.create({ registration: null });
+
+function update() {
+ const SW = getSW();
+ const registrationWaiting = SW.registration?.waiting;
+
+ if (registrationWaiting) {
+ registrationWaiting.postMessage({ type: 'SKIP_WAITING' });
+ registrationWaiting.onstatechange = function(e) {
+ if (e.target.state === 'activated') {
+ resetApp();
+ }
+ };
+ }
+}
+
+function storeRegistration(registration) {
+ setSW({ registration });
+}
+
+const effects = { update, storeRegistration };
+
+export default effects;
diff --git a/src/store/sw/index.js b/src/store/sw/index.js
index 83c4ee6..9ab5c69 100644
--- a/src/store/sw/index.js
+++ b/src/store/sw/index.js
@@ -1,8 +1,8 @@
import { atom, useRecoilState } from 'recoil';
import state from 'state-local';
-import { noop } from 'utils';
-import * as effects from 'store/effects';
+import noop from 'utils/noop';
+import effects from './effects';
const [getActions, setActions] = state.create({
handleSuccess: noop,
@@ -28,11 +28,11 @@ function useSW() {
function handleUpdate(registration) {
setSW(state => ({ ...state, isUpdated: true }));
- effects.sw.saveRegistration(registration);
+ effects.storeRegistration(registration);
}
function update() {
- effects.sw.update();
+ effects.update();
}
setActions({ handleSuccess, handleUpdate, update });
diff --git a/src/store/theme/index.js b/src/store/theme/index.js
index cf8f13f..455dc27 100644
--- a/src/store/theme/index.js
+++ b/src/store/theme/index.js
@@ -1,21 +1,27 @@
import { atom, useRecoilState } from 'recoil';
-import * as effects from 'store/effects';
-
import { themePair } from 'config';
const themeModeState = atom({
key: 'themeModeState',
- default: localStorage.getItem('theme-mode') || 'dark',
+ default: 'dark',
+ effects_UNSTABLE: [
+ synchronizeWithLocalStorage,
+ ],
});
+function synchronizeWithLocalStorage({ setSelf, onSet }) {
+ const storedTheme = localStorage.getItem('theme-mode');
+ storedTheme && setSelf(storedTheme);
+
+ onSet(value => localStorage.setItem('theme-mode', value));
+}
+
function useTheme() {
const [themeMode, setThemeMode] = useRecoilState(themeModeState);
function toggle() {
- const mode = themeMode === themePair[0] ? themePair[1] : themePair[0];
- setThemeMode(mode);
- effects.theme.lsSave(mode);
+ setThemeMode(mode => mode === themePair[0] ? themePair[1] : themePair[0]);
}
return [themeMode, { toggle }];
diff --git a/src/utils/asyncComponentLoader/index.js b/src/utils/asyncComponentLoader/index.js
index 07dd201..28e2b6d 100644
--- a/src/utils/asyncComponentLoader/index.js
+++ b/src/utils/asyncComponentLoader/index.js
@@ -1,4 +1,4 @@
-import _asyncComponentLoader from './loader';
+import _asyncComponentLoader, { getDelayedFallback } from './loader';
import Loading from 'components/Loading';
import LoaderErrorBoundaryFallback from 'errorHandling/Fallbacks/Loader';
@@ -11,4 +11,5 @@ const asyncComponentLoader = (
FallbackFail = LoaderErrorBoundaryFallback,
) => _asyncComponentLoader(loadComponent, loaderOptions, FallbackWaiting, FallbackFail);
+export { getDelayedFallback };
export default asyncComponentLoader;
diff --git a/src/utils/asyncComponentLoader/loader.js b/src/utils/asyncComponentLoader/loader.js
index 043dc11..3921f61 100644
--- a/src/utils/asyncComponentLoader/loader.js
+++ b/src/utils/asyncComponentLoader/loader.js
@@ -1,6 +1,6 @@
import React, { Suspense, useState, useEffect, lazy } from 'react';
-import { sleep } from 'utils';
+import sleep from 'utils/sleep';
// a little bit complex staff is going on here
// let me explain it
@@ -98,28 +98,31 @@ const getLazyComponent = (loadComponent, loaderOptions, FallbackFail) => lazy(()
// INFO: the usage of `asyncComponentLoader` looks like this:
// asyncComponentLoader(() => import('pages/Welcome'))
-const asyncComponentLoader = (
+function asyncComponentLoader(
loadComponent,
loaderOptions,
FallbackWaiting,
FallbackFail,
-) => props => {
-
- const Fallback = loaderOptions.delay
- ? getDelayedFallback(FallbackWaiting, loaderOptions.delay)
- : FallbackWaiting;
-
- const LazyComponent = getLazyComponent(
- loadComponent,
- loaderOptions,
- FallbackFail,
- );
-
- return (
- }>
-
-
- );
-};
+) {
+ return function AsyncComponent(props) {
+ const Fallback = loaderOptions.delay
+ ? getDelayedFallback(FallbackWaiting, loaderOptions.delay)
+ : FallbackWaiting;
+
+ const LazyComponent = getLazyComponent(
+ loadComponent,
+ loaderOptions,
+ FallbackFail,
+ );
+
+ return (
+ }>
+
+
+ );
+ }
+}
+
+export { getDelayedFallback };
export default asyncComponentLoader;
diff --git a/src/utils/index.js b/src/utils/index.js
deleted file mode 100644
index 7bff4ca..0000000
--- a/src/utils/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import today from './today';
-import noop from './noop';
-import isMobile from './isMobile';
-import resetApp from './resetApp';
-import downloadFile from './downloadFile';
-import sleep from './sleep';
-import asyncComponentLoader from './asyncComponentLoader';
-
-export {
- today,
- noop,
- isMobile,
- resetApp,
- downloadFile,
- sleep,
- asyncComponentLoader,
-};
diff --git a/yarn.lock b/yarn.lock
index 36e7197..8e52924 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9300,10 +9300,10 @@ realpath-native@^1.1.0:
dependencies:
util.promisify "^1.0.0"
-recoil@^0.0.10:
- version "0.0.10"
- resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.0.10.tgz#679ab22306f559f8a63c46fd5ff5241539f9248f"
- integrity sha512-+9gRqehw3yKETmoZbhSnWu4GO10HDb5xYf1CjLF1oXGK2uT6GX5Lu9mfTXwjxV/jXxEKx8MIRUUbgPxvbJ8SEw==
+recoil@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.1.2.tgz#844c612f535826dbe54c977761a67ded16f6d063"
+ integrity sha512-hIRrHlkmW4yITlBFprVYjVPhzPKYrJKoaDrrJtAtbkMeXfXaa/XE5OlyR10n+rNfnKWNToCKb3Z4fo86IGjkzg==
recursive-readdir@2.2.2:
version "2.2.2"