diff options
author | 2021-05-03 12:15:13 -0500 | |
---|---|---|
committer | 2021-05-03 12:15:13 -0500 | |
commit | ed631329e731d31e384dacc1ec399ba60b7c906b (patch) | |
tree | 0c998bb642c1feab773cb0e751dbb0ece1e59d64 /packages/create-astro/src/components/App.tsx | |
parent | 467820996f71b0c78f2000294cb6f3c0a8f3aca4 (diff) | |
download | astro-ed631329e731d31e384dacc1ec399ba60b7c906b.tar.gz astro-ed631329e731d31e384dacc1ec399ba60b7c906b.tar.zst astro-ed631329e731d31e384dacc1ec399ba60b7c906b.zip |
`create-astro` UI (#164)
* refactor: improve create-astro layout, build script
* feat(create-astro): v0.1.0
* docs(create-astro): add README
* feat(create-astro): add meta files to starter templates
Diffstat (limited to 'packages/create-astro/src/components/App.tsx')
-rw-r--r-- | packages/create-astro/src/components/App.tsx | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/packages/create-astro/src/components/App.tsx b/packages/create-astro/src/components/App.tsx new file mode 100644 index 000000000..fd9192bb6 --- /dev/null +++ b/packages/create-astro/src/components/App.tsx @@ -0,0 +1,93 @@ +import React, {FC, useEffect} from 'react'; +import { prepareTemplate, isEmpty, emptyDir } from '../utils'; +import Header from './Header'; +import Install from './Install'; +import ProjectName from './ProjectName'; +import Template from './Template'; +import Confirm from './Confirm'; +import Finalize from './Finalize'; + +interface Context { + use: 'npm'|'yarn'; + run: boolean; + projectExists?: boolean; + force?: boolean; + projectName?: string; + template?: string; + templates: string[]; + ready?: boolean; +} + +const getStep = ({ projectName, projectExists: exists, template, force, ready }: Context) => { + switch (true) { + case !projectName: return { + key: 'projectName', + Component: ProjectName + }; + case projectName && exists === true && typeof force === 'undefined': return { + key: 'force', + Component: Confirm + } + case (exists === false || force) && !template: return { + key: 'template', + Component: Template + }; + case !ready: return { + key: 'install', + Component: Install + }; + default: return { + key: 'final', + Component: Finalize + } + } +} + +const App: FC<{ context: Context }> = ({ context }) => { + const [state, setState] = React.useState(context); + const step = React.useRef(getStep(context)); + const onSubmit = (value: string|boolean) => { + const { key } = step.current; + const newState = { ...state, [key]: value }; + step.current = getStep(newState) + setState(newState) + } + + useEffect(() => { + let isSubscribed = true + if (state.projectName && typeof state.projectExists === 'undefined') { + const newState = { ...state, projectExists: !isEmpty(state.projectName) }; + step.current = getStep(newState) + if (isSubscribed) { + setState(newState); + } + } + + if (state.projectName && (state.projectExists === false || state.force) && state.template) { + if (state.force) emptyDir(state.projectName); + prepareTemplate(context.use, state.template, state.projectName).then(() => { + if (isSubscribed) { + setState(v => { + const newState = {...v, ready: true }; + step.current = getStep(newState); + return newState; + }); + } + }); + } + + return () => { + isSubscribed = false; + } + }, [state]); + const { Component } = step.current; + + return ( + <> + <Header context={state}/> + <Component context={state} onSubmit={onSubmit} /> + </> + ) +}; + +export default App; |