Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/docs/app/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from "fumadocs-ui/page";

import { StepperDemo } from "@/registry/new-york/blocks/stepper-demo/components/stepper-demo";
import { StepperWithActivity } from "@/registry/new-york/blocks/stepper-with-activity/components/stepper-with-activity";
import { StepperWithDescription } from "@/registry/new-york/blocks/stepper-with-description/components/stepper-with-description";
import { StepperWithForm } from "@/registry/new-york/blocks/stepper-with-form/components/stepper-with-form";
import { StepperWithIcon } from "@/registry/new-york/blocks/stepper-with-icon/components/stepper-with-icon";
Expand Down Expand Up @@ -77,6 +78,7 @@ export default async function Page(props: {
Step,
DemoViewer,
StepperDemo,
StepperWithActivity,
StepperWithDescription,
StepperWithForm,
StepperWithIcon,
Expand Down
12 changes: 12 additions & 0 deletions apps/docs/content/docs/react/shadcn/examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ Install the example by copying the following command:
npx shadcn add https://stepperize.vercel.app/r/stepper-demo.json
```

## Stepper with `<Activity>`

<OpenInV0 name="stepper-with-activity">
<StepperWithActivity />
</OpenInV0>

Install the example by copying the following command:

```bash
npx shadcn add https://stepperize.vercel.app/r/stepper-with-activity.json
```

## Stepper with description

<OpenInV0 name="stepper-with-description">
Expand Down
126 changes: 63 additions & 63 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
@@ -1,65 +1,65 @@
{
"name": "docs",
"version": "2.5.7",
"private": true,
"scripts": {
"build": "next build --turbo",
"dev": "next dev --turbo",
"start": "next start",
"postinstall": "fumadocs-mdx",
"registry:build": "shadcn build",
"clean": "rm -rf .turbo .next node_modules"
},
"dependencies": {
"@hookform/resolvers": "^5.2.2",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.13",
"@stepperize/react": "workspace:*",
"@stepperize/solid": "workspace:*",
"@stepperize/vue": "workspace:*",
"arktype": "^2.1.22",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"fumadocs-core": "15.8.3",
"fumadocs-mdx": "12.0.2",
"fumadocs-twoslash": "3.1.8",
"fumadocs-typescript": "4.0.11",
"fumadocs-ui": "15.8.3",
"geist": "1.5.1",
"hast-util-to-jsx-runtime": "^2.3.6",
"lucide-react": "^0.544.0",
"motion": "^12.23.22",
"next": "15.5.4",
"react": "catalog:",
"react-dom": "catalog:",
"react-hook-form": "^7.64.0",
"shadcn": "3.4.0",
"shiki": "3.13.0",
"solid-js": "^1.9.9",
"tailwind-merge": "^3.3.1",
"ts-morph": "27.0.0",
"tw-animate-css": "^1.4.0",
"twoslash": "^0.3.4",
"valibot": "^1.1.0",
"zod": "^4.1.11"
},
"devDependencies": {
"@fumadocs/cli": "^1.0.2",
"@tailwindcss/postcss": "^4.1.14",
"@types/mdx": "^2.0.13",
"@types/node": "24.7.0",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"@types/react-syntax-highlighter": "^15.5.13",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.14",
"typescript": "catalog:"
}
"name": "docs",
"version": "2.5.7",
"private": true,
"scripts": {
"build": "next build --turbo",
"dev": "next dev --turbo",
"start": "next start",
"postinstall": "fumadocs-mdx",
"registry:build": "shadcn build",
"clean": "rm -rf .turbo .next node_modules"
},
"dependencies": {
"@hookform/resolvers": "^5.2.2",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.13",
"@stepperize/react": "workspace:*",
"@stepperize/solid": "workspace:*",
"@stepperize/vue": "workspace:*",
"arktype": "^2.1.22",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"fumadocs-core": "15.8.3",
"fumadocs-mdx": "12.0.2",
"fumadocs-twoslash": "3.1.8",
"fumadocs-typescript": "4.0.11",
"fumadocs-ui": "15.8.3",
"geist": "1.5.1",
"hast-util-to-jsx-runtime": "^2.3.6",
"lucide-react": "^0.544.0",
"motion": "^12.23.22",
"next": "16.0.0-beta.0",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, don't update the next package to the beta version

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe Next 16 has been released yet and afaik this is the version that React 19.2 is included in which is when Activity is introduced.

Totally fine if you don't merge while it's still in beta but just wanted to get this PR open.

If you're aware of a lower version of Next that includes React 19.2, happy to downgrade.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The library does not depend on NextJS, so I think you could use the Activity API without any issues because the react version in the repo is the new one. I haven't tested it yet, but I don't think you'll have any problems.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Hmm, unfortunately I get this error when it's a lower next version. When I log React.version you can see 19.2.0-canary-0bdb9206-20250818 logged so it's possible the 19.2.0 set in the catalog is not getting resolved correctly

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yea I see. Well, in that case I wonder if we can just document this use case without a preview and just add a sub section in the hook docs: https://stepperize.vercel.app/docs/react/api-references/hook#rendering-methods

Would be great to have a live preview, but I don’t like the idea of use a very early beta version of NextJS affecting all the docs app. This could generate otros unexpected issues in other libraries related to fumadocs

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry haven't had time to get back to this. Saw the new version of next and fumadocs is stable release. Would you want to hold this PR until that's upgraded?

"react": "catalog:",
"react-dom": "catalog:",
"react-hook-form": "^7.64.0",
"shadcn": "3.4.0",
"shiki": "3.13.0",
"solid-js": "^1.9.9",
"tailwind-merge": "^3.3.1",
"ts-morph": "27.0.0",
"tw-animate-css": "^1.4.0",
"twoslash": "^0.3.4",
"valibot": "^1.1.0",
"zod": "^4.1.11"
},
"devDependencies": {
"@fumadocs/cli": "^1.0.2",
"@tailwindcss/postcss": "^4.1.14",
"@types/mdx": "^2.0.13",
"@types/node": "24.7.0",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"@types/react-syntax-highlighter": "^15.5.13",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.14",
"typescript": "catalog:"
}
}
27 changes: 27 additions & 0 deletions apps/docs/public/r/stepper-with-activity.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"use client";

import * as React from "react";

import { defineStepper } from "@/registry/new-york/blocks/stepper-with-activity/components/ui/stepper";
import { Button } from "@/registry/new-york/ui/button";

const { Stepper, useStepper } = defineStepper(
{
id: "step-1",
title: "Step 1",
},
{
id: "step-2",
title: "Step 2",
},
{
id: "step-3",
title: "Step 3",
}
);

export function StepperWithActivity() {
return (
<Stepper.Provider className="space-y-4" variant="horizontal">
{({ methods }) => (
<React.Fragment>
<Stepper.Navigation>
{methods.all.map((step) => (
<Stepper.Step
key={step.id}
of={step.id}
onClick={() => methods.goTo(step.id)}
>
<Stepper.Title>{step.title}</Stepper.Title>
</Stepper.Step>
))}
</Stepper.Navigation>
<Wrapper />
<Stepper.Controls>
{!methods.isLast && (
<Button
type="button"
variant="secondary"
onClick={methods.prev}
disabled={methods.isFirst}
>
Previous
</Button>
)}
<Button onClick={methods.isLast ? methods.reset : methods.next}>
{methods.isLast ? "Reset" : "Next"}
</Button>
</Stepper.Controls>
</React.Fragment>
)}
</Stepper.Provider>
);
}

const Wrapper = () => {
const { current } = useStepper();

return (
<>
<React.Activity mode={current.id === "step-1" ? "visible" : "hidden"}>
<Content id={current.id} />
</React.Activity>
<React.Activity mode={current.id === "step-2" ? "visible" : "hidden"}>
<Content id={current.id} />
</React.Activity>
<React.Activity mode={current.id === "step-3" ? "visible" : "hidden"}>
<Content id={current.id} />
</React.Activity>
</>
);
};
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can achieve this in a simpler way, like

const Wrapper = () => {
  const { current } = useStepper();

  return (
    <>
      {steps.map((stepId) => (
        <React.Activity
          key={stepId}
          mode={current.id === stepId ? "visible" : "hidden"}
        >
          <Content id={current.id} />
        </React.Activity>
      ))}
    </>
  );
};

Getting the steps from the defineStepper instance

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah ya fair callout, originally it was rendering a different component for each step but simplified it to use the basic component


const Content = ({ id }: { id: string }) => {
return (
<Stepper.Panel className="h-[200px] content-center rounded border bg-secondary text-secondary-foreground p-8">
<p className="text-xl font-normal">Content for {id}</p>
</Stepper.Panel>
);
};
Loading