mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 20:03:12 +03:00
Tweaked type definitions in signup form
This commit is contained in:
parent
af907b70cb
commit
03fb1b188c
@ -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<Props> = ({options}) => {
|
||||
const App: React.FC<AppProps> = ({options}) => {
|
||||
const [page, setPage] = React.useState<Page>({
|
||||
name: 'FormPage',
|
||||
data: {}
|
||||
@ -38,13 +38,13 @@ const App: React.FC<Props> = ({options}) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<AppContext.Provider value={context}>
|
||||
<AppContextProvider value={context}>
|
||||
<Frame>
|
||||
<ContentBox>
|
||||
<PageComponent {...data} />
|
||||
</ContentBox>
|
||||
</Frame>
|
||||
</AppContext.Provider>
|
||||
</AppContextProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -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<AppContextType>({} as any);
|
||||
const AppContext = React.createContext<AppContextType>({} as any);
|
||||
|
||||
export const AppContextProvider = AppContext.Provider;
|
||||
|
||||
export const useAppContext = () => useContext(AppContext);
|
||||
|
@ -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<Props> = ({children}) => {
|
||||
const {color} = React.useContext(AppContext).options;
|
||||
export const ContentBox: React.FC<ContentBoxProps> = ({children}) => {
|
||||
const {color} = useAppContext().options;
|
||||
|
||||
const style = {
|
||||
'--gh-accent-color': color
|
||||
|
@ -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<Props> = () => {
|
||||
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<Props> = () => {
|
||||
</div>;
|
||||
};
|
||||
|
||||
const Form: React.FC<Props> = () => {
|
||||
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<HTMLFormElement> = async (e) => {
|
||||
|
@ -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<Props> = ({email}) => {
|
||||
const {options} = React.useContext(AppContext);
|
||||
export const SuccessPage: React.FC<SuccessPageProps> = ({email}) => {
|
||||
const {options} = useAppContext();
|
||||
|
||||
if (isMinimal(options)) {
|
||||
return <div>
|
||||
|
@ -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 extends PageName> = {
|
||||
name: Name;
|
||||
// get props of component
|
||||
data: React.ComponentProps<typeof Pages[Name]>;
|
||||
|
||||
type PageTypes = {
|
||||
[name in PageName]: {
|
||||
name: name,
|
||||
data: React.ComponentProps<typeof Pages[name]>
|
||||
}
|
||||
}
|
||||
|
||||
export type Page = PageTypes[keyof PageTypes]
|
||||
|
||||
export default Pages;
|
||||
|
Loading…
Reference in New Issue
Block a user