From 1d883676455a5aecf548f4b69f116ea6f5297074 Mon Sep 17 00:00:00 2001 From: Phi Date: Tue, 17 Sep 2019 16:18:45 -0400 Subject: [PATCH] refact: convert components to use React.FC type + type improvements --- custom.d.ts | 4 ++++ package.json | 1 + src/SidebarProvider.tsx | 8 ++----- src/ThemeProvider.tsx | 13 +++++------ src/components/Container/index.tsx | 6 ++--- src/components/DiscordButton/index.tsx | 4 ++-- src/components/Footer/index.tsx | 4 ++-- src/components/Header/index.tsx | 10 ++++++--- src/components/Layout/index.tsx | 9 ++++---- src/components/Markdown/index.tsx | 8 +++---- src/components/MobileHeader/index.tsx | 4 ++-- src/components/ResourceBreadcrumb/index.tsx | 8 +++++-- src/components/ResourceHeader/index.tsx | 22 +++++++++---------- src/components/ResourcesLayout/index.tsx | 4 ++-- src/components/ResourcesLink/index.tsx | 12 +++++----- src/components/ResourcesList/index.tsx | 4 ++-- src/components/ResourcesSidebar/index.tsx | 10 ++++++--- .../ResourcesSidebarSection/index.tsx | 6 ++--- src/components/SEO/index.tsx | 6 ++--- src/components/StackedAvatars/index.tsx | 6 ++--- src/components/ThemeToggler/index.tsx | 4 ++-- src/components/Waves/index.tsx | 6 ++--- src/templates/languagePost.tsx | 4 ++-- 23 files changed, 89 insertions(+), 74 deletions(-) create mode 100644 custom.d.ts diff --git a/custom.d.ts b/custom.d.ts new file mode 100644 index 0000000..1a3dd3c --- /dev/null +++ b/custom.d.ts @@ -0,0 +1,4 @@ +declare module "*.svg" { + const content: any; + export default content; +} diff --git a/package.json b/package.json index 376ce8f..f1c1b92 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\"" }, "dependencies": { + "@reach/router": "^1.2.1", "gatsby": "^2.13.51", "gatsby-image": "^2.2.8", "gatsby-plugin-layout": "^1.1.2", diff --git a/src/SidebarProvider.tsx b/src/SidebarProvider.tsx index b70b137..02bb1e4 100644 --- a/src/SidebarProvider.tsx +++ b/src/SidebarProvider.tsx @@ -1,8 +1,4 @@ -import React, { useMemo, useState } from "react" - -interface ISidebarProviderProps { - children: React.ReactNode -} +import React, { FC, useMemo, useState } from "react" export interface ISidebarContextInterface { current: number @@ -13,7 +9,7 @@ export const SidebarContext = React.createContext { const [current, setCurrent] = useState(0) const memoizedContextValue = useMemo( diff --git a/src/ThemeProvider.tsx b/src/ThemeProvider.tsx index 0d6ca85..4836f9e 100644 --- a/src/ThemeProvider.tsx +++ b/src/ThemeProvider.tsx @@ -1,23 +1,22 @@ -import React, { createContext, useMemo } from "react" +import React, { createContext, FC, useMemo } from "react" import { ThemeProvider as BaseThemeProvider } from "styled-components" import { darkTheme, lightTheme } from "./design/themes" import { useLocalStorage } from "./hooks/useLocalStorage" -interface IThemeProviderProps { - // TODO: type this properly, BaseThemeProvider doesn't like React.ReactNode - children: any -} - export interface IThemeContext { theme: "dark" | "light" setTheme: () => void toggleTheme: () => void } +interface IScopedDownChildren { + children: JSX.Element +} + export const ThemeContext = createContext(null) -const ThemeProvider = ({ children }: IThemeProviderProps) => { +const ThemeProvider: FC = ({ children }) => { const [theme, setTheme] = useLocalStorage("theme", "light") const themeObject = useMemo( diff --git a/src/components/Container/index.tsx b/src/components/Container/index.tsx index 4849eb8..3cf77d6 100644 --- a/src/components/Container/index.tsx +++ b/src/components/Container/index.tsx @@ -1,9 +1,9 @@ -import React, { PropsWithChildren } from "react" +import React, { FC } from "react" import * as SC from "./styles" -export function Container({ +export const Container: FC = ({ children, ...restProps -}: PropsWithChildren<{}>): JSX.Element { +}) => { return {children} } diff --git a/src/components/DiscordButton/index.tsx b/src/components/DiscordButton/index.tsx index 0eed1a2..67bc74e 100644 --- a/src/components/DiscordButton/index.tsx +++ b/src/components/DiscordButton/index.tsx @@ -1,7 +1,7 @@ -import React, { PropsWithChildren } from "react" +import React, { FC } from "react" import * as SC from "./styles" -export function DiscordButton({ children }: PropsWithChildren<{}>) { +export const DiscordButton: FC = ({ children }) => { return ( {children} diff --git a/src/components/Footer/index.tsx b/src/components/Footer/index.tsx index 05b6aaa..1af8347 100644 --- a/src/components/Footer/index.tsx +++ b/src/components/Footer/index.tsx @@ -1,8 +1,8 @@ -import React from "react" +import React, { FC } from "react" import { Container } from "../Container" import * as SC from "./styles" -export function Footer() { +export const Footer: FC = () => { return ( diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 46ec8b1..62d9d8a 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -1,5 +1,5 @@ import { Link } from "gatsby" -import React, { PropsWithChildren, useLayoutEffect, useState } from "react" +import React, { FC, useLayoutEffect, useState } from "react" import { DiscordButton } from "../DiscordButton" import { WavesBottom, WavesTop } from "../Waves" import * as SC from "./styles" @@ -8,7 +8,11 @@ interface IHeaderProps { isHome: boolean } -function MenuItem({ children, to }: PropsWithChildren<{ to: string }>) { +interface IMenuItemProps { + to: string +} + +const MenuItem: FC = ({ children, to }) => { return ( ) { ) } -export function Header({ isHome }: IHeaderProps) { +export const Header: FC = ({ isHome }) => { // Hack to force Particle.js to rerender const [noop, setNoop] = useState(0) useLayoutEffect(() => { diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index c8bc6ea..4a56a70 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -5,7 +5,8 @@ * See: https://www.gatsbyjs.org/docs/use-static-query/ */ -import React, { Fragment, PropsWithChildren } from "react" +import { RouteComponentProps } from '@reach/router' +import React, { FC, Fragment } from "react" import { GlobalStyles } from "../../globalStyles" import { ThemeProvider } from "../../ThemeProvider" @@ -15,11 +16,11 @@ import { Header } from "../Header" import { WavesBottom } from "../Waves" import * as SC from "./styles" -export function Layout({ +export const Layout: FC = ({ children, location, -}: PropsWithChildren<{ location: Location }>) { - const isHome = location.pathname === "/" +}) => { + const isHome = location ? location.pathname === "/" : false return ( diff --git a/src/components/Markdown/index.tsx b/src/components/Markdown/index.tsx index a6a2aa7..e6d7caf 100644 --- a/src/components/Markdown/index.tsx +++ b/src/components/Markdown/index.tsx @@ -3,7 +3,7 @@ import "prismjs/components/prism-markup-templating" import "prismjs/components/prism-php" import "prismjs/components/prism-python" import "prismjs/plugins/line-numbers/prism-line-numbers.css" -import React from "react" +import React, { FC, useEffect } from "react" import * as SC from "./styles" interface IMarkdownProps { @@ -14,11 +14,11 @@ interface IMarkdownProps { This component is used as a wrapper around Markdown generated content, mainly to provide styles to the html generated. */ -export function Markdown({ +export const Markdown: FC = ({ content, ...restProps -}: IMarkdownProps): JSX.Element { - React.useEffect(() => { +}) => { + useEffect(() => { Prism.highlightAll() }, []) return ( diff --git a/src/components/MobileHeader/index.tsx b/src/components/MobileHeader/index.tsx index d316039..7f334fd 100644 --- a/src/components/MobileHeader/index.tsx +++ b/src/components/MobileHeader/index.tsx @@ -1,11 +1,11 @@ -import React from "react" +import React, { FC } from "react" import * as SC from "./styles" interface IMobileHeaderProps { openMenu: () => void } -export function MobileHeader({ openMenu }: IMobileHeaderProps) { +export const MobileHeader: FC = ({ openMenu }) => { return ( diff --git a/src/components/ResourceBreadcrumb/index.tsx b/src/components/ResourceBreadcrumb/index.tsx index d26ccdf..19baf87 100644 --- a/src/components/ResourceBreadcrumb/index.tsx +++ b/src/components/ResourceBreadcrumb/index.tsx @@ -1,15 +1,19 @@ -import React from "react" +import React, { FC } from "react" import ChevronUp from "../../icons/chevron-up.svg" import { IFileOrFolder } from "../../types" import { humanize, traversePaths } from "../../utils" import * as SC from "./styles" +interface ILinkProps { + item: IFileOrFolder +} + interface IResourceBreadcrumbProps { relativePath: any } -function Link({ item }: { item: IFileOrFolder }) { +const Link: FC = ({ item }) => { return {humanize(item.title)} } diff --git a/src/components/ResourceHeader/index.tsx b/src/components/ResourceHeader/index.tsx index 3fa8e83..4b41c18 100644 --- a/src/components/ResourceHeader/index.tsx +++ b/src/components/ResourceHeader/index.tsx @@ -1,4 +1,4 @@ -import React, { Fragment } from "react" +import React, { FC, Fragment } from "react" import ChevronUp from "../../icons/chevron-up.svg" import { ResourceBreadcrumb } from "../ResourceBreadcrumb" @@ -6,13 +6,13 @@ import { StackedAvatars } from "../StackedAvatars" import * as SC from "./styles" interface IResourceHeaderProps { - relativePath: any - title: any - authors: any - createdAt: any - timeToRead: any - recommendedReading: any - externalResources: any + relativePath: string + title: string + authors: string[] + createdAt: string + timeToRead: number + recommendedReading: string[] + externalResources: string[] } function ExtraLink({ @@ -43,7 +43,7 @@ function ExtraLink({ ) } -export function ResourceHeader({ +export const ResourceHeader: FC = ({ relativePath, title, authors, @@ -51,7 +51,7 @@ export function ResourceHeader({ timeToRead, recommendedReading, externalResources, -}: IResourceHeaderProps) { +}) => { const date = new Date(createdAt) const month = date.toLocaleString("default", { month: "long" }) const day = date.getDate() @@ -67,7 +67,7 @@ export function ResourceHeader({ {authors.length} contributor - {authors.lenght > 1 && "s"} + {authors.length > 1 && "s"} {dateToHuman} diff --git a/src/components/ResourcesLayout/index.tsx b/src/components/ResourcesLayout/index.tsx index a11acad..0ded442 100644 --- a/src/components/ResourcesLayout/index.tsx +++ b/src/components/ResourcesLayout/index.tsx @@ -5,7 +5,7 @@ * See: https://www.gatsbyjs.org/docs/use-static-query/ */ -import React, { PropsWithChildren, useState } from "react" +import React, { FC, useState } from "react" import { GlobalStyles } from "../../globalStyles" import { SidebarProvider } from "../../SidebarProvider" @@ -14,7 +14,7 @@ import { MobileHeader } from "../MobileHeader" import { ResourcesSidebar } from "../ResourcesSidebar" import * as SC from "./styles" -export function ResourcesLayout({ children }: PropsWithChildren<{}>) { +export const ResourcesLayout: FC = ({ children }) => { const [activeMobileMenu, setActiveMobileMenu] = useState(false) function openMenu() { diff --git a/src/components/ResourcesLink/index.tsx b/src/components/ResourcesLink/index.tsx index 60b4055..414b786 100644 --- a/src/components/ResourcesLink/index.tsx +++ b/src/components/ResourcesLink/index.tsx @@ -1,12 +1,14 @@ -import React, { PropsWithChildren } from "react" +import React, { FC } from "react" import * as SC from "./styles" -export function ResourcesLink({ +interface IResourcesLinkProps { + to: string +} + +export const ResourcesLink: FC = ({ children, to, -}: PropsWithChildren<{ - to: string -}>) { +}) => { if (!to.match(/^(https?:\/\/)/)) { return ( {children} diff --git a/src/components/ResourcesList/index.tsx b/src/components/ResourcesList/index.tsx index 486da14..680ed2a 100644 --- a/src/components/ResourcesList/index.tsx +++ b/src/components/ResourcesList/index.tsx @@ -1,5 +1,5 @@ import { graphql, useStaticQuery } from "gatsby" -import React, { memo } from "react" +import React, { FC, HTMLAttributes, memo } from "react" import "react-perfect-scrollbar/dist/css/styles.css" import { IAllResourcesQuery, IFileOrFolder, IFolder } from "../../types" import { humanize } from "../../utils" @@ -51,7 +51,7 @@ const Language = memo(({ item }: { item: IFolder; index: number }) => { ) }) -export function ResourcesList(props: React.HTMLAttributes) { +export const ResourcesList: FC> = (props) => { const resources = useStaticQuery(ALL_RESOURCES) const tree = useBuildTree(resources) diff --git a/src/components/ResourcesSidebar/index.tsx b/src/components/ResourcesSidebar/index.tsx index d371ddb..dceacee 100644 --- a/src/components/ResourcesSidebar/index.tsx +++ b/src/components/ResourcesSidebar/index.tsx @@ -1,5 +1,5 @@ import { graphql, Link, useStaticQuery } from "gatsby" -import React, { memo, PropsWithChildren, useState } from "react" +import React, { FC, HTMLAttributes, memo, useState } from "react" import Scrollbar from "react-perfect-scrollbar" import "react-perfect-scrollbar/dist/css/styles.css" import TriangleDown from "../../icons/triangle-down.svg" @@ -83,7 +83,11 @@ const FirstLevelFolder = memo( } ) -function MenuItem({ children, to }: PropsWithChildren<{ to: string }>) { +interface IMenuItemProps { + to: string +} + +const MenuItem: FC = ({ children, to }) => { return ( {children} @@ -91,7 +95,7 @@ function MenuItem({ children, to }: PropsWithChildren<{ to: string }>) { ) } -export function ResourcesSidebar(props: React.HTMLAttributes) { +export const ResourcesSidebar: FC> = (props) => { const resources = useStaticQuery(ALL_RESOURCES) const tree = useBuildTree(resources) diff --git a/src/components/ResourcesSidebarSection/index.tsx b/src/components/ResourcesSidebarSection/index.tsx index ef76ccc..177c8c8 100644 --- a/src/components/ResourcesSidebarSection/index.tsx +++ b/src/components/ResourcesSidebarSection/index.tsx @@ -1,14 +1,14 @@ -import React, { PropsWithChildren } from "react" +import React, { FC } from "react" import * as SC from "./styles" export interface IResourcesSidebarSectionProps { readonly title: string } -export function ResourcesSidebarSection({ +export const ResourcesSidebarSection: FC = ({ title, children, -}: PropsWithChildren) { +}) => { return (
{title} diff --git a/src/components/SEO/index.tsx b/src/components/SEO/index.tsx index a4c274d..693031e 100644 --- a/src/components/SEO/index.tsx +++ b/src/components/SEO/index.tsx @@ -1,5 +1,5 @@ import { graphql, useStaticQuery } from "gatsby" -import React from "react" +import React, { FC } from "react" import Helmet from "react-helmet" interface ISEOProps { @@ -10,13 +10,13 @@ interface ISEOProps { readonly title: string } -export function SEO({ +export const SEO: FC = ({ description, lang = "en", meta = [], keywords = [], title, -}: ISEOProps) { +}) => { const { site } = useStaticQuery( graphql` query { diff --git a/src/components/StackedAvatars/index.tsx b/src/components/StackedAvatars/index.tsx index 57e2f88..26bf022 100644 --- a/src/components/StackedAvatars/index.tsx +++ b/src/components/StackedAvatars/index.tsx @@ -1,12 +1,12 @@ -import React from "react" +import React, { FC } from "react" import * as SC from "./styles" interface IStackedAvatarsProps { - authors: any + authors: any[] } -export function StackedAvatars({ authors }: IStackedAvatarsProps) { +export const StackedAvatars: FC = ({ authors }) => { return ( {authors.map((author, index) => ( diff --git a/src/components/ThemeToggler/index.tsx b/src/components/ThemeToggler/index.tsx index c2b8422..84de93e 100644 --- a/src/components/ThemeToggler/index.tsx +++ b/src/components/ThemeToggler/index.tsx @@ -1,8 +1,8 @@ -import React from "react" +import React, { FC } from "react" import useTheme from "../../hooks/useTheme" import * as SC from "./styles" -export function ThemeToggler() { +export const ThemeToggler: FC = () => { const { theme, toggleTheme } = useTheme() return ( diff --git a/src/components/Waves/index.tsx b/src/components/Waves/index.tsx index 9fe1192..cb0b783 100644 --- a/src/components/Waves/index.tsx +++ b/src/components/Waves/index.tsx @@ -1,10 +1,10 @@ -import React from "react" +import React, { FC } from "react" import * as SC from "./styles" -export function WavesTop() { +export const WavesTop: FC = () => { return } -export function WavesBottom() { +export const WavesBottom: FC = () => { return } diff --git a/src/templates/languagePost.tsx b/src/templates/languagePost.tsx index dd642fe..e223ec9 100644 --- a/src/templates/languagePost.tsx +++ b/src/templates/languagePost.tsx @@ -1,11 +1,11 @@ import { graphql } from "gatsby" -import React, { Fragment } from "react" +import React, { FC, Fragment } from "react" import { Markdown } from "../components/Markdown" import { ResourceHeader } from "../components/ResourceHeader" import { SEO } from "../components/SEO" // @todo maybe find alternative type for data -function LanguagePost({ data }: any) { +const LanguagePost: FC = ({ data }) => { const { relativePath } = data.file const { html, fields, frontmatter, timeToRead } = data.file.post