@navinc/base-react-components
Version:
Nav's Pattern Library
127 lines (110 loc) • 3.38 kB
JavaScript
import React, { useState, createContext, useContext, useCallback } from 'react'
import styled from 'styled-components'
import Header from './header.js'
import Copy from './copy'
import CDNIllustration from './cdn-illustration.js'
import StandardCard from './standard-card.js'
const WizardFlowContext = createContext({})
export const ChildContainer = styled.div``
export const Image = styled(CDNIllustration)`
max-width: 192px;
justify-self: center;
@media (${({ theme }) => theme.forLargerThanPhone}) {
width: 192px;
}
`
export const Container = styled.div`
display: grid;
grid-template-columns: auto;
grid-auto-rows: auto;
${ChildContainer} {
grid-column: span 2;
grid-row: 2;
}
@media (${({ theme }) => theme.forLargerThanPhone}) {
grid-template-columns: 1fr 2fr;
grid-auto-rows: auto;
${Image} {
grid-row: span 2;
}
${ChildContainer} {
grid-column: initial;
grid-row: initial;
}
}
`
const StyledCopy = styled(Copy)`
/* styling for the colored bar above the question steps label */
&::before {
content: '';
background: ${({ stepColor, theme }) => stepColor || theme.lightBlue400};
display: block;
width: 88px;
height: 8px;
border-radius: 4px;
margin-bottom: 16px;
}
`
export const InnerContainer = styled.div`
display: grid;
grid-gap: 16px;
`
export const WizardFlowProvider = ({ children }) => {
const childrenArray = React.Children.toArray(children)
const [currentStep, setCurrentStep] = useState(0)
const [isLoading, setIsLoading] = useState(false)
const incrementStep = useCallback(() => setCurrentStep(currentStep + 1), [currentStep])
const decrementStep = useCallback(() => setCurrentStep(currentStep - 1), [currentStep])
const values = {
currentStep: currentStep + 1,
totalSteps: childrenArray.length,
incrementStep,
decrementStep,
isLoading,
setIsLoading,
}
return <WizardFlowContext.Provider value={values}>{childrenArray[currentStep]}</WizardFlowContext.Provider>
}
export const useWizardFlow = () => {
const { currentStep, totalSteps, incrementStep, decrementStep, isLoading, setIsLoading } = useContext(
WizardFlowContext
)
return { currentStep, totalSteps, incrementStep, decrementStep, isLoading, setIsLoading }
}
const WizardStep = ({
stepLabel,
stepColor,
stepContainerTestId,
imageFileName,
headerCopy,
actionTrackingContext,
actionForm,
actionText,
actionTestId,
children,
}) => {
const { currentStep, totalSteps, decrementStep, isLoading } = useWizardFlow()
return (
<>
<Container data-testid={stepContainerTestId}>
{imageFileName && <Image filename={imageFileName} />}
<InnerContainer>
<StyledCopy light shouldScaleFont size="sm" stepColor={stepColor}>
{stepLabel || `QUESTION ${currentStep} OF ${totalSteps}`}
</StyledCopy>
{headerCopy && <Header size="lg">{headerCopy}</Header>}
{children}
</InnerContainer>
</Container>
<StandardCard.Footer
isLoading={isLoading}
actionDataTestId={actionTestId}
actionText={actionText || 'Next'}
actionForm={actionForm}
onBack={currentStep > 1 ? () => decrementStep() : null}
actionTrackingContext={actionTrackingContext}
/>
</>
)
}
export default WizardStep