add steps
This commit is contained in:
76
apps/admin.saladeaula.digital/app/components/wizard.tsx
Normal file
76
apps/admin.saladeaula.digital/app/components/wizard.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
import React, {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useMemo,
|
||||
useState,
|
||||
type ReactNode,
|
||||
type ReactElement
|
||||
} from 'react'
|
||||
|
||||
type WizardContextProps = (name: string) => void
|
||||
|
||||
const WizardContext = createContext<WizardContextProps | null>(null)
|
||||
|
||||
export function useWizard(): WizardContextProps {
|
||||
const ctx = useContext(WizardContext)
|
||||
|
||||
if (!ctx) {
|
||||
throw new Error('useWizard must be used within <Wizard />')
|
||||
}
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
type WizardProps = {
|
||||
children: ReactNode
|
||||
index?: number
|
||||
onChange?: (index: number) => void
|
||||
}
|
||||
|
||||
export function Wizard({
|
||||
children,
|
||||
index: initIndex = 0,
|
||||
onChange
|
||||
}: WizardProps) {
|
||||
const [index, setIndex] = useState<number>(initIndex)
|
||||
|
||||
const components = useMemo(
|
||||
() => React.Children.toArray(children) as ReactElement<WizardStepProps>[],
|
||||
[children]
|
||||
)
|
||||
|
||||
const steps = useMemo(
|
||||
() => components.map((child) => child.props.name),
|
||||
[components]
|
||||
)
|
||||
|
||||
const child = components[index]
|
||||
|
||||
const onChange_ = useCallback<WizardContextProps>(
|
||||
(name) => {
|
||||
const nextIndex = steps.findIndex((n) => n === name)
|
||||
|
||||
if (nextIndex >= 0) {
|
||||
setIndex(nextIndex)
|
||||
onChange?.(nextIndex)
|
||||
}
|
||||
},
|
||||
[steps]
|
||||
)
|
||||
|
||||
return (
|
||||
<WizardContext.Provider value={onChange_}>
|
||||
{React.isValidElement(child) ? React.cloneElement(child) : child}
|
||||
</WizardContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export type WizardStepProps = {
|
||||
name: string
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export function WizardStep({ children }: WizardStepProps) {
|
||||
return <>{children}</>
|
||||
}
|
||||
Reference in New Issue
Block a user