mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-26 12:21:36 +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 React, {ComponentProps} from 'react';
|
||||||
import pages, {Page, PageName} from './pages';
|
import pages, {Page, PageName} from './pages';
|
||||||
import {AppContext, SignupFormOptions} from './AppContext';
|
import {AppContextProvider, SignupFormOptions} from './AppContext';
|
||||||
import {ContentBox} from './components/ContentBox';
|
import {ContentBox} from './components/ContentBox';
|
||||||
import {Frame} from './components/Frame';
|
import {Frame} from './components/Frame';
|
||||||
import {setupGhostApi} from './utils/api';
|
import {setupGhostApi} from './utils/api';
|
||||||
|
|
||||||
type Props = {
|
type AppProps = {
|
||||||
options: SignupFormOptions;
|
options: SignupFormOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
const App: React.FC<Props> = ({options}) => {
|
const App: React.FC<AppProps> = ({options}) => {
|
||||||
const [page, setPage] = React.useState<Page>({
|
const [page, setPage] = React.useState<Page>({
|
||||||
name: 'FormPage',
|
name: 'FormPage',
|
||||||
data: {}
|
data: {}
|
||||||
@ -38,13 +38,13 @@ const App: React.FC<Props> = ({options}) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AppContext.Provider value={context}>
|
<AppContextProvider value={context}>
|
||||||
<Frame>
|
<Frame>
|
||||||
<ContentBox>
|
<ContentBox>
|
||||||
<PageComponent {...data} />
|
<PageComponent {...data} />
|
||||||
</ContentBox>
|
</ContentBox>
|
||||||
</Frame>
|
</Frame>
|
||||||
</AppContext.Provider>
|
</AppContextProvider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Ref: https://reactjs.org/docs/context.html
|
// 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 pages, {Page, PageName} from './pages';
|
||||||
import {GhostApi} from './utils/api';
|
import {GhostApi} from './utils/api';
|
||||||
|
|
||||||
@ -19,4 +19,8 @@ export type AppContextType = {
|
|||||||
api: GhostApi,
|
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 React from 'react';
|
||||||
import {AppContext} from '../AppContext';
|
import {useAppContext} from '../AppContext';
|
||||||
|
|
||||||
type Props = {
|
type ContentBoxProps = {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ContentBox: React.FC<Props> = ({children}) => {
|
export const ContentBox: React.FC<ContentBoxProps> = ({children}) => {
|
||||||
const {color} = React.useContext(AppContext).options;
|
const {color} = useAppContext().options;
|
||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
'--gh-accent-color': color
|
'--gh-accent-color': color
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import React, {FormEventHandler} from 'react';
|
import React, {FormEventHandler} from 'react';
|
||||||
import {AppContext} from '../../AppContext';
|
|
||||||
import {isMinimal} from '../../utils/helpers';
|
import {isMinimal} from '../../utils/helpers';
|
||||||
import {isValidEmail} from '../../utils/validator';
|
import {isValidEmail} from '../../utils/validator';
|
||||||
|
import {useAppContext} from '../../AppContext';
|
||||||
|
|
||||||
type Props = {};
|
export const FormPage: React.FC = () => {
|
||||||
|
const {options} = useAppContext();
|
||||||
export const FormPage: React.FC<Props> = () => {
|
|
||||||
const {options} = React.useContext(AppContext);
|
|
||||||
|
|
||||||
if (isMinimal(options)) {
|
if (isMinimal(options)) {
|
||||||
return (
|
return (
|
||||||
@ -27,11 +25,11 @@ export const FormPage: React.FC<Props> = () => {
|
|||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Form: React.FC<Props> = () => {
|
const Form: React.FC = () => {
|
||||||
const [email, setEmail] = React.useState('');
|
const [email, setEmail] = React.useState('');
|
||||||
const [error, setError] = React.useState('');
|
const [error, setError] = React.useState('');
|
||||||
const [loading, setLoading] = React.useState(false);
|
const [loading, setLoading] = React.useState(false);
|
||||||
const {api, setPage, options} = React.useContext(AppContext);
|
const {api, setPage, options} = useAppContext();
|
||||||
const labels = options.labels;
|
const labels = options.labels;
|
||||||
|
|
||||||
const submit: FormEventHandler<HTMLFormElement> = async (e) => {
|
const submit: FormEventHandler<HTMLFormElement> = async (e) => {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {AppContext} from '../../AppContext';
|
|
||||||
import {isMinimal} from '../../utils/helpers';
|
import {isMinimal} from '../../utils/helpers';
|
||||||
|
import {useAppContext} from '../../AppContext';
|
||||||
|
|
||||||
type Props = {
|
type SuccessPageProps = {
|
||||||
email: string;
|
email: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SuccessPage: React.FC<Props> = ({email}) => {
|
export const SuccessPage: React.FC<SuccessPageProps> = ({email}) => {
|
||||||
const {options} = React.useContext(AppContext);
|
const {options} = useAppContext();
|
||||||
|
|
||||||
if (isMinimal(options)) {
|
if (isMinimal(options)) {
|
||||||
return <div>
|
return <div>
|
||||||
|
@ -2,23 +2,20 @@ import React from 'react';
|
|||||||
import {FormPage} from './components/pages/FormPage';
|
import {FormPage} from './components/pages/FormPage';
|
||||||
import {SuccessPage} from './components/pages/SuccessPage';
|
import {SuccessPage} from './components/pages/SuccessPage';
|
||||||
|
|
||||||
// When adding a new page, also add it at the bottom to the Page type (*)
|
|
||||||
const Pages = {
|
const Pages = {
|
||||||
FormPage,
|
FormPage,
|
||||||
SuccessPage
|
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 PageName = keyof typeof Pages;
|
||||||
export type PageType<Name extends PageName> = {
|
|
||||||
name: Name;
|
type PageTypes = {
|
||||||
// get props of component
|
[name in PageName]: {
|
||||||
data: React.ComponentProps<typeof Pages[Name]>;
|
name: name,
|
||||||
|
data: React.ComponentProps<typeof Pages[name]>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Page = PageTypes[keyof PageTypes]
|
||||||
|
|
||||||
export default Pages;
|
export default Pages;
|
||||||
|
Loading…
Reference in New Issue
Block a user