React Package (@gooonzick/wizard-react) ​
useWizard Hook ​
ts
function useWizard<T extends Record<string, unknown>>(
options: UseWizardOptions<T>,
): UseWizardReturn<T>;UseWizardOptions<T> ​
ts
interface UseWizardOptions<T> {
definition: WizardDefinition<T>;
initialData: T;
context?: WizardContext;
onStateChange?: (state: WizardState<T>) => void;
onStepEnter?: (stepId: StepId, data: T) => void;
onStepLeave?: (stepId: StepId, data: T) => void;
onComplete?: (data: T) => void;
onError?: (error: Error) => void;
}UseWizardReturn<T> ​
The hook returns an organized object with five slices:
ts
interface UseWizardReturn<T> {
state: UseWizardState<T>;
validation: UseWizardValidation;
navigation: UseWizardNavigation;
loading: UseWizardLoading;
actions: UseWizardActions<T>;
}
interface UseWizardState<T> {
currentStepId: StepId;
currentStep: WizardStepDefinition<T>;
data: T;
isCompleted: boolean;
}
interface UseWizardValidation {
isValid: boolean;
validationErrors?: Record<string, string>;
}
interface UseWizardNavigation {
// State
canGoNext: boolean;
canGoPrevious: boolean;
isFirstStep: boolean;
isLastStep: boolean;
visitedSteps: StepId[];
availableSteps: StepId[];
stepHistory: StepId[];
// Actions
goNext(): Promise<void>;
goPrevious(): Promise<void>;
goBack(steps?: number): Promise<void>;
goToStep(stepId: StepId): Promise<void>;
}
interface UseWizardLoading {
isValidating: boolean;
isSubmitting: boolean;
isNavigating: boolean;
}
interface UseWizardActions<T> {
updateData(updater: (data: T) => T): void;
setData(data: T): void;
updateField<K extends keyof T>(field: K, value: T[K]): void;
validate(): Promise<void>;
canSubmit(): Promise<boolean>;
submit(): Promise<void>;
reset(data?: T): void;
}Example:
ts
import { useWizard } from "@gooonzick/wizard-react";
const { state, navigation, actions, validation, loading } = useWizard({
definition: myWizard,
initialData: { name: "", email: "" },
onComplete: (data) => {
console.log("Completed:", data);
},
});
// Use state.currentStep, state.data, navigation.goNext(), actions.updateField(), etc.Granular Hooks ​
For fine-grained subscriptions, use WizardProvider with these hooks:
ts
// Only subscribes to data changes
const { data, currentStepId, currentStep, isCompleted } = useWizardData<T>();
// Only subscribes to navigation changes
const { canGoNext, canGoPrevious, goNext, goPrevious, ... } = useWizardNavigation();
// Only subscribes to validation changes
const { isValid, validationErrors } = useWizardValidation();
// Only subscribes to loading changes
const { isValidating, isSubmitting, isNavigating } = useWizardLoading();
// Actions (stable, doesn't cause re-renders)
const { updateField, updateData, setData, validate, submit, reset, canSubmit } = useWizardActions<T>();WizardProvider ​
Context provider for sharing wizard state:
ts
interface WizardProviderProps<T> {
definition: WizardDefinition<T>;
initialData: T;
context?: WizardContext;
onStateChange?: (state: WizardState<T>) => void;
onStepEnter?: (stepId: StepId, data: T) => void;
onStepLeave?: (stepId: StepId, data: T) => void;
onComplete?: (data: T) => void;
onError?: (error: Error) => void;
children: React.ReactNode;
}