mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 16:23:06 +10:00
refactor: useContext & remove enum
This commit is contained in:
@ -26,7 +26,7 @@ import {
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@documenso/ui/primitives/popover';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip';
|
||||
|
||||
import type { WithStep } from '../stepper';
|
||||
import { useStep } from '../stepper';
|
||||
import type { TAddFieldsFormSchema } from './add-fields.types';
|
||||
import {
|
||||
DocumentFlowFormContainerActions,
|
||||
@ -65,10 +65,9 @@ export const AddFieldsFormPartial = ({
|
||||
recipients,
|
||||
fields,
|
||||
onSubmit,
|
||||
useStep, // Stepper
|
||||
}: WithStep<AddFieldsFormProps>) => {
|
||||
}: AddFieldsFormProps) => {
|
||||
const { isWithinPageBounds, getFieldPosition, getPage } = useDocumentElement();
|
||||
const { currentStep, totalSteps, nextStep, previousStep } = useStep();
|
||||
const { currentStep, totalSteps, previousStep } = useStep();
|
||||
|
||||
const {
|
||||
control,
|
||||
|
||||
@ -18,7 +18,7 @@ import { Input } from '@documenso/ui/primitives/input';
|
||||
import { Label } from '@documenso/ui/primitives/label';
|
||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
import type { WithStep } from '../stepper';
|
||||
import { useStep } from '../stepper';
|
||||
import type { TAddSignersFormSchema } from './add-signers.types';
|
||||
import { ZAddSignersFormSchema } from './add-signers.types';
|
||||
import {
|
||||
@ -43,14 +43,13 @@ export const AddSignersFormPartial = ({
|
||||
document,
|
||||
fields: _fields,
|
||||
onSubmit,
|
||||
useStep, // Stepper
|
||||
}: WithStep<AddSignersFormProps>) => {
|
||||
}: AddSignersFormProps) => {
|
||||
const { toast } = useToast();
|
||||
const { remaining } = useLimits();
|
||||
|
||||
const initialId = useId();
|
||||
|
||||
const { currentStep, totalSteps, nextStep, previousStep } = useStep();
|
||||
const { currentStep, totalSteps, previousStep } = useStep();
|
||||
|
||||
const {
|
||||
control,
|
||||
|
||||
@ -10,7 +10,7 @@ import { Input } from '@documenso/ui/primitives/input';
|
||||
import { Label } from '@documenso/ui/primitives/label';
|
||||
import { Textarea } from '@documenso/ui/primitives/textarea';
|
||||
|
||||
import type { WithStep } from '../stepper';
|
||||
import { useStep } from '../stepper';
|
||||
import type { TAddSubjectFormSchema } from './add-subject.types';
|
||||
import {
|
||||
DocumentFlowFormContainerActions,
|
||||
@ -34,8 +34,7 @@ export const AddSubjectFormPartial = ({
|
||||
fields: _fields,
|
||||
document,
|
||||
onSubmit,
|
||||
useStep,
|
||||
}: WithStep<AddSubjectFormProps>) => {
|
||||
}: AddSubjectFormProps) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
@ -50,7 +49,7 @@ export const AddSubjectFormPartial = ({
|
||||
});
|
||||
|
||||
const onFormSubmit = handleSubmit(onSubmit);
|
||||
const { currentStep, totalSteps, nextStep, previousStep } = useStep();
|
||||
const { currentStep, totalSteps, previousStep } = useStep();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -8,7 +8,7 @@ import { FormErrorMessage } from '@documenso/ui/primitives/form/form-error-messa
|
||||
import { Input } from '@documenso/ui/primitives/input';
|
||||
import { Label } from '@documenso/ui/primitives/label';
|
||||
|
||||
import type { WithStep } from '../stepper';
|
||||
import { useStep } from '../stepper';
|
||||
import type { TAddTitleFormSchema } from './add-title.types';
|
||||
import {
|
||||
DocumentFlowFormContainerActions,
|
||||
@ -32,8 +32,7 @@ export const AddTitleFormPartial = ({
|
||||
fields: _fields,
|
||||
document,
|
||||
onSubmit,
|
||||
useStep,
|
||||
}: WithStep<AddTitleFormProps>) => {
|
||||
}: AddTitleFormProps) => {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
|
||||
@ -1,26 +1,24 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
type StepProps = {
|
||||
readonly useStep: () => {
|
||||
stepIndex: number;
|
||||
currentStep: number;
|
||||
totalSteps: number;
|
||||
isFirst: boolean;
|
||||
isLast: boolean;
|
||||
nextStep: () => void;
|
||||
previousStep: () => void;
|
||||
};
|
||||
type StepContextType = {
|
||||
stepIndex: number;
|
||||
currentStep: number;
|
||||
totalSteps: number;
|
||||
isFirst: boolean;
|
||||
isLast: boolean;
|
||||
nextStep: () => void;
|
||||
previousStep: () => void;
|
||||
};
|
||||
|
||||
export type WithStep<T> = T & StepProps;
|
||||
const StepContext = createContext<StepContextType | null>(null);
|
||||
|
||||
type StepperProps = {
|
||||
children: React.ReactNode;
|
||||
onComplete?: () => void;
|
||||
onStepChanged?: (currentStep: number) => void;
|
||||
currentStep?: number;
|
||||
setCurrentStep?: (step: number) => void;
|
||||
currentStep?: number; // external control prop
|
||||
setCurrentStep?: (step: number) => void; // external control function
|
||||
};
|
||||
|
||||
export const Stepper: FC<StepperProps> = ({
|
||||
@ -57,7 +55,12 @@ export const Stepper: FC<StepperProps> = ({
|
||||
onStepChanged && onStepChanged(currentStep);
|
||||
}, [currentStep, onStepChanged]);
|
||||
|
||||
const useStep = () => ({
|
||||
// Empty stepper
|
||||
if (totalSteps === 0) return null;
|
||||
|
||||
const currentChild = React.Children.toArray(children)[currentStep - 1];
|
||||
|
||||
const stepContextValue: StepContextType = {
|
||||
stepIndex: currentStep - 1,
|
||||
currentStep,
|
||||
totalSteps,
|
||||
@ -65,15 +68,14 @@ export const Stepper: FC<StepperProps> = ({
|
||||
isLast: currentStep === totalSteps,
|
||||
nextStep,
|
||||
previousStep,
|
||||
});
|
||||
};
|
||||
|
||||
// empty stepper
|
||||
if (totalSteps === 0) return null;
|
||||
|
||||
const currentChild = React.Children.toArray(children)[currentStep - 1];
|
||||
|
||||
// type validation
|
||||
if (!React.isValidElement<StepProps>(currentChild)) return null;
|
||||
|
||||
return <>{React.cloneElement(currentChild, { useStep })}</>;
|
||||
return <StepContext.Provider value={stepContextValue}>{currentChild}</StepContext.Provider>;
|
||||
};
|
||||
|
||||
/** Hook for children to use the step context */
|
||||
export const useStep = (): StepContextType => {
|
||||
const context = useContext(StepContext);
|
||||
if (!context) throw new Error('useStep must be used within a Stepper');
|
||||
return context;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user