From 168d5fb37c927e45e784d51c8b8fbd1670a3ef59 Mon Sep 17 00:00:00 2001 From: Joonas Sandell Date: Sat, 4 May 2024 03:55:50 +0300 Subject: [PATCH] =?UTF-8?q?Convert=20to=20TypeScript=20and=20add=20ESLint/?= =?UTF-8?q?Prettier=20=F0=9F=A4=8C=20(#3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Among the conversion and linting there are additional changes included: * Set proper useEffect deps * Header: Fix initial arrow animation (unnecessary animating happened under the Splash) * Header: Remove unnecessary animation props that didn't have effect and do minor animation tweaks * Header: Remove the marquee "transition" key since it isn't a variant * Header: Rename NavItem -> HeaderNavItem * Header: Fix useMedia ssr error * Fix https://github.com/vercel/next.js/issues/65161 * Relocate locomotive-scroll wrapper to components with proper types * Add build step script for Vercel, not active currently * Figure: Don't spread props since the invalid blur* attrs could be applied (https://github.com/vercel/next.js/issues/56511) * Figure: Remove unnecessary props and add ones that could be needed * Figure: Add alt text to video also * Tweak tokens * Slightly tweak some content strings and styles * Refactor unnecessary stuff away from useInView hook * Bunch of file extension changes and sort tweaks * Relocate and fix component script * Sort keys, jsx props and destructured keys * Sitemap: Better key for projects * utility.js -> utils.ts --- .eslintrc.json | 52 + .gitignore | 4 + components/App/{App.jsx => App.tsx} | 121 +- components/App/App.types.ts | 21 + components/App/{AppHead.jsx => AppHead.tsx} | 56 +- components/App/{_index.scss => index.scss} | 0 components/App/{index.js => index.ts} | 1 + components/Button/Button.types.ts | 17 + .../{ButtonArrow.jsx => ButtonArrow.tsx} | 26 +- ...nimations.js => ButtonEnter.animations.ts} | 23 +- .../{ButtonEnter.jsx => ButtonEnter.tsx} | 33 +- components/Button/index.js | 2 - components/Button/{_index.scss => index.scss} | 0 components/Button/index.ts | 4 + .../ConditionalWrapper/ConditionalWrapper.jsx | 2 - .../ConditionalWrapper/ConditionalWrapper.tsx | 7 + .../ConditionalWrapper.types.ts | 7 + components/ConditionalWrapper/index.js | 1 - components/ConditionalWrapper/index.ts | 2 + ...ure.animations.js => Figure.animations.ts} | 11 +- components/Figure/{Figure.jsx => Figure.tsx} | 51 +- components/Figure/Figure.types.ts | 35 + components/Figure/index.js | 1 - components/Figure/{_index.scss => index.scss} | 0 components/Figure/index.ts | 3 + components/Footer/{Footer.jsx => Footer.tsx} | 6 +- components/Footer/{_index.scss => index.scss} | 0 components/Footer/{index.js => index.ts} | 0 components/Head/{Head.jsx => Head.tsx} | 20 +- components/Head/Head.types.ts | 7 + components/Head/index.js | 1 - components/Head/index.ts | 2 + ...der.animations.js => Header.animations.ts} | 163 +- components/Header/{Header.jsx => Header.tsx} | 119 +- components/Header/Header.types.ts | 13 + .../{HeaderNavItem.jsx => HeaderNavItem.tsx} | 71 +- components/Header/_Header.scss | 2 +- components/Header/index.js | 1 - components/Header/{_index.scss => index.scss} | 0 components/Header/index.ts | 4 + .../Heading/{Heading.jsx => Heading.tsx} | 10 +- components/Heading/Heading.types.ts | 9 + components/Heading/_Heading.scss | 2 +- components/Heading/index.js | 1 - .../Heading/{_index.scss => index.scss} | 0 components/Heading/index.ts | 2 + ...{Hero.animations.js => Hero.animations.ts} | 13 +- components/Hero/{Hero.jsx => Hero.tsx} | 52 +- components/Hero/Hero.types.ts | 39 + .../Hero/{HeroContent.jsx => HeroContent.tsx} | 12 +- components/Hero/{_index.scss => index.scss} | 0 components/Hero/{index.js => index.ts} | 1 + .../Hr/{Hr.animations.js => Hr.animations.ts} | 3 +- components/Hr/{Hr.jsx => Hr.tsx} | 9 +- components/Hr/Hr.types.ts | 3 + components/Hr/index.js | 1 - components/Hr/{_index.scss => index.scss} | 0 components/Hr/index.ts | 3 + components/Icon/Icon.jsx | 36 - components/Icon/Icon.tsx | 34 + components/Icon/Icon.types.ts | 3 + components/Icon/index.js | 1 - components/Icon/{_index.scss => index.scss} | 0 components/Icon/index.ts | 2 + components/Info/{Info.jsx => Info.tsx} | 35 +- components/Info/Info.types.ts | 15 + components/Info/index.js | 1 - components/Info/{_index.scss => index.scss} | 0 components/Info/index.ts | 2 + ...{Link.animations.js => Link.animations.ts} | 9 +- components/Link/{Link.jsx => Link.tsx} | 40 +- components/Link/Link.types.ts | 11 + components/Link/index.js | 1 - components/Link/{_index.scss => index.scss} | 0 components/Link/index.ts | 3 + ...l.animations.js => LinkRoll.animations.ts} | 17 +- .../LinkRoll/{LinkRoll.jsx => LinkRoll.tsx} | 42 +- components/LinkRoll/LinkRoll.types.ts | 11 + components/LinkRoll/index.js | 1 - .../LinkRoll/{_index.scss => index.scss} | 0 components/LinkRoll/index.ts | 3 + .../LocomotiveScroll/LocomotiveScroll.tsx | 48 +- .../LocomotiveScroll.types.ts | 57 + components/LocomotiveScroll/index.ts | 4 + .../LocomotiveScroll/useLocomotiveScroll.tsx | 10 + .../LocomotiveScroll/useScrollTo.ts | 20 +- .../{NextProject.jsx => NextProject.tsx} | 38 +- components/NextProject/NextProject.types.ts | 3 + components/NextProject/index.js | 1 - .../NextProject/{_index.scss => index.scss} | 0 components/NextProject/index.ts | 2 + ...ash.animations.js => Splash.animations.ts} | 5 +- components/Splash/{Splash.jsx => Splash.tsx} | 6 +- components/Splash/Splash.types.ts | 6 + components/Splash/index.js | 1 - components/Splash/{_index.scss => index.scss} | 0 components/Splash/index.ts | 3 + ...tamp.animations.js => Stamp.animations.ts} | 14 +- components/Stamp/{Stamp.jsx => Stamp.tsx} | 39 +- components/Stamp/Stamp.types.ts | 12 + components/Stamp/index.js | 1 - components/Stamp/{_index.scss => index.scss} | 0 components/Stamp/index.ts | 3 + .../SubInfo/{SubInfo.jsx => SubInfo.tsx} | 25 +- components/SubInfo/SubInfo.types.ts | 13 + components/SubInfo/index.js | 1 - .../SubInfo/{_index.scss => index.scss} | 0 components/SubInfo/index.ts | 2 + ...e.animations.js => Template.animations.ts} | 22 +- .../Template/{Template.jsx => Template.tsx} | 23 +- components/Template/Template.types.ts | 22 + components/Template/TemplateMain.jsx | 3 - components/Template/TemplateMain.tsx | 5 + ...emplateSection.jsx => TemplateSection.tsx} | 4 +- .../Template/{_index.scss => index.scss} | 0 components/Template/{index.js => index.ts} | 2 + components/Text/{Text.jsx => Text.tsx} | 19 +- components/Text/Text.types.ts | 10 + components/Text/index.js | 1 - components/Text/{_index.scss => index.scss} | 0 components/Text/index.ts | 2 + ...animations.js => TextReveal.animations.ts} | 7 +- .../{TextReveal.jsx => TextReveal.tsx} | 17 +- components/TextReveal/TextReveal.types.ts | 6 + components/TextReveal/index.js | 1 - .../TextReveal/{_index.scss => index.scss} | 0 components/TextReveal/index.ts | 3 + features/404/{Page.jsx => Page.tsx} | 3 +- features/404/{index.js => index.ts} | 0 features/About/{Page.jsx => Page.tsx} | 53 +- features/About/{index.js => index.ts} | 0 features/Home/{Page.jsx => Page.tsx} | 54 +- features/Home/{index.js => index.ts} | 0 .../Project/Archive/{Hero.jsx => Hero.tsx} | 20 +- .../Project/Archive/{Page.jsx => Page.tsx} | 23 +- ...{Hero.animations.js => Hero.animations.ts} | 7 +- .../Project/Biocode/{Hero.jsx => Hero.tsx} | 26 +- .../Project/Biocode/{Page.jsx => Page.tsx} | 64 +- features/Project/Biocode/_Hero.scss | 13 +- ...{Hero.animations.js => Hero.animations.ts} | 3 +- .../Mediasignal/{Hero.jsx => Hero.tsx} | 29 +- .../Mediasignal/{Page.jsx => Page.tsx} | 37 +- .../Project/MoreWork/{Hero.jsx => Hero.tsx} | 25 +- .../Project/MoreWork/{Page.jsx => Page.tsx} | 47 +- ...{Hero.animations.js => Hero.animations.ts} | 7 +- features/Project/Oras/{Hero.jsx => Hero.tsx} | 37 +- features/Project/Oras/{Page.jsx => Page.tsx} | 48 +- ...{Hero.animations.js => Hero.animations.ts} | 3 +- .../Project/Sandbox/{Hero.jsx => Hero.tsx} | 27 +- .../Project/Sandbox/{Page.jsx => Page.tsx} | 37 +- features/Project/{index.js => index.ts} | 6 - jsconfig.json | 8 - lib/{config.js => config.ts} | 66 +- lib/{detect.js => detect.ts} | 17 +- lib/getImages.js | 18 - lib/getImages.ts | 26 + lib/react-locomotive-scroll/index.js | 5 - .../useLocomotiveScroll.hook.jsx | 10 - lib/useInView.js | 46 - lib/useInView.ts | 44 + lib/{useUrlState.js => useUrlState.ts} | 8 +- lib/utility.js | 83 - lib/utils.ts | 72 + next.config.js => next.config.mjs | 18 +- package-lock.json | 11317 ++++++++-------- package.json | 33 +- pages/{404.jsx => 404.tsx} | 0 pages/{_app.jsx => _app.tsx} | 3 +- pages/{_document.jsx => _document.tsx} | 2 +- pages/{about.jsx => about.tsx} | 2 +- pages/{archive.jsx => archive.tsx} | 5 +- pages/{biocode.jsx => biocode.tsx} | 5 +- pages/{index.jsx => index.tsx} | 2 +- pages/{mediasignal.jsx => mediasignal.tsx} | 7 +- pages/{more-work.jsx => more-work.tsx} | 7 +- pages/{oras.jsx => oras.tsx} | 7 +- pages/{sandbox.jsx => sandbox.tsx} | 7 +- postcss.config.js => postcss.config.cjs | 0 prettier.config.js => prettier.config.cjs | 2 +- .../create-component.cjs | 22 +- .../templates/Component.cjs | 3 +- .../templates/_Component.scss.cjs | 0 .../index.js => scripts/templates/index.cjs | 2 +- .../templates/index.scss.cjs | 2 +- scripts/templates/templates.cjs | 6 + stylesheets/_tokens.scss | 2 +- .../helpers/{_helper.scss => _various.scss} | 0 stylesheets/index.scss | 14 +- stylesheets/vendors/_nprogress.scss | 2 +- tsconfig.json | 21 + types/common.ts | 62 + types/event.ts | 9 + types/index.ts | 3 + types/tag.ts | 4 + utils/templates/templates.js | 7 - 195 files changed, 7673 insertions(+), 6652 deletions(-) create mode 100644 .eslintrc.json rename components/App/{App.jsx => App.tsx} (76%) create mode 100644 components/App/App.types.ts rename components/App/{AppHead.jsx => AppHead.tsx} (65%) rename components/App/{_index.scss => index.scss} (100%) rename components/App/{index.js => index.ts} (63%) create mode 100644 components/Button/Button.types.ts rename components/Button/{ButtonArrow.jsx => ButtonArrow.tsx} (92%) rename components/Button/{ButtonEnter.animations.js => ButtonEnter.animations.ts} (62%) rename components/Button/{ButtonEnter.jsx => ButtonEnter.tsx} (90%) delete mode 100644 components/Button/index.js rename components/Button/{_index.scss => index.scss} (100%) create mode 100644 components/Button/index.ts delete mode 100644 components/ConditionalWrapper/ConditionalWrapper.jsx create mode 100644 components/ConditionalWrapper/ConditionalWrapper.tsx create mode 100644 components/ConditionalWrapper/ConditionalWrapper.types.ts delete mode 100644 components/ConditionalWrapper/index.js create mode 100644 components/ConditionalWrapper/index.ts rename components/Figure/{Figure.animations.js => Figure.animations.ts} (81%) rename components/Figure/{Figure.jsx => Figure.tsx} (86%) create mode 100644 components/Figure/Figure.types.ts delete mode 100644 components/Figure/index.js rename components/Figure/{_index.scss => index.scss} (100%) create mode 100644 components/Figure/index.ts rename components/Footer/{Footer.jsx => Footer.tsx} (90%) rename components/Footer/{_index.scss => index.scss} (100%) rename components/Footer/{index.js => index.ts} (100%) rename components/Head/{Head.jsx => Head.tsx} (71%) create mode 100644 components/Head/Head.types.ts delete mode 100644 components/Head/index.js create mode 100644 components/Head/index.ts rename components/Header/{Header.animations.js => Header.animations.ts} (60%) rename components/Header/{Header.jsx => Header.tsx} (85%) create mode 100644 components/Header/Header.types.ts rename components/Header/{HeaderNavItem.jsx => HeaderNavItem.tsx} (74%) delete mode 100644 components/Header/index.js rename components/Header/{_index.scss => index.scss} (100%) create mode 100644 components/Header/index.ts rename components/Heading/{Heading.jsx => Heading.tsx} (73%) create mode 100644 components/Heading/Heading.types.ts delete mode 100644 components/Heading/index.js rename components/Heading/{_index.scss => index.scss} (100%) create mode 100644 components/Heading/index.ts rename components/Hero/{Hero.animations.js => Hero.animations.ts} (76%) rename components/Hero/{Hero.jsx => Hero.tsx} (82%) create mode 100644 components/Hero/Hero.types.ts rename components/Hero/{HeroContent.jsx => HeroContent.tsx} (82%) rename components/Hero/{_index.scss => index.scss} (100%) rename components/Hero/{index.js => index.ts} (75%) rename components/Hr/{Hr.animations.js => Hr.animations.ts} (63%) rename components/Hr/{Hr.jsx => Hr.tsx} (76%) create mode 100644 components/Hr/Hr.types.ts delete mode 100644 components/Hr/index.js rename components/Hr/{_index.scss => index.scss} (100%) create mode 100644 components/Hr/index.ts delete mode 100644 components/Icon/Icon.jsx create mode 100644 components/Icon/Icon.tsx create mode 100644 components/Icon/Icon.types.ts delete mode 100644 components/Icon/index.js rename components/Icon/{_index.scss => index.scss} (100%) create mode 100644 components/Icon/index.ts rename components/Info/{Info.jsx => Info.tsx} (85%) create mode 100644 components/Info/Info.types.ts delete mode 100644 components/Info/index.js rename components/Info/{_index.scss => index.scss} (100%) create mode 100644 components/Info/index.ts rename components/Link/{Link.animations.js => Link.animations.ts} (77%) rename components/Link/{Link.jsx => Link.tsx} (79%) create mode 100644 components/Link/Link.types.ts delete mode 100644 components/Link/index.js rename components/Link/{_index.scss => index.scss} (100%) create mode 100644 components/Link/index.ts rename components/LinkRoll/{LinkRoll.animations.js => LinkRoll.animations.ts} (76%) rename components/LinkRoll/{LinkRoll.jsx => LinkRoll.tsx} (84%) create mode 100644 components/LinkRoll/LinkRoll.types.ts delete mode 100644 components/LinkRoll/index.js rename components/LinkRoll/{_index.scss => index.scss} (100%) create mode 100644 components/LinkRoll/index.ts rename lib/react-locomotive-scroll/LocomotiveScroll.context.jsx => components/LocomotiveScroll/LocomotiveScroll.tsx (64%) create mode 100644 components/LocomotiveScroll/LocomotiveScroll.types.ts create mode 100644 components/LocomotiveScroll/index.ts create mode 100644 components/LocomotiveScroll/useLocomotiveScroll.tsx rename lib/useScrollTo.js => components/LocomotiveScroll/useScrollTo.ts (57%) rename components/NextProject/{NextProject.jsx => NextProject.tsx} (74%) create mode 100644 components/NextProject/NextProject.types.ts delete mode 100644 components/NextProject/index.js rename components/NextProject/{_index.scss => index.scss} (100%) create mode 100644 components/NextProject/index.ts rename components/Splash/{Splash.animations.js => Splash.animations.ts} (75%) rename components/Splash/{Splash.jsx => Splash.tsx} (87%) create mode 100644 components/Splash/Splash.types.ts delete mode 100644 components/Splash/index.js rename components/Splash/{_index.scss => index.scss} (100%) create mode 100644 components/Splash/index.ts rename components/Stamp/{Stamp.animations.js => Stamp.animations.ts} (57%) rename components/Stamp/{Stamp.jsx => Stamp.tsx} (78%) create mode 100644 components/Stamp/Stamp.types.ts delete mode 100644 components/Stamp/index.js rename components/Stamp/{_index.scss => index.scss} (100%) create mode 100644 components/Stamp/index.ts rename components/SubInfo/{SubInfo.jsx => SubInfo.tsx} (86%) create mode 100644 components/SubInfo/SubInfo.types.ts delete mode 100644 components/SubInfo/index.js rename components/SubInfo/{_index.scss => index.scss} (100%) create mode 100644 components/SubInfo/index.ts rename components/Template/{Template.animations.js => Template.animations.ts} (51%) rename components/Template/{Template.jsx => Template.tsx} (86%) create mode 100644 components/Template/Template.types.ts delete mode 100644 components/Template/TemplateMain.jsx create mode 100644 components/Template/TemplateMain.tsx rename components/Template/{TemplateSection.jsx => TemplateSection.tsx} (88%) rename components/Template/{_index.scss => index.scss} (100%) rename components/Template/{index.js => index.ts} (56%) rename components/Text/{Text.jsx => Text.tsx} (81%) create mode 100644 components/Text/Text.types.ts delete mode 100644 components/Text/index.js rename components/Text/{_index.scss => index.scss} (100%) create mode 100644 components/Text/index.ts rename components/TextReveal/{TextReveal.animations.js => TextReveal.animations.ts} (74%) rename components/TextReveal/{TextReveal.jsx => TextReveal.tsx} (74%) create mode 100644 components/TextReveal/TextReveal.types.ts delete mode 100644 components/TextReveal/index.js rename components/TextReveal/{_index.scss => index.scss} (100%) create mode 100644 components/TextReveal/index.ts rename features/404/{Page.jsx => Page.tsx} (81%) rename features/404/{index.js => index.ts} (100%) rename features/About/{Page.jsx => Page.tsx} (95%) rename features/About/{index.js => index.ts} (100%) rename features/Home/{Page.jsx => Page.tsx} (79%) rename features/Home/{index.js => index.ts} (100%) rename features/Project/Archive/{Hero.jsx => Hero.tsx} (83%) rename features/Project/Archive/{Page.jsx => Page.tsx} (94%) rename features/Project/Biocode/{Hero.animations.js => Hero.animations.ts} (75%) rename features/Project/Biocode/{Hero.jsx => Hero.tsx} (94%) rename features/Project/Biocode/{Page.jsx => Page.tsx} (93%) rename features/Project/Mediasignal/{Hero.animations.js => Hero.animations.ts} (71%) rename features/Project/Mediasignal/{Hero.jsx => Hero.tsx} (84%) rename features/Project/Mediasignal/{Page.jsx => Page.tsx} (91%) rename features/Project/MoreWork/{Hero.jsx => Hero.tsx} (88%) rename features/Project/MoreWork/{Page.jsx => Page.tsx} (95%) rename features/Project/Oras/{Hero.animations.js => Hero.animations.ts} (78%) rename features/Project/Oras/{Hero.jsx => Hero.tsx} (93%) rename features/Project/Oras/{Page.jsx => Page.tsx} (94%) rename features/Project/Sandbox/{Hero.animations.js => Hero.animations.ts} (71%) rename features/Project/Sandbox/{Hero.jsx => Hero.tsx} (86%) rename features/Project/Sandbox/{Page.jsx => Page.tsx} (91%) rename features/Project/{index.js => index.ts} (95%) delete mode 100644 jsconfig.json rename lib/{config.js => config.ts} (91%) rename lib/{detect.js => detect.ts} (76%) delete mode 100644 lib/getImages.js create mode 100644 lib/getImages.ts delete mode 100644 lib/react-locomotive-scroll/index.js delete mode 100644 lib/react-locomotive-scroll/useLocomotiveScroll.hook.jsx delete mode 100644 lib/useInView.js create mode 100644 lib/useInView.ts rename lib/{useUrlState.js => useUrlState.ts} (59%) delete mode 100644 lib/utility.js create mode 100644 lib/utils.ts rename next.config.js => next.config.mjs (73%) rename pages/{404.jsx => 404.tsx} (100%) rename pages/{_app.jsx => _app.tsx} (51%) rename pages/{_document.jsx => _document.tsx} (82%) rename pages/{about.jsx => about.tsx} (80%) rename pages/{archive.jsx => archive.tsx} (68%) rename pages/{biocode.jsx => biocode.tsx} (68%) rename pages/{index.jsx => index.tsx} (77%) rename pages/{mediasignal.jsx => mediasignal.tsx} (69%) rename pages/{more-work.jsx => more-work.tsx} (68%) rename pages/{oras.jsx => oras.tsx} (67%) rename pages/{sandbox.jsx => sandbox.tsx} (68%) rename postcss.config.js => postcss.config.cjs (100%) rename prettier.config.js => prettier.config.cjs (100%) rename utils/create-component.js => scripts/create-component.cjs (64%) rename utils/templates/Component.js => scripts/templates/Component.cjs (91%) rename utils/templates/_Component.scss.js => scripts/templates/_Component.scss.cjs (100%) rename utils/templates/index.js => scripts/templates/index.cjs (84%) rename utils/templates/_index.scss.js => scripts/templates/index.scss.cjs (85%) create mode 100644 scripts/templates/templates.cjs rename stylesheets/helpers/{_helper.scss => _various.scss} (100%) create mode 100644 tsconfig.json create mode 100644 types/common.ts create mode 100644 types/event.ts create mode 100644 types/index.ts create mode 100644 types/tag.ts delete mode 100644 utils/templates/templates.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..29aebb5d --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://json.schemastore.org/eslintrc", + "extends": [ + "next/core-web-vitals", + "plugin:import/recommended", + "plugin:prettier/recommended", + "plugin:@typescript-eslint/recommended", + "plugin:typescript-sort-keys/recommended" + ], + "plugins": [ + "sort-imports-es6-autofix", + "sort-keys-fix", + "sort-destructure-keys" + ], + "rules": { + "@typescript-eslint/consistent-type-imports": [ + "error", + { + "prefer": "type-imports", + "fixStyle": "inline-type-imports" + } + ], + "@typescript-eslint/consistent-type-exports": "error", + "@typescript-eslint/prefer-nullish-coalescing": "error", + "@typescript-eslint/no-explicit-any": "off", + "import/newline-after-import": "error", + "sort-imports-es6-autofix/sort-imports-es6": [ + 2, + { + "ignoreCase": true + } + ], + "sort-keys-fix/sort-keys-fix": "error", + "sort-destructure-keys/sort-destructure-keys": [ + 2, + { "caseSensitive": false } + ], + "react/no-unescaped-entities": "off", + "react/jsx-sort-props": "error" + }, + "overrides": [ + { + "files": ["*.ts", "*.tsx"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "project": ["tsconfig.json"], + "sourceType": "module" + } + } + ] +} diff --git a/.gitignore b/.gitignore index 34fe57ae..26ec4df5 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,10 @@ yarn-error.log* .env.test.local .env.production.local +# TypeScript +*.tsbuildinfo +next-env.d.ts + # Misc .DS_Store *.pem diff --git a/components/App/App.jsx b/components/App/App.tsx similarity index 76% rename from components/App/App.jsx rename to components/App/App.tsx index b58fe154..32d6bca4 100644 --- a/components/App/App.jsx +++ b/components/App/App.tsx @@ -1,57 +1,62 @@ -import { createContext, useContext, useEffect, useState, useRef } from 'react'; -import { AnimatePresence } from 'framer-motion'; -import { isBrowser } from '@/lib/utility'; -import { Splash } from '@/components/Splash'; +import { AnimatePresence, domAnimation, LazyMotion } from 'framer-motion'; +import { + type AppContextProps, + AppHead, + type AppProps, + type AppStateProps, +} from './'; +import { createContext, useContext, useEffect, useRef, useState } from 'react'; +import { EASE_CSS, SLOW_NETWORK_DELAY } from '@/lib/config'; import { Header } from '@/components/Header'; -import { LocomotiveScrollProvider } from '@/lib/react-locomotive-scroll'; +import { isBrowser } from '@/lib/utils'; +import { LocomotiveScrollProvider } from '@/components/LocomotiveScroll'; +import { Splash } from '@/components/Splash'; import { useRouter } from 'next/router'; -import { LazyMotion, domAnimation } from 'framer-motion'; -import Script from 'next/script'; -import { AppHead } from './'; -import { EASE_CSS, SLOW_NETWORK_DELAY } from '@/lib/config'; import NProgress from 'nprogress'; +import Script from 'next/script'; const DISABLE_LOADING = process.env.NEXT_PUBLIC_DISABLE_LOADING; const GOOGLE_ANALYTICS = process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS; const PRODUCTION = process.env.NODE_ENV === 'production'; - -const AppContext = createContext({ - detect: {}, - html: isBrowser && document.documentElement, - loading: DISABLE_LOADING ? false : true, - loadingEnd: DISABLE_LOADING ? true : false, - transition: false, // 'template', false, true - transitionInitial: false, -}); let scrollOnUpdateOnce = false; -export const App = ({ Component, pageProps }) => { - const appContext = useAppContext(); - const [appState, setAppState] = useState(appContext); +const AppContext = createContext(undefined); + +export const App = ({ Component, pageProps }: AppProps) => { + const [appState, setAppState] = useState({ + detect: {}, + html: (isBrowser && document.documentElement) as AppStateProps['html'], + loading: DISABLE_LOADING ? false : true, + loadingEnd: DISABLE_LOADING ? true : false, + transition: false, + transitionInitial: false, + }); const { html, loading, loadingEnd, transition } = appState; - const { asPath, beforePopState, push, events } = useRouter(); - const [animationComplete, setAnimationComplete] = useState(); + const { asPath, beforePopState, events, push } = useRouter(); + const [animationComplete, setAnimationComplete] = useState< + string | undefined + >(); const containerRef = useRef(null); /* ====== * App set state functions * ====== */ - const setTransition = value => { + const setTransition = (value: AppStateProps['transition']) => { setAppState(prevState => ({ ...prevState, transition: value, })); }; - const setTransitionInitial = value => { + const setTransitionInitial = (value: AppStateProps['transitionInitial']) => { setAppState(prevState => ({ ...prevState, transitionInitial: value, })); }; - const setLoadingEnd = value => { + const setLoadingEnd = (value: AppStateProps['loadingEnd']) => { setAppState(prevState => ({ ...prevState, loadingEnd: value, @@ -64,11 +69,13 @@ export const App = ({ Component, pageProps }) => { useEffect(() => { if (process.env.NODE_ENV === 'production') { - console.info('Made by me with Next.js, Framer Motion and tears. 🥲'); + console.info( + 'Made by me with Next.js, TypeScript, Framer Motion and tears. 🥲', + ); } (async () => { - const { isIphoneSafari, isWindows, hasTouch, hasThemeColor } = + const { hasThemeColor, hasTouch, isIphoneSafari, isWindows } = await import('@/lib/detect'); if (isWindows) html.classList.add('is-windows'); if (hasThemeColor) html.classList.add('has-themeColor'); @@ -91,7 +98,7 @@ export const App = ({ Component, pageProps }) => { })); return () => window.removeEventListener('resize', rootHeight); - }, []); + }, [html]); /* ====== * Various @@ -99,7 +106,7 @@ export const App = ({ Component, pageProps }) => { useEffect(() => { if (loadingEnd) html.classList.remove('is-loading'); - }, [loadingEnd]); + }, [loadingEnd, html]); useEffect(() => { if (transition) { @@ -114,13 +121,13 @@ export const App = ({ Component, pageProps }) => { setTimeout(() => html.classList.remove('is-transition:withDelay'), 300); setTimeout(() => html.classList.remove(hackClass), 300); } - }, [transition]); + }, [transition, html]); /** * Add loader with nprogress for slow networks */ useEffect(() => { - let timeout; + let timeout: ReturnType; NProgress.configure({ easing: EASE_CSS, @@ -146,14 +153,15 @@ export const App = ({ Component, pageProps }) => { events.off('routeChangeError', changeComplete); events.off('routeChangeComplete', changeComplete); }; - }, []); + }, [events]); /** * Set template transition by default when navigating back/forward */ - const [popStateTimeout, setPopStateTimeout] = useState(null); + const [popStateTimeout, setPopStateTimeout] = + useState>(); useEffect(() => { - beforePopState(({ url, as }) => { + beforePopState(({ as, url }) => { if (transition === 'template') { setPopStateTimeout( setTimeout(() => { @@ -168,7 +176,7 @@ export const App = ({ Component, pageProps }) => { } }); return () => popStateTimeout && clearTimeout(popStateTimeout); - }, [transition]); + }, [transition, beforePopState, push, popStateTimeout]); /** * Set initial transitions ready for animation (e.g. for Hero) @@ -181,8 +189,8 @@ export const App = ({ Component, pageProps }) => { * Send GA page views */ useEffect(() => { - if (PRODUCTION) { - const handleRouteChange = url => { + if (PRODUCTION && GOOGLE_ANALYTICS) { + const handleRouteChange = (url: string) => { window.gtag('config', GOOGLE_ANALYTICS, { page_path: url, }); @@ -225,6 +233,21 @@ export const App = ({ Component, pageProps }) => { > { + scroll.scroll.stop && scroll.start(); + scroll.scrollTo(0, { disableLerp: true, duration: 0 }); + if (transition) setTransition(false); + }} + onUpdate={scroll => { + if (!DISABLE_LOADING) { + if (!scrollOnUpdateOnce && !loadingEnd) scroll.stop(); + if (!scrollOnUpdateOnce && loadingEnd) { + scrollOnUpdateOnce = true; + scroll.start(); + } + } + }} options={{ class: '@', draggingClass: 'is-drag', @@ -238,26 +261,12 @@ export const App = ({ Component, pageProps }) => { smooth: true, smoothClass: 'is-smooth', tablet: { + breakpoint: 1024, smooth: true, }, touchMultiplier: 4, }} - location={animationComplete} watch={[loadingEnd]} - onLocationChange={scroll => { - scroll.scroll.stop && scroll.start(); - scroll.scrollTo(0, { duration: 0, disableLerp: true }); - if (transition) setTransition(false); - }} - onUpdate={scroll => { - if (!DISABLE_LOADING) { - if (!scrollOnUpdateOnce && !loadingEnd) scroll.stop(); - if (!scrollOnUpdateOnce && loadingEnd) { - scrollOnUpdateOnce = true; - scroll.start(); - } - } - }} >
@@ -279,4 +288,8 @@ export const App = ({ Component, pageProps }) => { ); }; -export const useAppContext = () => useContext(AppContext); +export const useAppContext = () => { + const context = useContext(AppContext); + if (context) return context; + throw new Error('useAppContext must be used within App'); +}; diff --git a/components/App/App.types.ts b/components/App/App.types.ts new file mode 100644 index 00000000..8735777b --- /dev/null +++ b/components/App/App.types.ts @@ -0,0 +1,21 @@ +import type { AppProps as NextAppProps } from 'next/app'; + +export interface AppProps extends Omit {} + +export interface AppStateProps { + detect: { + [key: string]: boolean; + }; + html: Document['documentElement']; + loading: boolean; + loadingEnd: boolean; + transition: boolean | 'template'; + transitionInitial: boolean; +} + +export interface AppContextProps { + appState: AppStateProps; + setLoadingEnd: (value: AppStateProps['loadingEnd']) => void; + setTransition: (value: AppStateProps['transition']) => void; + setTransitionInitial: (value: AppStateProps['transitionInitial']) => void; +} diff --git a/components/App/AppHead.jsx b/components/App/AppHead.tsx similarity index 65% rename from components/App/AppHead.jsx rename to components/App/AppHead.tsx index 4d0d8078..14f82fa6 100644 --- a/components/App/AppHead.jsx +++ b/components/App/AppHead.tsx @@ -1,5 +1,5 @@ -import Head from 'next/head'; import { useRouter } from 'next/router'; +import Head from 'next/head'; export const AppHead = () => { const ORIGIN = process.env.NEXT_PUBLIC_ORIGIN; @@ -12,84 +12,84 @@ export const AppHead = () => { {/* Common */} {title} - + {/* Open Graph */} - + - - - - - + + + + + {/* Twitter */} - + - - + + - + {/* Icons */} - - - + + + {/* Web app */} - - + + {/* Schema.org */}