Skip to content

Commit

Permalink
Merge pull request #30 from damianricobelli/feature/callbacks
Browse files Browse the repository at this point in the history
feature: add callbacks
  • Loading branch information
damianricobelli authored Aug 19, 2024
2 parents 2e51fdb + dd79f49 commit f75b9d2
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 14 deletions.
6 changes: 6 additions & 0 deletions .changeset/grumpy-tomatoes-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"docs": patch
"@stepperize/react": minor
---

feature: add callbacks
12 changes: 12 additions & 0 deletions docs/pages/docs/getting-started/stepper.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,18 @@ These are the props that can be passed to the `Stepper` component:
typeSimple: "function",
description: "Function to be called when metadata changes.",
},
{
name: "onBeforeStepChange",
type: "(currentStep: Step, nextStep: Step) => boolean",
typeSimple: "function",
description: "Function to be called before the step changes.",
},
{
name: "onAfterStepChange",
type: "(currentStep: Step, nextStep: Step) => void",
typeSimple: "function",
description: "Function to be called after the step changes.",
},
{
name: "children",
typeSimple: "React.ReactNode",
Expand Down
15 changes: 10 additions & 5 deletions docs/pages/docs/getting-started/use-stepper.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,20 @@ The `useStepper` hook returns an object with the following properties:
},
{
name: "goToNextStep",
typeSimple: "() => void",
type: "() => void",
typeSimple: "function",
description: "Allow to go to the next step",
},
{
name: "goToPrevStep",
typeSimple: "() => void",
type: "() => void",
typeSimple: "function",
description: "Allow to go to the previous step",
},
{
name: "goToStep",
typeSimple: "(id: string) => void",
type: "(id: string) => void",
typeSimple: "function",
description: "Set the current active step by ID",
},
{
Expand All @@ -67,7 +70,8 @@ The `useStepper` hook returns an object with the following properties:
},
{
name: "reset",
typeSimple: "() => void",
type: "() => void",
typeSimple: "function",
description: "Reset the stepper to the first step or initial step",
},
{
Expand All @@ -83,7 +87,8 @@ The `useStepper` hook returns an object with the following properties:
},
{
name: "getStepById",
typeSimple: "(id: string) => Step",
type: "(id: string) => Step",
typeSimple: "function",
description: "Get a step by its ID",
},
{
Expand Down
32 changes: 24 additions & 8 deletions packages/react/src/stepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const Stepper = <
expandable = false,
metadata,
onChangeMetadata,
onBeforeStepChange,
onAfterStepChange,
children,
}: StepperProps<Steps, Metadata>) => {
const initialCounter = React.useMemo(
Expand All @@ -29,27 +31,42 @@ export const Stepper = <
const isLastStep = counter === steps.length - 1;
const isFirstStep = counter === 0;

const stepsCount = steps.length;
function changeStep(newCounter: number) {
const nextStep = steps[newCounter];

if (onBeforeStepChange) {
const result = onBeforeStepChange(currentStep, nextStep);
if (result === false) {
return;
}
}

setCounter(newCounter);

if (onAfterStepChange) {
onAfterStepChange(currentStep, nextStep);
}
}

function goToNextStep() {
if (!isLastStep) {
setCounter((counter) => counter + 1);
changeStep(counter + 1);
}
}

function goToPrevStep() {
if (!isFirstStep) {
setCounter((counter) => counter - 1);
changeStep(counter - 1);
}
}

function goToStep(id: Step["id"]) {
const index = steps.findIndex((step) => step.id === id);
setCounter(index);
changeStep(index);
}

function reset() {
setCounter(initialCounter);
changeStep(initialCounter);
}

function getStepById(id: Step["id"]) {
Expand All @@ -64,7 +81,7 @@ export const Stepper = <
"data-step": step.id,
"data-optional": step.isOptional ?? false,
"data-disabled": step.isDisabled ?? false,
"data-completed": counter > steps.findIndex(s => s.id === id),
"data-completed": counter > steps.findIndex((s) => s.id === id),
"data-active": isActive,
"data-last": isLastStep,
},
Expand All @@ -76,7 +93,7 @@ export const Stepper = <
"aria-label": step.title ?? step.id,
"aria-current": isActive ? "step" : undefined,
"aria-posinset": counter + 1,
"aria-setsize": stepsCount,
"aria-setsize": steps.length,
"aria-labelledby": `${step.id}-label`,
"aria-describedby": step.description ?? step.id,
"aria-expanded": expandable,
Expand Down Expand Up @@ -114,7 +131,6 @@ export const Stepper = <
goToStep,
getStepById,
reset,
stepsCount,
when,
}}
>
Expand Down
9 changes: 8 additions & 1 deletion packages/react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export type StepperContextType<
goToStep: (id: Steps[number]["id"]) => void;
getStepById: (id: Steps[number]["id"]) => Step;
reset: () => void;
stepsCount: number;
when: (id: Steps[number]["id"]) => {
render: (
fn: (step: StepWithAttr<Step>) => React.ReactNode,
Expand All @@ -65,5 +64,13 @@ export type StepperProps<
expandable?: boolean;
metadata?: Metadata;
onChangeMetadata?: (metadata: Metadata) => void;
onBeforeStepChange?: (
currentStep: Steps[number],
nextStep: Steps[number],
) => boolean;
onAfterStepChange?: (
currentStep: Steps[number],
nextStep: Steps[number],
) => void;
children: React.ReactNode;
};

0 comments on commit f75b9d2

Please sign in to comment.