diff --git a/ghost/signup-form/src/App.tsx b/ghost/signup-form/src/App.tsx index 36ccbc71cd..6e20e92833 100644 --- a/ghost/signup-form/src/App.tsx +++ b/ghost/signup-form/src/App.tsx @@ -1,15 +1,15 @@ import React, {ComponentProps} from 'react'; import pages, {Page, PageName} from './pages'; -import {AppContext, SignupFormOptions} from './AppContext'; +import {AppContextProvider, SignupFormOptions} from './AppContext'; import {ContentBox} from './components/ContentBox'; import {Frame} from './components/Frame'; import {setupGhostApi} from './utils/api'; -type Props = { +type AppProps = { options: SignupFormOptions; }; -const App: React.FC = ({options}) => { +const App: React.FC = ({options}) => { const [page, setPage] = React.useState({ name: 'FormPage', data: {} @@ -38,13 +38,13 @@ const App: React.FC = ({options}) => { return (
- + - +
); }; diff --git a/ghost/signup-form/src/AppContext.ts b/ghost/signup-form/src/AppContext.ts index 88ee8dd6b8..a81d1ab35d 100644 --- a/ghost/signup-form/src/AppContext.ts +++ b/ghost/signup-form/src/AppContext.ts @@ -1,5 +1,5 @@ // Ref: https://reactjs.org/docs/context.html -import React, {ComponentProps} from 'react'; +import React, {ComponentProps, useContext} from 'react'; import pages, {Page, PageName} from './pages'; import {GhostApi} from './utils/api'; @@ -19,4 +19,8 @@ export type AppContextType = { api: GhostApi, } -export const AppContext = React.createContext({} as any); +const AppContext = React.createContext({} as any); + +export const AppContextProvider = AppContext.Provider; + +export const useAppContext = () => useContext(AppContext); diff --git a/ghost/signup-form/src/components/ContentBox.tsx b/ghost/signup-form/src/components/ContentBox.tsx index e148f3ce5f..ecdcb7f6dd 100644 --- a/ghost/signup-form/src/components/ContentBox.tsx +++ b/ghost/signup-form/src/components/ContentBox.tsx @@ -1,12 +1,12 @@ import React from 'react'; -import {AppContext} from '../AppContext'; +import {useAppContext} from '../AppContext'; -type Props = { +type ContentBoxProps = { children: React.ReactNode }; -export const ContentBox: React.FC = ({children}) => { - const {color} = React.useContext(AppContext).options; +export const ContentBox: React.FC = ({children}) => { + const {color} = useAppContext().options; const style = { '--gh-accent-color': color diff --git a/ghost/signup-form/src/components/pages/FormPage.tsx b/ghost/signup-form/src/components/pages/FormPage.tsx index a98d55e743..6d98cb137d 100644 --- a/ghost/signup-form/src/components/pages/FormPage.tsx +++ b/ghost/signup-form/src/components/pages/FormPage.tsx @@ -1,12 +1,10 @@ import React, {FormEventHandler} from 'react'; -import {AppContext} from '../../AppContext'; import {isMinimal} from '../../utils/helpers'; import {isValidEmail} from '../../utils/validator'; +import {useAppContext} from '../../AppContext'; -type Props = {}; - -export const FormPage: React.FC = () => { - const {options} = React.useContext(AppContext); +export const FormPage: React.FC = () => { + const {options} = useAppContext(); if (isMinimal(options)) { return ( @@ -27,11 +25,11 @@ export const FormPage: React.FC = () => { ; }; -const Form: React.FC = () => { +const Form: React.FC = () => { const [email, setEmail] = React.useState(''); const [error, setError] = React.useState(''); const [loading, setLoading] = React.useState(false); - const {api, setPage, options} = React.useContext(AppContext); + const {api, setPage, options} = useAppContext(); const labels = options.labels; const submit: FormEventHandler = async (e) => { diff --git a/ghost/signup-form/src/components/pages/SuccessPage.tsx b/ghost/signup-form/src/components/pages/SuccessPage.tsx index 2baec7140d..38d76e7394 100644 --- a/ghost/signup-form/src/components/pages/SuccessPage.tsx +++ b/ghost/signup-form/src/components/pages/SuccessPage.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import {AppContext} from '../../AppContext'; import {isMinimal} from '../../utils/helpers'; +import {useAppContext} from '../../AppContext'; -type Props = { +type SuccessPageProps = { email: string; }; -export const SuccessPage: React.FC = ({email}) => { - const {options} = React.useContext(AppContext); +export const SuccessPage: React.FC = ({email}) => { + const {options} = useAppContext(); if (isMinimal(options)) { return
diff --git a/ghost/signup-form/src/pages.tsx b/ghost/signup-form/src/pages.tsx index 3b696d172a..f022daa0a0 100644 --- a/ghost/signup-form/src/pages.tsx +++ b/ghost/signup-form/src/pages.tsx @@ -2,23 +2,20 @@ import React from 'react'; import {FormPage} from './components/pages/FormPage'; import {SuccessPage} from './components/pages/SuccessPage'; -// When adding a new page, also add it at the bottom to the Page type (*) const Pages = { FormPage, SuccessPage }; -// (*) Note we have repeated names here, and don't use PageName -// to make type checking work for the Page type, so we have type checks in place -// that we pass the right data to the right page (otherwise it will only check if -// the name is correct, and the data is correct for any page, not the specific page) -export type Page = PageType<'FormPage'> | PageType<'SuccessPage'>; - export type PageName = keyof typeof Pages; -export type PageType = { - name: Name; - // get props of component - data: React.ComponentProps; + +type PageTypes = { + [name in PageName]: { + name: name, + data: React.ComponentProps + } } +export type Page = PageTypes[keyof PageTypes] + export default Pages;