diff --git a/apps/www/content/docs/components/stepper.mdx b/apps/www/content/docs/components/stepper.mdx
index 4df49e06953..5ad08739655 100644
--- a/apps/www/content/docs/components/stepper.mdx
+++ b/apps/www/content/docs/components/stepper.mdx
@@ -61,15 +61,13 @@ A `Stepper` component is composed of the following parts:
- `StepperTitle` - Step title.
- `StepperDescription` - Step description.
- `StepperPanel` - Section to render the step content based on the current step.
-- `StepperControls` - Step controls to navigate through the steps.
-- `StepperAction` - Next, previous and reset buttons.
+- `StepperControls` - Section to render the buttons to navigate through the steps.
## Usage
```tsx showLineNumbers
import {
Stepper,
- StepperAction,
StepperControls,
StepperDescription,
StepperNavigation,
@@ -96,10 +94,7 @@ export function Component() {
...
-
-
- ...
-
+ ...
)
}
@@ -138,17 +133,12 @@ export function MyFirstStepper() {
```tsx
export function MyFirstStepper() {
- const steps = stepperInstance.steps
return (
{({ methods }) => (
- {steps.map((step) => (
- methods.goTo(step.id)}
- >
+ {methods.all.map((step) => (
+ methods.goTo(step.id)}>
{step.title}
))}
@@ -166,12 +156,16 @@ export function MyFirstStepper() {
const steps = stepperInstance.steps
return (
- {/* StepperNavigation code */}
- {steps.map((step) => (
-
- {({ step }) => Content for {step.id}
}
-
- ))}
+ {({ methods }) => (
+ <>
+ {/* StepperNavigation code */}
+ {methods.switch({
+ "step-1": (step) => ,
+ "step-2": (step) => ,
+ "step-3": (step) => ,
+ })}
+ >
+ )}
)
}
@@ -187,13 +181,26 @@ export function MyFirstStepper() {
const steps = stepperInstance.steps
return (
- {/* StepperNavigation code */}
- {/* StepperPanel code */}
-
- Previous
- Next
- Reset
-
+ {({ methods }) => (
+ <>
+ {/* StepperNavigation code */}
+ {/* StepperPanel code */}
+
+ {!methods.isLast && (
+
+ )}
+
+
+ >
+ )}
)
}
@@ -203,43 +210,49 @@ export function MyFirstStepper() {
```tsx
export function MyFirstStepper() {
- const steps = stepperInstance.steps
return (
{({ methods }) => (
<>
- {steps.map((step) => (
- methods.goTo(step.id)}
- >
+ {methods.all.map((step) => (
+ methods.goTo(step.id)}>
{step.title}
))}
- {steps.map((step) => (
-
- {({ step }) => (
- Content for {step.id}
- )}
-
- ))}
+ {methods.switch({
+ "step-1": (step) => ,
+ "step-2": (step) => ,
+ "step-3": (step) => ,
+ })}
- Previous
- Next
- Reset
+ {!methods.isLast && (
+
+ )}
+
>
)}
)
}
+
+const Content = ({ id }: { id: string }) => {
+ return (
+
+ Content for {id}
+
+ )
+}
```
@@ -295,7 +308,7 @@ The children accept a function that has as parameters the `methods` prop. The `m
If you don't need the `methods` prop, you can just pass the children directly
- and get the methods from the `useStepper` hook.
+ and get the methods from the `useStepper` hook from your stepper instance.
**Props**
@@ -355,22 +368,14 @@ The `StepperDescription` component is used to render the description of the step
## StepperPanel
-The `StepperPanel` component is used to render the content of the step. You just need to pass the `when` prop which is the step you want to render.
-
-The children accept a function that has as parameters the step and a function `onBeforeAction` that allows to execute a callback before an action `prev`, `next` or `
-
-
- You don't have to worry about the stepper knowing which panel to render. If
- the step is not correct, the panel will not be rendered.
-
+The `StepperPanel` component is used to render the content of the step.
**Props**
-| Name | Type | Description |
-| ---------- | ------------------------------------------------------- | ----------------------------------------- |
-| `children` | `React.ReactNode or function({step, onBeforeCallback})` | Content to render. |
-| `when` | `Step` | Used to conditionally render the content. |
-| `asChild` | `boolean` | Render as child. |
+| Name | Type | Description |
+| ---------- | ----------------- | ------------------ |
+| `children` | `React.ReactNode` | Content to render. |
+| `asChild` | `boolean` | Render as child. |
## StepperControls
@@ -383,23 +388,33 @@ The `StepperControls` component is used to render the buttons to navigate throug
| `children` | `React.ReactNode` | Buttons to render. |
| `asChild` | `boolean` | Render as child. |
-### StepperAction
+## Before/after actions
-The `StepperAction` component is used to render the buttons to navigate through the steps. You just need to pass the `action` prop which is the action you want to perform.
+You can add a callback to the `next` and `prev` methods to execute a callback before or after the action is executed.
+**This is useful if you need to validate the form or check if the step is valid before moving to the prev/next step.**
-
- If you need to execute a function before the button action is executed, you
- can use the `onBeforeAction` prop.
-
+For example:
-**Props**
+```tsx
+methods.beforeNext(async () => {
+ const valid = await form.trigger()
+ if (!valid) return false
+ return true
+})
+```
+
+That function will validate the form and check if the step is valid before moving to the next step returning a boolean value.
+
+More info about the `beforeNext` and `beforePrev` methods can be found in the [API References](https://stepperize.vercel.app/docs/react/api-references/hook#beforeafter-functions).
-| Name | Type | Description |
-| ---------------- | ----------------------------------------------------------------------------------------- | --------------------------------------------------- |
-| `children` | `React.ReactNode` | Buttons to render. |
-| `asChild` | `boolean` | Render as child. |
-| `action` | `prev, next or reset` | Action to perform. |
-| `onBeforeAction` | `(event: React.MouseEvent, prevStep: Step, nextStep: Step) => boolean` | Function to execute before the action is performed. |
+## Skip steps
+
+Through the methods you can access functions like `goTo` to skip to a specific step.
+
+```tsx
+// From step 1 to step 3
+methods.goTo("step-3")
+```
## Examples
diff --git a/apps/www/package.json b/apps/www/package.json
index 111de6e4b7f..3f1300eaab6 100644
--- a/apps/www/package.json
+++ b/apps/www/package.json
@@ -52,7 +52,7 @@
"@radix-ui/react-toggle": "^1.0.3",
"@radix-ui/react-toggle-group": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.6",
- "@stepperize/react": "^4.1.3",
+ "@stepperize/react": "^4.2.0",
"@tanstack/react-table": "^8.9.1",
"@vercel/analytics": "^1.2.2",
"@vercel/og": "^0.0.21",
diff --git a/apps/www/public/r/colors/index.json b/apps/www/public/r/colors/index.json
index c25158efb11..c06c452a3ff 100644
--- a/apps/www/public/r/colors/index.json
+++ b/apps/www/public/r/colors/index.json
@@ -6,6 +6,7 @@
"hex": "#000000",
"rgb": "rgb(0,0,0)",
"hsl": "hsl(0,0%,0%)",
+ "oklch": "oklch(0.00,0.00,0)",
"rgbChannel": "0 0 0",
"hslChannel": "0 0% 0%"
},
@@ -13,6 +14,7 @@
"hex": "#ffffff",
"rgb": "rgb(255,255,255)",
"hsl": "hsl(0,0%,100%)",
+ "oklch": "oklch(1.00,0.00,0)",
"rgbChannel": "255 255 255",
"hslChannel": "0 0% 100%"
},
@@ -22,6 +24,7 @@
"hex": "#f8fafc",
"rgb": "rgb(248,250,252)",
"hsl": "hsl(210,40%,98%)",
+ "oklch": "oklch(0.98,0.00,248)",
"rgbChannel": "248 250 252",
"hslChannel": "210 40% 98%"
},
@@ -30,6 +33,7 @@
"hex": "#f1f5f9",
"rgb": "rgb(241,245,249)",
"hsl": "hsl(210,40%,96.1%)",
+ "oklch": "oklch(0.97,0.01,248)",
"rgbChannel": "241 245 249",
"hslChannel": "210 40% 96.1%"
},
@@ -38,6 +42,7 @@
"hex": "#e2e8f0",
"rgb": "rgb(226,232,240)",
"hsl": "hsl(214.3,31.8%,91.4%)",
+ "oklch": "oklch(0.93,0.01,256)",
"rgbChannel": "226 232 240",
"hslChannel": "214.3 31.8% 91.4%"
},
@@ -46,6 +51,7 @@
"hex": "#cbd5e1",
"rgb": "rgb(203,213,225)",
"hsl": "hsl(212.7,26.8%,83.9%)",
+ "oklch": "oklch(0.87,0.02,253)",
"rgbChannel": "203 213 225",
"hslChannel": "212.7 26.8% 83.9%"
},
@@ -54,6 +60,7 @@
"hex": "#94a3b8",
"rgb": "rgb(148,163,184)",
"hsl": "hsl(215,20.2%,65.1%)",
+ "oklch": "oklch(0.71,0.04,257)",
"rgbChannel": "148 163 184",
"hslChannel": "215 20.2% 65.1%"
},
@@ -62,6 +69,7 @@
"hex": "#64748b",
"rgb": "rgb(100,116,139)",
"hsl": "hsl(215.4,16.3%,46.9%)",
+ "oklch": "oklch(0.55,0.04,257)",
"rgbChannel": "100 116 139",
"hslChannel": "215.4 16.3% 46.9%"
},
@@ -70,6 +78,7 @@
"hex": "#475569",
"rgb": "rgb(71,85,105)",
"hsl": "hsl(215.3,19.3%,34.5%)",
+ "oklch": "oklch(0.45,0.04,257)",
"rgbChannel": "71 85 105",
"hslChannel": "215.3 19.3% 34.5%"
},
@@ -78,6 +87,7 @@
"hex": "#334155",
"rgb": "rgb(51,65,85)",
"hsl": "hsl(215.3,25%,26.7%)",
+ "oklch": "oklch(0.37,0.04,257)",
"rgbChannel": "51 65 85",
"hslChannel": "215.3 25% 26.7%"
},
@@ -86,6 +96,7 @@
"hex": "#1e293b",
"rgb": "rgb(30,41,59)",
"hsl": "hsl(217.2,32.6%,17.5%)",
+ "oklch": "oklch(0.28,0.04,260)",
"rgbChannel": "30 41 59",
"hslChannel": "217.2 32.6% 17.5%"
},
@@ -94,6 +105,7 @@
"hex": "#0f172a",
"rgb": "rgb(15,23,42)",
"hsl": "hsl(222.2,47.4%,11.2%)",
+ "oklch": "oklch(0.21,0.04,266)",
"rgbChannel": "15 23 42",
"hslChannel": "222.2 47.4% 11.2%"
},
@@ -102,6 +114,7 @@
"hex": "#020617",
"rgb": "rgb(2,6,23)",
"hsl": "hsl(222.2,84%,4.9%)",
+ "oklch": "oklch(0.13,0.04,265)",
"rgbChannel": "2 6 23",
"hslChannel": "222.2 84% 4.9%"
}
@@ -112,6 +125,7 @@
"hex": "#f9fafb",
"rgb": "rgb(249,250,251)",
"hsl": "hsl(210,20%,98%)",
+ "oklch": "oklch(0.98,0.00,248)",
"rgbChannel": "249 250 251",
"hslChannel": "210 20% 98%"
},
@@ -120,6 +134,7 @@
"hex": "#f3f4f6",
"rgb": "rgb(243,244,246)",
"hsl": "hsl(220,14.3%,95.9%)",
+ "oklch": "oklch(0.97,0.00,265)",
"rgbChannel": "243 244 246",
"hslChannel": "220 14.3% 95.9%"
},
@@ -128,6 +143,7 @@
"hex": "#e5e7eb",
"rgb": "rgb(229,231,235)",
"hsl": "hsl(220,13%,91%)",
+ "oklch": "oklch(0.93,0.01,265)",
"rgbChannel": "229 231 235",
"hslChannel": "220 13% 91%"
},
@@ -136,6 +152,7 @@
"hex": "#d1d5db",
"rgb": "rgb(209,213,219)",
"hsl": "hsl(216,12.2%,83.9%)",
+ "oklch": "oklch(0.87,0.01,258)",
"rgbChannel": "209 213 219",
"hslChannel": "216 12.2% 83.9%"
},
@@ -144,6 +161,7 @@
"hex": "#9ca3af",
"rgb": "rgb(156,163,175)",
"hsl": "hsl(217.9,10.6%,64.9%)",
+ "oklch": "oklch(0.71,0.02,261)",
"rgbChannel": "156 163 175",
"hslChannel": "217.9 10.6% 64.9%"
},
@@ -152,6 +170,7 @@
"hex": "#6b7280",
"rgb": "rgb(107,114,128)",
"hsl": "hsl(220,8.9%,46.1%)",
+ "oklch": "oklch(0.55,0.02,264)",
"rgbChannel": "107 114 128",
"hslChannel": "220 8.9% 46.1%"
},
@@ -160,6 +179,7 @@
"hex": "#4b5563",
"rgb": "rgb(75,85,99)",
"hsl": "hsl(215,13.8%,34.1%)",
+ "oklch": "oklch(0.45,0.03,257)",
"rgbChannel": "75 85 99",
"hslChannel": "215 13.8% 34.1%"
},
@@ -168,6 +188,7 @@
"hex": "#374151",
"rgb": "rgb(55,65,81)",
"hsl": "hsl(216.9,19.1%,26.7%)",
+ "oklch": "oklch(0.37,0.03,260)",
"rgbChannel": "55 65 81",
"hslChannel": "216.9 19.1% 26.7%"
},
@@ -176,6 +197,7 @@
"hex": "#1f2937",
"rgb": "rgb(31,41,55)",
"hsl": "hsl(215,27.9%,16.9%)",
+ "oklch": "oklch(0.28,0.03,257)",
"rgbChannel": "31 41 55",
"hslChannel": "215 27.9% 16.9%"
},
@@ -184,6 +206,7 @@
"hex": "#111827",
"rgb": "rgb(17,24,39)",
"hsl": "hsl(220.9,39.3%,11%)",
+ "oklch": "oklch(0.21,0.03,265)",
"rgbChannel": "17 24 39",
"hslChannel": "220.9 39.3% 11%"
},
@@ -192,6 +215,7 @@
"hex": "#030712",
"rgb": "rgb(3,7,18)",
"hsl": "hsl(224,71.4%,4.1%)",
+ "oklch": "oklch(0.13,0.03,262)",
"rgbChannel": "3 7 18",
"hslChannel": "224 71.4% 4.1%"
}
@@ -202,6 +226,7 @@
"hex": "#fafafa",
"rgb": "rgb(250,250,250)",
"hsl": "hsl(0,0%,98%)",
+ "oklch": "oklch(0.99,0.00,0)",
"rgbChannel": "250 250 250",
"hslChannel": "0 0% 98%"
},
@@ -210,6 +235,7 @@
"hex": "#f4f4f5",
"rgb": "rgb(244,244,245)",
"hsl": "hsl(240,4.8%,95.9%)",
+ "oklch": "oklch(0.97,0.00,286)",
"rgbChannel": "244 244 245",
"hslChannel": "240 4.8% 95.9%"
},
@@ -218,6 +244,7 @@
"hex": "#e4e4e7",
"rgb": "rgb(228,228,231)",
"hsl": "hsl(240,5.9%,90%)",
+ "oklch": "oklch(0.92,0.00,286)",
"rgbChannel": "228 228 231",
"hslChannel": "240 5.9% 90%"
},
@@ -226,6 +253,7 @@
"hex": "#d4d4d8",
"rgb": "rgb(212,212,216)",
"hsl": "hsl(240,4.9%,83.9%)",
+ "oklch": "oklch(0.87,0.01,286)",
"rgbChannel": "212 212 216",
"hslChannel": "240 4.9% 83.9%"
},
@@ -234,6 +262,7 @@
"hex": "#a1a1aa",
"rgb": "rgb(161,161,170)",
"hsl": "hsl(240,5%,64.9%)",
+ "oklch": "oklch(0.71,0.01,286)",
"rgbChannel": "161 161 170",
"hslChannel": "240 5% 64.9%"
},
@@ -242,6 +271,7 @@
"hex": "#71717a",
"rgb": "rgb(113,113,122)",
"hsl": "hsl(240,3.8%,46.1%)",
+ "oklch": "oklch(0.55,0.01,286)",
"rgbChannel": "113 113 122",
"hslChannel": "240 3.8% 46.1%"
},
@@ -250,6 +280,7 @@
"hex": "#52525b",
"rgb": "rgb(82,82,91)",
"hsl": "hsl(240,5.2%,33.9%)",
+ "oklch": "oklch(0.44,0.01,286)",
"rgbChannel": "82 82 91",
"hslChannel": "240 5.2% 33.9%"
},
@@ -258,6 +289,7 @@
"hex": "#3f3f46",
"rgb": "rgb(63,63,70)",
"hsl": "hsl(240,5.3%,26.1%)",
+ "oklch": "oklch(0.37,0.01,286)",
"rgbChannel": "63 63 70",
"hslChannel": "240 5.3% 26.1%"
},
@@ -266,6 +298,7 @@
"hex": "#27272a",
"rgb": "rgb(39,39,42)",
"hsl": "hsl(240,3.7%,15.9%)",
+ "oklch": "oklch(0.27,0.01,286)",
"rgbChannel": "39 39 42",
"hslChannel": "240 3.7% 15.9%"
},
@@ -274,6 +307,7 @@
"hex": "#18181b",
"rgb": "rgb(24,24,27)",
"hsl": "hsl(240,5.9%,10%)",
+ "oklch": "oklch(0.21,0.01,286)",
"rgbChannel": "24 24 27",
"hslChannel": "240 5.9% 10%"
},
@@ -282,6 +316,7 @@
"hex": "#09090b",
"rgb": "rgb(9,9,11)",
"hsl": "hsl(240,10%,3.9%)",
+ "oklch": "oklch(0.14,0.00,286)",
"rgbChannel": "9 9 11",
"hslChannel": "240 10% 3.9%"
}
@@ -292,6 +327,7 @@
"hex": "#fafafa",
"rgb": "rgb(250,250,250)",
"hsl": "hsl(0,0%,98%)",
+ "oklch": "oklch(0.99,0.00,0)",
"rgbChannel": "250 250 250",
"hslChannel": "0 0% 98%"
},
@@ -300,6 +336,7 @@
"hex": "#f5f5f5",
"rgb": "rgb(245,245,245)",
"hsl": "hsl(0,0%,96.1%)",
+ "oklch": "oklch(0.97,0.00,0)",
"rgbChannel": "245 245 245",
"hslChannel": "0 0% 96.1%"
},
@@ -308,6 +345,7 @@
"hex": "#e5e5e5",
"rgb": "rgb(229,229,229)",
"hsl": "hsl(0,0%,89.8%)",
+ "oklch": "oklch(0.92,0.00,0)",
"rgbChannel": "229 229 229",
"hslChannel": "0 0% 89.8%"
},
@@ -316,6 +354,7 @@
"hex": "#d4d4d4",
"rgb": "rgb(212,212,212)",
"hsl": "hsl(0,0%,83.1%)",
+ "oklch": "oklch(0.87,0.00,0)",
"rgbChannel": "212 212 212",
"hslChannel": "0 0% 83.1%"
},
@@ -324,6 +363,7 @@
"hex": "#a3a3a3",
"rgb": "rgb(163,163,163)",
"hsl": "hsl(0,0%,63.9%)",
+ "oklch": "oklch(0.72,0.00,0)",
"rgbChannel": "163 163 163",
"hslChannel": "0 0% 63.9%"
},
@@ -332,6 +372,7 @@
"hex": "#737373",
"rgb": "rgb(115,115,115)",
"hsl": "hsl(0,0%,45.1%)",
+ "oklch": "oklch(0.56,0.00,0)",
"rgbChannel": "115 115 115",
"hslChannel": "0 0% 45.1%"
},
@@ -340,6 +381,7 @@
"hex": "#525252",
"rgb": "rgb(82,82,82)",
"hsl": "hsl(0,0%,32.2%)",
+ "oklch": "oklch(0.44,0.00,0)",
"rgbChannel": "82 82 82",
"hslChannel": "0 0% 32.2%"
},
@@ -348,6 +390,7 @@
"hex": "#404040",
"rgb": "rgb(64,64,64)",
"hsl": "hsl(0,0%,25.1%)",
+ "oklch": "oklch(0.37,0.00,0)",
"rgbChannel": "64 64 64",
"hslChannel": "0 0% 25.1%"
},
@@ -356,6 +399,7 @@
"hex": "#262626",
"rgb": "rgb(38,38,38)",
"hsl": "hsl(0,0%,14.9%)",
+ "oklch": "oklch(0.27,0.00,0)",
"rgbChannel": "38 38 38",
"hslChannel": "0 0% 14.9%"
},
@@ -364,6 +408,7 @@
"hex": "#171717",
"rgb": "rgb(23,23,23)",
"hsl": "hsl(0,0%,9%)",
+ "oklch": "oklch(0.20,0.00,0)",
"rgbChannel": "23 23 23",
"hslChannel": "0 0% 9%"
},
@@ -372,6 +417,7 @@
"hex": "#0a0a0a",
"rgb": "rgb(10,10,10)",
"hsl": "hsl(0,0%,3.9%)",
+ "oklch": "oklch(0.14,0.00,0)",
"rgbChannel": "10 10 10",
"hslChannel": "0 0% 3.9%"
}
@@ -382,6 +428,7 @@
"hex": "#fafaf9",
"rgb": "rgb(250,250,249)",
"hsl": "hsl(60,9.1%,97.8%)",
+ "oklch": "oklch(0.98,0.00,106)",
"rgbChannel": "250 250 249",
"hslChannel": "60 9.1% 97.8%"
},
@@ -390,6 +437,7 @@
"hex": "#f5f5f4",
"rgb": "rgb(245,245,244)",
"hsl": "hsl(60,4.8%,95.9%)",
+ "oklch": "oklch(0.97,0.00,106)",
"rgbChannel": "245 245 244",
"hslChannel": "60 4.8% 95.9%"
},
@@ -398,6 +446,7 @@
"hex": "#e7e5e4",
"rgb": "rgb(231,229,228)",
"hsl": "hsl(20,5.9%,90%)",
+ "oklch": "oklch(0.92,0.00,49)",
"rgbChannel": "231 229 228",
"hslChannel": "20 5.9% 90%"
},
@@ -406,6 +455,7 @@
"hex": "#d6d3d1",
"rgb": "rgb(214,211,209)",
"hsl": "hsl(24,5.7%,82.9%)",
+ "oklch": "oklch(0.87,0.00,56)",
"rgbChannel": "214 211 209",
"hslChannel": "24 5.7% 82.9%"
},
@@ -414,6 +464,7 @@
"hex": "#a8a29e",
"rgb": "rgb(168,162,158)",
"hsl": "hsl(24,5.4%,63.9%)",
+ "oklch": "oklch(0.72,0.01,56)",
"rgbChannel": "168 162 158",
"hslChannel": "24 5.4% 63.9%"
},
@@ -422,6 +473,7 @@
"hex": "#78716c",
"rgb": "rgb(120,113,108)",
"hsl": "hsl(25,5.3%,44.7%)",
+ "oklch": "oklch(0.55,0.01,58)",
"rgbChannel": "120 113 108",
"hslChannel": "25 5.3% 44.7%"
},
@@ -430,6 +482,7 @@
"hex": "#57534e",
"rgb": "rgb(87,83,78)",
"hsl": "hsl(33.3,5.5%,32.4%)",
+ "oklch": "oklch(0.44,0.01,74)",
"rgbChannel": "87 83 78",
"hslChannel": "33.3 5.5% 32.4%"
},
@@ -438,6 +491,7 @@
"hex": "#44403c",
"rgb": "rgb(68,64,60)",
"hsl": "hsl(30,6.3%,25.1%)",
+ "oklch": "oklch(0.37,0.01,68)",
"rgbChannel": "68 64 60",
"hslChannel": "30 6.3% 25.1%"
},
@@ -446,6 +500,7 @@
"hex": "#292524",
"rgb": "rgb(41,37,36)",
"hsl": "hsl(12,6.5%,15.1%)",
+ "oklch": "oklch(0.27,0.01,34)",
"rgbChannel": "41 37 36",
"hslChannel": "12 6.5% 15.1%"
},
@@ -454,6 +509,7 @@
"hex": "#1c1917",
"rgb": "rgb(28,25,23)",
"hsl": "hsl(24,9.8%,10%)",
+ "oklch": "oklch(0.22,0.01,56)",
"rgbChannel": "28 25 23",
"hslChannel": "24 9.8% 10%"
},
@@ -462,6 +518,7 @@
"hex": "#0c0a09",
"rgb": "rgb(12,10,9)",
"hsl": "hsl(20,14.3%,4.1%)",
+ "oklch": "oklch(0.15,0.00,49)",
"rgbChannel": "12 10 9",
"hslChannel": "20 14.3% 4.1%"
}
@@ -472,6 +529,7 @@
"hex": "#fef2f2",
"rgb": "rgb(254,242,242)",
"hsl": "hsl(0,85.7%,97.3%)",
+ "oklch": "oklch(0.97,0.01,17)",
"rgbChannel": "254 242 242",
"hslChannel": "0 85.7% 97.3%"
},
@@ -480,6 +538,7 @@
"hex": "#fee2e2",
"rgb": "rgb(254,226,226)",
"hsl": "hsl(0,93.3%,94.1%)",
+ "oklch": "oklch(0.94,0.03,18)",
"rgbChannel": "254 226 226",
"hslChannel": "0 93.3% 94.1%"
},
@@ -488,6 +547,7 @@
"hex": "#fecaca",
"rgb": "rgb(254,202,202)",
"hsl": "hsl(0,96.3%,89.4%)",
+ "oklch": "oklch(0.88,0.06,18)",
"rgbChannel": "254 202 202",
"hslChannel": "0 96.3% 89.4%"
},
@@ -496,6 +556,7 @@
"hex": "#fca5a5",
"rgb": "rgb(252,165,165)",
"hsl": "hsl(0,93.5%,81.8%)",
+ "oklch": "oklch(0.81,0.10,20)",
"rgbChannel": "252 165 165",
"hslChannel": "0 93.5% 81.8%"
},
@@ -504,6 +565,7 @@
"hex": "#f87171",
"rgb": "rgb(248,113,113)",
"hsl": "hsl(0,90.6%,70.8%)",
+ "oklch": "oklch(0.71,0.17,22)",
"rgbChannel": "248 113 113",
"hslChannel": "0 90.6% 70.8%"
},
@@ -512,6 +574,7 @@
"hex": "#ef4444",
"rgb": "rgb(239,68,68)",
"hsl": "hsl(0,84.2%,60.2%)",
+ "oklch": "oklch(0.64,0.21,25)",
"rgbChannel": "239 68 68",
"hslChannel": "0 84.2% 60.2%"
},
@@ -520,6 +583,7 @@
"hex": "#dc2626",
"rgb": "rgb(220,38,38)",
"hsl": "hsl(0,72.2%,50.6%)",
+ "oklch": "oklch(0.58,0.22,27)",
"rgbChannel": "220 38 38",
"hslChannel": "0 72.2% 50.6%"
},
@@ -528,6 +592,7 @@
"hex": "#b91c1c",
"rgb": "rgb(185,28,28)",
"hsl": "hsl(0,73.7%,41.8%)",
+ "oklch": "oklch(0.51,0.19,28)",
"rgbChannel": "185 28 28",
"hslChannel": "0 73.7% 41.8%"
},
@@ -536,6 +601,7 @@
"hex": "#991b1b",
"rgb": "rgb(153,27,27)",
"hsl": "hsl(0,70%,35.3%)",
+ "oklch": "oklch(0.44,0.16,27)",
"rgbChannel": "153 27 27",
"hslChannel": "0 70% 35.3%"
},
@@ -544,6 +610,7 @@
"hex": "#7f1d1d",
"rgb": "rgb(127,29,29)",
"hsl": "hsl(0,62.8%,30.6%)",
+ "oklch": "oklch(0.40,0.13,26)",
"rgbChannel": "127 29 29",
"hslChannel": "0 62.8% 30.6%"
},
@@ -552,6 +619,7 @@
"hex": "#450a0a",
"rgb": "rgb(69,10,10)",
"hsl": "hsl(0,74.7%,15.5%)",
+ "oklch": "oklch(0.26,0.09,26)",
"rgbChannel": "69 10 10",
"hslChannel": "0 74.7% 15.5%"
}
@@ -562,6 +630,7 @@
"hex": "#fff7ed",
"rgb": "rgb(255,247,237)",
"hsl": "hsl(33.3,100%,96.5%)",
+ "oklch": "oklch(0.98,0.02,74)",
"rgbChannel": "255 247 237",
"hslChannel": "33.3 100% 96.5%"
},
@@ -570,6 +639,7 @@
"hex": "#ffedd5",
"rgb": "rgb(255,237,213)",
"hsl": "hsl(34.3,100%,91.8%)",
+ "oklch": "oklch(0.95,0.04,75)",
"rgbChannel": "255 237 213",
"hslChannel": "34.3 100% 91.8%"
},
@@ -578,6 +648,7 @@
"hex": "#fed7aa",
"rgb": "rgb(254,215,170)",
"hsl": "hsl(32.1,97.7%,83.1%)",
+ "oklch": "oklch(0.90,0.07,71)",
"rgbChannel": "254 215 170",
"hslChannel": "32.1 97.7% 83.1%"
},
@@ -586,6 +657,7 @@
"hex": "#fdba74",
"rgb": "rgb(253,186,116)",
"hsl": "hsl(30.7,97.2%,72.4%)",
+ "oklch": "oklch(0.84,0.12,66)",
"rgbChannel": "253 186 116",
"hslChannel": "30.7 97.2% 72.4%"
},
@@ -594,6 +666,7 @@
"hex": "#fb923c",
"rgb": "rgb(251,146,60)",
"hsl": "hsl(27,96%,61%)",
+ "oklch": "oklch(0.76,0.16,56)",
"rgbChannel": "251 146 60",
"hslChannel": "27 96% 61%"
},
@@ -602,6 +675,7 @@
"hex": "#f97316",
"rgb": "rgb(249,115,22)",
"hsl": "hsl(24.6,95%,53.1%)",
+ "oklch": "oklch(0.70,0.19,48)",
"rgbChannel": "249 115 22",
"hslChannel": "24.6 95% 53.1%"
},
@@ -610,6 +684,7 @@
"hex": "#ea580c",
"rgb": "rgb(234,88,12)",
"hsl": "hsl(20.5,90.2%,48.2%)",
+ "oklch": "oklch(0.65,0.19,41)",
"rgbChannel": "234 88 12",
"hslChannel": "20.5 90.2% 48.2%"
},
@@ -618,6 +693,7 @@
"hex": "#c2410c",
"rgb": "rgb(194,65,12)",
"hsl": "hsl(17.5,88.3%,40.4%)",
+ "oklch": "oklch(0.55,0.17,38)",
"rgbChannel": "194 65 12",
"hslChannel": "17.5 88.3% 40.4%"
},
@@ -626,6 +702,7 @@
"hex": "#9a3412",
"rgb": "rgb(154,52,18)",
"hsl": "hsl(15,79.1%,33.7%)",
+ "oklch": "oklch(0.47,0.14,37)",
"rgbChannel": "154 52 18",
"hslChannel": "15 79.1% 33.7%"
},
@@ -634,6 +711,7 @@
"hex": "#7c2d12",
"rgb": "rgb(124,45,18)",
"hsl": "hsl(15.3,74.6%,27.8%)",
+ "oklch": "oklch(0.41,0.12,38)",
"rgbChannel": "124 45 18",
"hslChannel": "15.3 74.6% 27.8%"
},
@@ -642,6 +720,7 @@
"hex": "#431407",
"rgb": "rgb(67,20,7)",
"hsl": "hsl(13,81.1%,14.5%)",
+ "oklch": "oklch(0.27,0.08,36)",
"rgbChannel": "67 20 7",
"hslChannel": "13 81.1% 14.5%"
}
@@ -652,6 +731,7 @@
"hex": "#fffbeb",
"rgb": "rgb(255,251,235)",
"hsl": "hsl(48,100%,96.1%)",
+ "oklch": "oklch(0.99,0.02,95)",
"rgbChannel": "255 251 235",
"hslChannel": "48 100% 96.1%"
},
@@ -660,6 +740,7 @@
"hex": "#fef3c7",
"rgb": "rgb(254,243,199)",
"hsl": "hsl(48,96.5%,88.8%)",
+ "oklch": "oklch(0.96,0.06,96)",
"rgbChannel": "254 243 199",
"hslChannel": "48 96.5% 88.8%"
},
@@ -668,6 +749,7 @@
"hex": "#fde68a",
"rgb": "rgb(253,230,138)",
"hsl": "hsl(48,96.6%,76.7%)",
+ "oklch": "oklch(0.92,0.12,96)",
"rgbChannel": "253 230 138",
"hslChannel": "48 96.6% 76.7%"
},
@@ -676,6 +758,7 @@
"hex": "#fcd34d",
"rgb": "rgb(252,211,77)",
"hsl": "hsl(45.9,96.7%,64.5%)",
+ "oklch": "oklch(0.88,0.15,92)",
"rgbChannel": "252 211 77",
"hslChannel": "45.9 96.7% 64.5%"
},
@@ -684,6 +767,7 @@
"hex": "#fbbf24",
"rgb": "rgb(251,191,36)",
"hsl": "hsl(43.3,96.4%,56.3%)",
+ "oklch": "oklch(0.84,0.16,84)",
"rgbChannel": "251 191 36",
"hslChannel": "43.3 96.4% 56.3%"
},
@@ -692,6 +776,7 @@
"hex": "#f59e0b",
"rgb": "rgb(245,158,11)",
"hsl": "hsl(37.7,92.1%,50.2%)",
+ "oklch": "oklch(0.77,0.16,70)",
"rgbChannel": "245 158 11",
"hslChannel": "37.7 92.1% 50.2%"
},
@@ -700,6 +785,7 @@
"hex": "#d97706",
"rgb": "rgb(217,119,6)",
"hsl": "hsl(32.1,94.6%,43.7%)",
+ "oklch": "oklch(0.67,0.16,58)",
"rgbChannel": "217 119 6",
"hslChannel": "32.1 94.6% 43.7%"
},
@@ -708,6 +794,7 @@
"hex": "#b45309",
"rgb": "rgb(180,83,9)",
"hsl": "hsl(26,90.5%,37.1%)",
+ "oklch": "oklch(0.56,0.15,49)",
"rgbChannel": "180 83 9",
"hslChannel": "26 90.5% 37.1%"
},
@@ -716,6 +803,7 @@
"hex": "#92400e",
"rgb": "rgb(146,64,14)",
"hsl": "hsl(22.7,82.5%,31.4%)",
+ "oklch": "oklch(0.47,0.12,46)",
"rgbChannel": "146 64 14",
"hslChannel": "22.7 82.5% 31.4%"
},
@@ -724,6 +812,7 @@
"hex": "#78350f",
"rgb": "rgb(120,53,15)",
"hsl": "hsl(21.7,77.8%,26.5%)",
+ "oklch": "oklch(0.41,0.11,46)",
"rgbChannel": "120 53 15",
"hslChannel": "21.7 77.8% 26.5%"
},
@@ -732,6 +821,7 @@
"hex": "#451a03",
"rgb": "rgb(69,26,3)",
"hsl": "hsl(20.9,91.7%,14.1%)",
+ "oklch": "oklch(0.28,0.07,46)",
"rgbChannel": "69 26 3",
"hslChannel": "20.9 91.7% 14.1%"
}
@@ -742,6 +832,7 @@
"hex": "#fefce8",
"rgb": "rgb(254,252,232)",
"hsl": "hsl(54.5,91.7%,95.3%)",
+ "oklch": "oklch(0.99,0.03,102)",
"rgbChannel": "254 252 232",
"hslChannel": "54.5 91.7% 95.3%"
},
@@ -750,6 +841,7 @@
"hex": "#fef9c3",
"rgb": "rgb(254,249,195)",
"hsl": "hsl(54.9,96.7%,88%)",
+ "oklch": "oklch(0.97,0.07,103)",
"rgbChannel": "254 249 195",
"hslChannel": "54.9 96.7% 88%"
},
@@ -758,6 +850,7 @@
"hex": "#fef08a",
"rgb": "rgb(254,240,138)",
"hsl": "hsl(52.8,98.3%,76.9%)",
+ "oklch": "oklch(0.95,0.12,102)",
"rgbChannel": "254 240 138",
"hslChannel": "52.8 98.3% 76.9%"
},
@@ -766,6 +859,7 @@
"hex": "#fde047",
"rgb": "rgb(253,224,71)",
"hsl": "hsl(50.4,97.8%,63.5%)",
+ "oklch": "oklch(0.91,0.17,98)",
"rgbChannel": "253 224 71",
"hslChannel": "50.4 97.8% 63.5%"
},
@@ -774,6 +868,7 @@
"hex": "#facc15",
"rgb": "rgb(250,204,21)",
"hsl": "hsl(47.9,95.8%,53.1%)",
+ "oklch": "oklch(0.86,0.17,92)",
"rgbChannel": "250 204 21",
"hslChannel": "47.9 95.8% 53.1%"
},
@@ -782,6 +877,7 @@
"hex": "#eab308",
"rgb": "rgb(234,179,8)",
"hsl": "hsl(45.4,93.4%,47.5%)",
+ "oklch": "oklch(0.80,0.16,86)",
"rgbChannel": "234 179 8",
"hslChannel": "45.4 93.4% 47.5%"
},
@@ -790,6 +886,7 @@
"hex": "#ca8a04",
"rgb": "rgb(202,138,4)",
"hsl": "hsl(40.6,96.1%,40.4%)",
+ "oklch": "oklch(0.68,0.14,76)",
"rgbChannel": "202 138 4",
"hslChannel": "40.6 96.1% 40.4%"
},
@@ -798,6 +895,7 @@
"hex": "#a16207",
"rgb": "rgb(161,98,7)",
"hsl": "hsl(35.5,91.7%,32.9%)",
+ "oklch": "oklch(0.55,0.12,66)",
"rgbChannel": "161 98 7",
"hslChannel": "35.5 91.7% 32.9%"
},
@@ -806,6 +904,7 @@
"hex": "#854d0e",
"rgb": "rgb(133,77,14)",
"hsl": "hsl(31.8,81%,28.8%)",
+ "oklch": "oklch(0.48,0.10,62)",
"rgbChannel": "133 77 14",
"hslChannel": "31.8 81% 28.8%"
},
@@ -814,6 +913,7 @@
"hex": "#713f12",
"rgb": "rgb(113,63,18)",
"hsl": "hsl(28.4,72.5%,25.7%)",
+ "oklch": "oklch(0.42,0.09,58)",
"rgbChannel": "113 63 18",
"hslChannel": "28.4 72.5% 25.7%"
},
@@ -822,6 +922,7 @@
"hex": "#422006",
"rgb": "rgb(66,32,6)",
"hsl": "hsl(26,83.3%,14.1%)",
+ "oklch": "oklch(0.29,0.06,54)",
"rgbChannel": "66 32 6",
"hslChannel": "26 83.3% 14.1%"
}
@@ -832,6 +933,7 @@
"hex": "#f7fee7",
"rgb": "rgb(247,254,231)",
"hsl": "hsl(78.3,92%,95.1%)",
+ "oklch": "oklch(0.99,0.03,121)",
"rgbChannel": "247 254 231",
"hslChannel": "78.3 92% 95.1%"
},
@@ -840,6 +942,7 @@
"hex": "#ecfccb",
"rgb": "rgb(236,252,203)",
"hsl": "hsl(79.6,89.1%,89.2%)",
+ "oklch": "oklch(0.97,0.07,122)",
"rgbChannel": "236 252 203",
"hslChannel": "79.6 89.1% 89.2%"
},
@@ -848,6 +951,7 @@
"hex": "#d9f99d",
"rgb": "rgb(217,249,157)",
"hsl": "hsl(80.9,88.5%,79.6%)",
+ "oklch": "oklch(0.94,0.12,124)",
"rgbChannel": "217 249 157",
"hslChannel": "80.9 88.5% 79.6%"
},
@@ -856,6 +960,7 @@
"hex": "#bef264",
"rgb": "rgb(190,242,100)",
"hsl": "hsl(82,84.5%,67.1%)",
+ "oklch": "oklch(0.90,0.18,127)",
"rgbChannel": "190 242 100",
"hslChannel": "82 84.5% 67.1%"
},
@@ -864,6 +969,7 @@
"hex": "#a3e635",
"rgb": "rgb(163,230,53)",
"hsl": "hsl(82.7,78%,55.5%)",
+ "oklch": "oklch(0.85,0.21,129)",
"rgbChannel": "163 230 53",
"hslChannel": "82.7 78% 55.5%"
},
@@ -872,6 +978,7 @@
"hex": "#84cc16",
"rgb": "rgb(132,204,22)",
"hsl": "hsl(83.7,80.5%,44.3%)",
+ "oklch": "oklch(0.77,0.20,131)",
"rgbChannel": "132 204 22",
"hslChannel": "83.7 80.5% 44.3%"
},
@@ -880,6 +987,7 @@
"hex": "#65a30d",
"rgb": "rgb(101,163,13)",
"hsl": "hsl(84.8,85.2%,34.5%)",
+ "oklch": "oklch(0.65,0.18,132)",
"rgbChannel": "101 163 13",
"hslChannel": "84.8 85.2% 34.5%"
},
@@ -888,6 +996,7 @@
"hex": "#4d7c0f",
"rgb": "rgb(77,124,15)",
"hsl": "hsl(85.9,78.4%,27.3%)",
+ "oklch": "oklch(0.53,0.14,132)",
"rgbChannel": "77 124 15",
"hslChannel": "85.9 78.4% 27.3%"
},
@@ -896,6 +1005,7 @@
"hex": "#3f6212",
"rgb": "rgb(63,98,18)",
"hsl": "hsl(86.3,69%,22.7%)",
+ "oklch": "oklch(0.45,0.11,131)",
"rgbChannel": "63 98 18",
"hslChannel": "86.3 69% 22.7%"
},
@@ -904,6 +1014,7 @@
"hex": "#365314",
"rgb": "rgb(54,83,20)",
"hsl": "hsl(87.6,61.2%,20.2%)",
+ "oklch": "oklch(0.41,0.10,131)",
"rgbChannel": "54 83 20",
"hslChannel": "87.6 61.2% 20.2%"
},
@@ -912,6 +1023,7 @@
"hex": "#1a2e05",
"rgb": "rgb(26,46,5)",
"hsl": "hsl(89.3,80.4%,10%)",
+ "oklch": "oklch(0.27,0.07,132)",
"rgbChannel": "26 46 5",
"hslChannel": "89.3 80.4% 10%"
}
@@ -922,6 +1034,7 @@
"hex": "#f0fdf4",
"rgb": "rgb(240,253,244)",
"hsl": "hsl(138.5,76.5%,96.7%)",
+ "oklch": "oklch(0.98,0.02,156)",
"rgbChannel": "240 253 244",
"hslChannel": "138.5 76.5% 96.7%"
},
@@ -930,6 +1043,7 @@
"hex": "#dcfce7",
"rgb": "rgb(220,252,231)",
"hsl": "hsl(140.6,84.2%,92.5%)",
+ "oklch": "oklch(0.96,0.04,157)",
"rgbChannel": "220 252 231",
"hslChannel": "140.6 84.2% 92.5%"
},
@@ -938,6 +1052,7 @@
"hex": "#bbf7d0",
"rgb": "rgb(187,247,208)",
"hsl": "hsl(141,78.9%,85.1%)",
+ "oklch": "oklch(0.93,0.08,156)",
"rgbChannel": "187 247 208",
"hslChannel": "141 78.9% 85.1%"
},
@@ -946,6 +1061,7 @@
"hex": "#86efac",
"rgb": "rgb(134,239,172)",
"hsl": "hsl(141.7,76.6%,73.1%)",
+ "oklch": "oklch(0.87,0.14,154)",
"rgbChannel": "134 239 172",
"hslChannel": "141.7 76.6% 73.1%"
},
@@ -954,6 +1070,7 @@
"hex": "#4ade80",
"rgb": "rgb(74,222,128)",
"hsl": "hsl(141.9,69.2%,58%)",
+ "oklch": "oklch(0.80,0.18,152)",
"rgbChannel": "74 222 128",
"hslChannel": "141.9 69.2% 58%"
},
@@ -962,6 +1079,7 @@
"hex": "#22c55e",
"rgb": "rgb(34,197,94)",
"hsl": "hsl(142.1,70.6%,45.3%)",
+ "oklch": "oklch(0.72,0.19,150)",
"rgbChannel": "34 197 94",
"hslChannel": "142.1 70.6% 45.3%"
},
@@ -970,6 +1088,7 @@
"hex": "#16a34a",
"rgb": "rgb(22,163,74)",
"hsl": "hsl(142.1,76.2%,36.3%)",
+ "oklch": "oklch(0.63,0.17,149)",
"rgbChannel": "22 163 74",
"hslChannel": "142.1 76.2% 36.3%"
},
@@ -978,6 +1097,7 @@
"hex": "#15803d",
"rgb": "rgb(21,128,61)",
"hsl": "hsl(142.4,71.8%,29.2%)",
+ "oklch": "oklch(0.53,0.14,150)",
"rgbChannel": "21 128 61",
"hslChannel": "142.4 71.8% 29.2%"
},
@@ -986,6 +1106,7 @@
"hex": "#166534",
"rgb": "rgb(22,101,52)",
"hsl": "hsl(142.8,64.2%,24.1%)",
+ "oklch": "oklch(0.45,0.11,151)",
"rgbChannel": "22 101 52",
"hslChannel": "142.8 64.2% 24.1%"
},
@@ -994,6 +1115,7 @@
"hex": "#14532d",
"rgb": "rgb(20,83,45)",
"hsl": "hsl(143.8,61.2%,20.2%)",
+ "oklch": "oklch(0.39,0.09,153)",
"rgbChannel": "20 83 45",
"hslChannel": "143.8 61.2% 20.2%"
},
@@ -1002,6 +1124,7 @@
"hex": "#052e16",
"rgb": "rgb(5,46,22)",
"hsl": "hsl(144.9,80.4%,10%)",
+ "oklch": "oklch(0.27,0.06,153)",
"rgbChannel": "5 46 22",
"hslChannel": "144.9 80.4% 10%"
}
@@ -1012,6 +1135,7 @@
"hex": "#ecfdf5",
"rgb": "rgb(236,253,245)",
"hsl": "hsl(151.8,81%,95.9%)",
+ "oklch": "oklch(0.98,0.02,166)",
"rgbChannel": "236 253 245",
"hslChannel": "151.8 81% 95.9%"
},
@@ -1020,6 +1144,7 @@
"hex": "#d1fae5",
"rgb": "rgb(209,250,229)",
"hsl": "hsl(149.3,80.4%,90%)",
+ "oklch": "oklch(0.95,0.05,163)",
"rgbChannel": "209 250 229",
"hslChannel": "149.3 80.4% 90%"
},
@@ -1028,6 +1153,7 @@
"hex": "#a7f3d0",
"rgb": "rgb(167,243,208)",
"hsl": "hsl(152.4,76%,80.4%)",
+ "oklch": "oklch(0.90,0.09,164)",
"rgbChannel": "167 243 208",
"hslChannel": "152.4 76% 80.4%"
},
@@ -1036,6 +1162,7 @@
"hex": "#6ee7b7",
"rgb": "rgb(110,231,183)",
"hsl": "hsl(156.2,71.6%,66.9%)",
+ "oklch": "oklch(0.85,0.13,165)",
"rgbChannel": "110 231 183",
"hslChannel": "156.2 71.6% 66.9%"
},
@@ -1044,6 +1171,7 @@
"hex": "#34d399",
"rgb": "rgb(52,211,153)",
"hsl": "hsl(158.1,64.4%,51.6%)",
+ "oklch": "oklch(0.77,0.15,163)",
"rgbChannel": "52 211 153",
"hslChannel": "158.1 64.4% 51.6%"
},
@@ -1052,6 +1180,7 @@
"hex": "#10b981",
"rgb": "rgb(16,185,129)",
"hsl": "hsl(160.1,84.1%,39.4%)",
+ "oklch": "oklch(0.70,0.15,162)",
"rgbChannel": "16 185 129",
"hslChannel": "160.1 84.1% 39.4%"
},
@@ -1060,6 +1189,7 @@
"hex": "#059669",
"rgb": "rgb(5,150,105)",
"hsl": "hsl(161.4,93.5%,30.4%)",
+ "oklch": "oklch(0.60,0.13,163)",
"rgbChannel": "5 150 105",
"hslChannel": "161.4 93.5% 30.4%"
},
@@ -1068,6 +1198,7 @@
"hex": "#047857",
"rgb": "rgb(4,120,87)",
"hsl": "hsl(162.9,93.5%,24.3%)",
+ "oklch": "oklch(0.51,0.10,166)",
"rgbChannel": "4 120 87",
"hslChannel": "162.9 93.5% 24.3%"
},
@@ -1076,6 +1207,7 @@
"hex": "#065f46",
"rgb": "rgb(6,95,70)",
"hsl": "hsl(163.1,88.1%,19.8%)",
+ "oklch": "oklch(0.43,0.09,167)",
"rgbChannel": "6 95 70",
"hslChannel": "163.1 88.1% 19.8%"
},
@@ -1084,6 +1216,7 @@
"hex": "#064e3b",
"rgb": "rgb(6,78,59)",
"hsl": "hsl(164.2,85.7%,16.5%)",
+ "oklch": "oklch(0.38,0.07,169)",
"rgbChannel": "6 78 59",
"hslChannel": "164.2 85.7% 16.5%"
},
@@ -1092,6 +1225,7 @@
"hex": "#022c22",
"rgb": "rgb(2,44,34)",
"hsl": "hsl(165.7,91.3%,9%)",
+ "oklch": "oklch(0.26,0.05,173)",
"rgbChannel": "2 44 34",
"hslChannel": "165.7 91.3% 9%"
}
@@ -1102,6 +1236,7 @@
"hex": "#f0fdfa",
"rgb": "rgb(240,253,250)",
"hsl": "hsl(166.2,76.5%,96.7%)",
+ "oklch": "oklch(0.98,0.01,181)",
"rgbChannel": "240 253 250",
"hslChannel": "166.2 76.5% 96.7%"
},
@@ -1110,6 +1245,7 @@
"hex": "#ccfbf1",
"rgb": "rgb(204,251,241)",
"hsl": "hsl(167.2,85.5%,89.2%)",
+ "oklch": "oklch(0.95,0.05,181)",
"rgbChannel": "204 251 241",
"hslChannel": "167.2 85.5% 89.2%"
},
@@ -1118,6 +1254,7 @@
"hex": "#99f6e4",
"rgb": "rgb(153,246,228)",
"hsl": "hsl(168.4,83.8%,78.2%)",
+ "oklch": "oklch(0.91,0.09,180)",
"rgbChannel": "153 246 228",
"hslChannel": "168.4 83.8% 78.2%"
},
@@ -1126,6 +1263,7 @@
"hex": "#5eead4",
"rgb": "rgb(94,234,212)",
"hsl": "hsl(170.6,76.9%,64.3%)",
+ "oklch": "oklch(0.85,0.13,181)",
"rgbChannel": "94 234 212",
"hslChannel": "170.6 76.9% 64.3%"
},
@@ -1134,6 +1272,7 @@
"hex": "#2dd4bf",
"rgb": "rgb(45,212,191)",
"hsl": "hsl(172.5,66%,50.4%)",
+ "oklch": "oklch(0.78,0.13,182)",
"rgbChannel": "45 212 191",
"hslChannel": "172.5 66% 50.4%"
},
@@ -1142,6 +1281,7 @@
"hex": "#14b8a6",
"rgb": "rgb(20,184,166)",
"hsl": "hsl(173.4,80.4%,40%)",
+ "oklch": "oklch(0.70,0.12,183)",
"rgbChannel": "20 184 166",
"hslChannel": "173.4 80.4% 40%"
},
@@ -1150,6 +1290,7 @@
"hex": "#0d9488",
"rgb": "rgb(13,148,136)",
"hsl": "hsl(174.7,83.9%,31.6%)",
+ "oklch": "oklch(0.60,0.10,185)",
"rgbChannel": "13 148 136",
"hslChannel": "174.7 83.9% 31.6%"
},
@@ -1158,6 +1299,7 @@
"hex": "#0f766e",
"rgb": "rgb(15,118,110)",
"hsl": "hsl(175.3,77.4%,26.1%)",
+ "oklch": "oklch(0.51,0.09,186)",
"rgbChannel": "15 118 110",
"hslChannel": "175.3 77.4% 26.1%"
},
@@ -1166,6 +1308,7 @@
"hex": "#115e59",
"rgb": "rgb(17,94,89)",
"hsl": "hsl(176.1,69.4%,21.8%)",
+ "oklch": "oklch(0.44,0.07,188)",
"rgbChannel": "17 94 89",
"hslChannel": "176.1 69.4% 21.8%"
},
@@ -1174,6 +1317,7 @@
"hex": "#134e4a",
"rgb": "rgb(19,78,74)",
"hsl": "hsl(175.9,60.8%,19%)",
+ "oklch": "oklch(0.39,0.06,188)",
"rgbChannel": "19 78 74",
"hslChannel": "175.9 60.8% 19%"
},
@@ -1182,6 +1326,7 @@
"hex": "#042f2e",
"rgb": "rgb(4,47,46)",
"hsl": "hsl(178.6,84.3%,10%)",
+ "oklch": "oklch(0.28,0.04,193)",
"rgbChannel": "4 47 46",
"hslChannel": "178.6 84.3% 10%"
}
@@ -1192,6 +1337,7 @@
"hex": "#ecfeff",
"rgb": "rgb(236,254,255)",
"hsl": "hsl(183.2,100%,96.3%)",
+ "oklch": "oklch(0.98,0.02,201)",
"rgbChannel": "236 254 255",
"hslChannel": "183.2 100% 96.3%"
},
@@ -1200,6 +1346,7 @@
"hex": "#cffafe",
"rgb": "rgb(207,250,254)",
"hsl": "hsl(185.1,95.9%,90.4%)",
+ "oklch": "oklch(0.96,0.04,203)",
"rgbChannel": "207 250 254",
"hslChannel": "185.1 95.9% 90.4%"
},
@@ -1208,6 +1355,7 @@
"hex": "#a5f3fc",
"rgb": "rgb(165,243,252)",
"hsl": "hsl(186.2,93.5%,81.8%)",
+ "oklch": "oklch(0.92,0.08,205)",
"rgbChannel": "165 243 252",
"hslChannel": "186.2 93.5% 81.8%"
},
@@ -1216,6 +1364,7 @@
"hex": "#67e8f9",
"rgb": "rgb(103,232,249)",
"hsl": "hsl(187,92.4%,69%)",
+ "oklch": "oklch(0.87,0.12,207)",
"rgbChannel": "103 232 249",
"hslChannel": "187 92.4% 69%"
},
@@ -1224,6 +1373,7 @@
"hex": "#22d3ee",
"rgb": "rgb(34,211,238)",
"hsl": "hsl(187.9,85.7%,53.3%)",
+ "oklch": "oklch(0.80,0.13,212)",
"rgbChannel": "34 211 238",
"hslChannel": "187.9 85.7% 53.3%"
},
@@ -1232,6 +1382,7 @@
"hex": "#06b6d4",
"rgb": "rgb(6,182,212)",
"hsl": "hsl(188.7,94.5%,42.7%)",
+ "oklch": "oklch(0.71,0.13,215)",
"rgbChannel": "6 182 212",
"hslChannel": "188.7 94.5% 42.7%"
},
@@ -1240,6 +1391,7 @@
"hex": "#0891b2",
"rgb": "rgb(8,145,178)",
"hsl": "hsl(191.6,91.4%,36.5%)",
+ "oklch": "oklch(0.61,0.11,222)",
"rgbChannel": "8 145 178",
"hslChannel": "191.6 91.4% 36.5%"
},
@@ -1248,6 +1400,7 @@
"hex": "#0e7490",
"rgb": "rgb(14,116,144)",
"hsl": "hsl(192.9,82.3%,31%)",
+ "oklch": "oklch(0.52,0.09,223)",
"rgbChannel": "14 116 144",
"hslChannel": "192.9 82.3% 31%"
},
@@ -1256,6 +1409,7 @@
"hex": "#155e75",
"rgb": "rgb(21,94,117)",
"hsl": "hsl(194.4,69.6%,27.1%)",
+ "oklch": "oklch(0.45,0.08,224)",
"rgbChannel": "21 94 117",
"hslChannel": "194.4 69.6% 27.1%"
},
@@ -1264,6 +1418,7 @@
"hex": "#164e63",
"rgb": "rgb(22,78,99)",
"hsl": "hsl(196.4,63.6%,23.7%)",
+ "oklch": "oklch(0.40,0.07,227)",
"rgbChannel": "22 78 99",
"hslChannel": "196.4 63.6% 23.7%"
},
@@ -1272,6 +1427,7 @@
"hex": "#083344",
"rgb": "rgb(8,51,68)",
"hsl": "hsl(197,78.9%,14.9%)",
+ "oklch": "oklch(0.30,0.05,230)",
"rgbChannel": "8 51 68",
"hslChannel": "197 78.9% 14.9%"
}
@@ -1282,6 +1438,7 @@
"hex": "#f0f9ff",
"rgb": "rgb(240,249,255)",
"hsl": "hsl(204,100%,97.1%)",
+ "oklch": "oklch(0.98,0.01,237)",
"rgbChannel": "240 249 255",
"hslChannel": "204 100% 97.1%"
},
@@ -1290,6 +1447,7 @@
"hex": "#e0f2fe",
"rgb": "rgb(224,242,254)",
"hsl": "hsl(204,93.8%,93.7%)",
+ "oklch": "oklch(0.95,0.03,237)",
"rgbChannel": "224 242 254",
"hslChannel": "204 93.8% 93.7%"
},
@@ -1298,6 +1456,7 @@
"hex": "#bae6fd",
"rgb": "rgb(186,230,253)",
"hsl": "hsl(200.6,94.4%,86.1%)",
+ "oklch": "oklch(0.90,0.06,231)",
"rgbChannel": "186 230 253",
"hslChannel": "200.6 94.4% 86.1%"
},
@@ -1306,6 +1465,7 @@
"hex": "#7dd3fc",
"rgb": "rgb(125,211,252)",
"hsl": "hsl(199.4,95.5%,73.9%)",
+ "oklch": "oklch(0.83,0.10,230)",
"rgbChannel": "125 211 252",
"hslChannel": "199.4 95.5% 73.9%"
},
@@ -1314,6 +1474,7 @@
"hex": "#38bdf8",
"rgb": "rgb(56,189,248)",
"hsl": "hsl(198.4,93.2%,59.6%)",
+ "oklch": "oklch(0.75,0.14,233)",
"rgbChannel": "56 189 248",
"hslChannel": "198.4 93.2% 59.6%"
},
@@ -1322,6 +1483,7 @@
"hex": "#0ea5e9",
"rgb": "rgb(14,165,233)",
"hsl": "hsl(198.6,88.7%,48.4%)",
+ "oklch": "oklch(0.68,0.15,237)",
"rgbChannel": "14 165 233",
"hslChannel": "198.6 88.7% 48.4%"
},
@@ -1330,6 +1492,7 @@
"hex": "#0284c7",
"rgb": "rgb(2,132,199)",
"hsl": "hsl(200.4,98%,39.4%)",
+ "oklch": "oklch(0.59,0.14,242)",
"rgbChannel": "2 132 199",
"hslChannel": "200.4 98% 39.4%"
},
@@ -1338,6 +1501,7 @@
"hex": "#0369a1",
"rgb": "rgb(3,105,161)",
"hsl": "hsl(201.3,96.3%,32.2%)",
+ "oklch": "oklch(0.50,0.12,243)",
"rgbChannel": "3 105 161",
"hslChannel": "201.3 96.3% 32.2%"
},
@@ -1346,6 +1510,7 @@
"hex": "#075985",
"rgb": "rgb(7,89,133)",
"hsl": "hsl(201,90%,27.5%)",
+ "oklch": "oklch(0.44,0.10,241)",
"rgbChannel": "7 89 133",
"hslChannel": "201 90% 27.5%"
},
@@ -1354,6 +1519,7 @@
"hex": "#0c4a6e",
"rgb": "rgb(12,74,110)",
"hsl": "hsl(202,80.3%,23.9%)",
+ "oklch": "oklch(0.39,0.08,241)",
"rgbChannel": "12 74 110",
"hslChannel": "202 80.3% 23.9%"
},
@@ -1362,6 +1528,7 @@
"hex": "#082f49",
"rgb": "rgb(8,47,73)",
"hsl": "hsl(204,80.2%,15.9%)",
+ "oklch": "oklch(0.29,0.06,243)",
"rgbChannel": "8 47 73",
"hslChannel": "204 80.2% 15.9%"
}
@@ -1372,6 +1539,7 @@
"hex": "#eff6ff",
"rgb": "rgb(239,246,255)",
"hsl": "hsl(213.8,100%,96.9%)",
+ "oklch": "oklch(0.97,0.01,255)",
"rgbChannel": "239 246 255",
"hslChannel": "213.8 100% 96.9%"
},
@@ -1380,6 +1548,7 @@
"hex": "#dbeafe",
"rgb": "rgb(219,234,254)",
"hsl": "hsl(214.3,94.6%,92.7%)",
+ "oklch": "oklch(0.93,0.03,256)",
"rgbChannel": "219 234 254",
"hslChannel": "214.3 94.6% 92.7%"
},
@@ -1388,6 +1557,7 @@
"hex": "#bfdbfe",
"rgb": "rgb(191,219,254)",
"hsl": "hsl(213.3,96.9%,87.3%)",
+ "oklch": "oklch(0.88,0.06,254)",
"rgbChannel": "191 219 254",
"hslChannel": "213.3 96.9% 87.3%"
},
@@ -1396,6 +1566,7 @@
"hex": "#93c5fd",
"rgb": "rgb(147,197,253)",
"hsl": "hsl(211.7,96.4%,78.4%)",
+ "oklch": "oklch(0.81,0.10,252)",
"rgbChannel": "147 197 253",
"hslChannel": "211.7 96.4% 78.4%"
},
@@ -1404,6 +1575,7 @@
"hex": "#60a5fa",
"rgb": "rgb(96,165,250)",
"hsl": "hsl(213.1,93.9%,67.8%)",
+ "oklch": "oklch(0.71,0.14,255)",
"rgbChannel": "96 165 250",
"hslChannel": "213.1 93.9% 67.8%"
},
@@ -1412,6 +1584,7 @@
"hex": "#3b82f6",
"rgb": "rgb(59,130,246)",
"hsl": "hsl(217.2,91.2%,59.8%)",
+ "oklch": "oklch(0.62,0.19,260)",
"rgbChannel": "59 130 246",
"hslChannel": "217.2 91.2% 59.8%"
},
@@ -1420,6 +1593,7 @@
"hex": "#2563eb",
"rgb": "rgb(37,99,235)",
"hsl": "hsl(221.2,83.2%,53.3%)",
+ "oklch": "oklch(0.55,0.22,263)",
"rgbChannel": "37 99 235",
"hslChannel": "221.2 83.2% 53.3%"
},
@@ -1428,6 +1602,7 @@
"hex": "#1d4ed8",
"rgb": "rgb(29,78,216)",
"hsl": "hsl(224.3,76.3%,48%)",
+ "oklch": "oklch(0.49,0.22,264)",
"rgbChannel": "29 78 216",
"hslChannel": "224.3 76.3% 48%"
},
@@ -1436,6 +1611,7 @@
"hex": "#1e40af",
"rgb": "rgb(30,64,175)",
"hsl": "hsl(225.9,70.7%,40.2%)",
+ "oklch": "oklch(0.42,0.18,266)",
"rgbChannel": "30 64 175",
"hslChannel": "225.9 70.7% 40.2%"
},
@@ -1444,6 +1620,7 @@
"hex": "#1e3a8a",
"rgb": "rgb(30,58,138)",
"hsl": "hsl(224.4,64.3%,32.9%)",
+ "oklch": "oklch(0.38,0.14,266)",
"rgbChannel": "30 58 138",
"hslChannel": "224.4 64.3% 32.9%"
},
@@ -1452,6 +1629,7 @@
"hex": "#172554",
"rgb": "rgb(23,37,84)",
"hsl": "hsl(226.2,57%,21%)",
+ "oklch": "oklch(0.28,0.09,268)",
"rgbChannel": "23 37 84",
"hslChannel": "226.2 57% 21%"
}
@@ -1462,6 +1640,7 @@
"hex": "#eef2ff",
"rgb": "rgb(238,242,255)",
"hsl": "hsl(225.9,100%,96.7%)",
+ "oklch": "oklch(0.96,0.02,272)",
"rgbChannel": "238 242 255",
"hslChannel": "225.9 100% 96.7%"
},
@@ -1470,6 +1649,7 @@
"hex": "#e0e7ff",
"rgb": "rgb(224,231,255)",
"hsl": "hsl(226.5,100%,93.9%)",
+ "oklch": "oklch(0.93,0.03,273)",
"rgbChannel": "224 231 255",
"hslChannel": "226.5 100% 93.9%"
},
@@ -1478,6 +1658,7 @@
"hex": "#c7d2fe",
"rgb": "rgb(199,210,254)",
"hsl": "hsl(228,96.5%,88.8%)",
+ "oklch": "oklch(0.87,0.06,274)",
"rgbChannel": "199 210 254",
"hslChannel": "228 96.5% 88.8%"
},
@@ -1486,6 +1667,7 @@
"hex": "#a5b4fc",
"rgb": "rgb(165,180,252)",
"hsl": "hsl(229.7,93.5%,81.8%)",
+ "oklch": "oklch(0.79,0.10,275)",
"rgbChannel": "165 180 252",
"hslChannel": "229.7 93.5% 81.8%"
},
@@ -1494,6 +1676,7 @@
"hex": "#818cf8",
"rgb": "rgb(129,140,248)",
"hsl": "hsl(234.5,89.5%,73.9%)",
+ "oklch": "oklch(0.68,0.16,277)",
"rgbChannel": "129 140 248",
"hslChannel": "234.5 89.5% 73.9%"
},
@@ -1502,6 +1685,7 @@
"hex": "#6366f1",
"rgb": "rgb(99,102,241)",
"hsl": "hsl(238.7,83.5%,66.7%)",
+ "oklch": "oklch(0.59,0.20,277)",
"rgbChannel": "99 102 241",
"hslChannel": "238.7 83.5% 66.7%"
},
@@ -1510,6 +1694,7 @@
"hex": "#4f46e5",
"rgb": "rgb(79,70,229)",
"hsl": "hsl(243.4,75.4%,58.6%)",
+ "oklch": "oklch(0.51,0.23,277)",
"rgbChannel": "79 70 229",
"hslChannel": "243.4 75.4% 58.6%"
},
@@ -1518,6 +1703,7 @@
"hex": "#4338ca",
"rgb": "rgb(67,56,202)",
"hsl": "hsl(244.5,57.9%,50.6%)",
+ "oklch": "oklch(0.46,0.21,277)",
"rgbChannel": "67 56 202",
"hslChannel": "244.5 57.9% 50.6%"
},
@@ -1526,6 +1712,7 @@
"hex": "#3730a3",
"rgb": "rgb(55,48,163)",
"hsl": "hsl(243.7,54.5%,41.4%)",
+ "oklch": "oklch(0.40,0.18,277)",
"rgbChannel": "55 48 163",
"hslChannel": "243.7 54.5% 41.4%"
},
@@ -1534,6 +1721,7 @@
"hex": "#312e81",
"rgb": "rgb(49,46,129)",
"hsl": "hsl(242.2,47.4%,34.3%)",
+ "oklch": "oklch(0.36,0.14,279)",
"rgbChannel": "49 46 129",
"hslChannel": "242.2 47.4% 34.3%"
},
@@ -1542,6 +1730,7 @@
"hex": "#1e1b4b",
"rgb": "rgb(30,27,75)",
"hsl": "hsl(243.8,47.1%,20%)",
+ "oklch": "oklch(0.26,0.09,281)",
"rgbChannel": "30 27 75",
"hslChannel": "243.8 47.1% 20%"
}
@@ -1552,6 +1741,7 @@
"hex": "#f5f3ff",
"rgb": "rgb(245,243,255)",
"hsl": "hsl(250,100%,97.6%)",
+ "oklch": "oklch(0.97,0.02,294)",
"rgbChannel": "245 243 255",
"hslChannel": "250 100% 97.6%"
},
@@ -1560,6 +1750,7 @@
"hex": "#ede9fe",
"rgb": "rgb(237,233,254)",
"hsl": "hsl(251.4,91.3%,95.5%)",
+ "oklch": "oklch(0.94,0.03,295)",
"rgbChannel": "237 233 254",
"hslChannel": "251.4 91.3% 95.5%"
},
@@ -1568,6 +1759,7 @@
"hex": "#ddd6fe",
"rgb": "rgb(221,214,254)",
"hsl": "hsl(250.5,95.2%,91.8%)",
+ "oklch": "oklch(0.89,0.05,293)",
"rgbChannel": "221 214 254",
"hslChannel": "250.5 95.2% 91.8%"
},
@@ -1576,6 +1768,7 @@
"hex": "#c4b5fd",
"rgb": "rgb(196,181,253)",
"hsl": "hsl(252.5,94.7%,85.1%)",
+ "oklch": "oklch(0.81,0.10,294)",
"rgbChannel": "196 181 253",
"hslChannel": "252.5 94.7% 85.1%"
},
@@ -1584,6 +1777,7 @@
"hex": "#a78bfa",
"rgb": "rgb(167,139,250)",
"hsl": "hsl(255.1,91.7%,76.3%)",
+ "oklch": "oklch(0.71,0.16,294)",
"rgbChannel": "167 139 250",
"hslChannel": "255.1 91.7% 76.3%"
},
@@ -1592,6 +1786,7 @@
"hex": "#8b5cf6",
"rgb": "rgb(139,92,246)",
"hsl": "hsl(258.3,89.5%,66.3%)",
+ "oklch": "oklch(0.61,0.22,293)",
"rgbChannel": "139 92 246",
"hslChannel": "258.3 89.5% 66.3%"
},
@@ -1600,6 +1795,7 @@
"hex": "#7c3aed",
"rgb": "rgb(124,58,237)",
"hsl": "hsl(262.1,83.3%,57.8%)",
+ "oklch": "oklch(0.54,0.25,293)",
"rgbChannel": "124 58 237",
"hslChannel": "262.1 83.3% 57.8%"
},
@@ -1608,6 +1804,7 @@
"hex": "#6d28d9",
"rgb": "rgb(109,40,217)",
"hsl": "hsl(263.4,70%,50.4%)",
+ "oklch": "oklch(0.49,0.24,293)",
"rgbChannel": "109 40 217",
"hslChannel": "263.4 70% 50.4%"
},
@@ -1616,6 +1813,7 @@
"hex": "#5b21b6",
"rgb": "rgb(91,33,182)",
"hsl": "hsl(263.4,69.3%,42.2%)",
+ "oklch": "oklch(0.43,0.21,293)",
"rgbChannel": "91 33 182",
"hslChannel": "263.4 69.3% 42.2%"
},
@@ -1624,6 +1822,7 @@
"hex": "#4c1d95",
"rgb": "rgb(76,29,149)",
"hsl": "hsl(263.5,67.4%,34.9%)",
+ "oklch": "oklch(0.38,0.18,294)",
"rgbChannel": "76 29 149",
"hslChannel": "263.5 67.4% 34.9%"
},
@@ -1632,6 +1831,7 @@
"hex": "#1e1b4b",
"rgb": "rgb(46,16,101)",
"hsl": "hsl(261.2,72.6%,22.9%)",
+ "oklch": "oklch(0.28,0.14,291)",
"rgbChannel": "46 16 101",
"hslChannel": "261.2 72.6% 22.9%"
}
@@ -1642,6 +1842,7 @@
"hex": "#faf5ff",
"rgb": "rgb(250,245,255)",
"hsl": "hsl(270,100%,98%)",
+ "oklch": "oklch(0.98,0.01,308)",
"rgbChannel": "250 245 255",
"hslChannel": "270 100% 98%"
},
@@ -1650,6 +1851,7 @@
"hex": "#f3e8ff",
"rgb": "rgb(243,232,255)",
"hsl": "hsl(268.7,100%,95.5%)",
+ "oklch": "oklch(0.95,0.03,307)",
"rgbChannel": "243 232 255",
"hslChannel": "268.7 100% 95.5%"
},
@@ -1658,6 +1860,7 @@
"hex": "#e9d5ff",
"rgb": "rgb(233,213,255)",
"hsl": "hsl(268.6,100%,91.8%)",
+ "oklch": "oklch(0.90,0.06,307)",
"rgbChannel": "233 213 255",
"hslChannel": "268.6 100% 91.8%"
},
@@ -1666,6 +1869,7 @@
"hex": "#d8b4fe",
"rgb": "rgb(216,180,254)",
"hsl": "hsl(269.2,97.4%,85.1%)",
+ "oklch": "oklch(0.83,0.11,306)",
"rgbChannel": "216 180 254",
"hslChannel": "269.2 97.4% 85.1%"
},
@@ -1674,6 +1878,7 @@
"hex": "#c084fc",
"rgb": "rgb(192,132,252)",
"hsl": "hsl(270,95.2%,75.3%)",
+ "oklch": "oklch(0.72,0.18,306)",
"rgbChannel": "192 132 252",
"hslChannel": "270 95.2% 75.3%"
},
@@ -1682,6 +1887,7 @@
"hex": "#a855f7",
"rgb": "rgb(168,85,247)",
"hsl": "hsl(270.7,91%,65.1%)",
+ "oklch": "oklch(0.63,0.23,304)",
"rgbChannel": "168 85 247",
"hslChannel": "270.7 91% 65.1%"
},
@@ -1690,6 +1896,7 @@
"hex": "#9333ea",
"rgb": "rgb(147,51,234)",
"hsl": "hsl(271.5,81.3%,55.9%)",
+ "oklch": "oklch(0.56,0.25,302)",
"rgbChannel": "147 51 234",
"hslChannel": "271.5 81.3% 55.9%"
},
@@ -1698,6 +1905,7 @@
"hex": "#7e22ce",
"rgb": "rgb(126,34,206)",
"hsl": "hsl(272.1,71.7%,47.1%)",
+ "oklch": "oklch(0.50,0.24,302)",
"rgbChannel": "126 34 206",
"hslChannel": "272.1 71.7% 47.1%"
},
@@ -1706,6 +1914,7 @@
"hex": "#6b21a8",
"rgb": "rgb(107,33,168)",
"hsl": "hsl(272.9,67.2%,39.4%)",
+ "oklch": "oklch(0.44,0.20,304)",
"rgbChannel": "107 33 168",
"hslChannel": "272.9 67.2% 39.4%"
},
@@ -1714,6 +1923,7 @@
"hex": "#581c87",
"rgb": "rgb(88,28,135)",
"hsl": "hsl(273.6,65.6%,32%)",
+ "oklch": "oklch(0.38,0.17,305)",
"rgbChannel": "88 28 135",
"hslChannel": "273.6 65.6% 32%"
},
@@ -1722,6 +1932,7 @@
"hex": "#3b0764",
"rgb": "rgb(59,7,100)",
"hsl": "hsl(273.5,86.9%,21%)",
+ "oklch": "oklch(0.29,0.14,303)",
"rgbChannel": "59 7 100",
"hslChannel": "273.5 86.9% 21%"
}
@@ -1732,6 +1943,7 @@
"hex": "#fdf4ff",
"rgb": "rgb(253,244,255)",
"hsl": "hsl(289.1,100%,97.8%)",
+ "oklch": "oklch(0.98,0.02,320)",
"rgbChannel": "253 244 255",
"hslChannel": "289.1 100% 97.8%"
},
@@ -1740,6 +1952,7 @@
"hex": "#fae8ff",
"rgb": "rgb(250,232,255)",
"hsl": "hsl(287,100%,95.5%)",
+ "oklch": "oklch(0.95,0.04,319)",
"rgbChannel": "250 232 255",
"hslChannel": "287 100% 95.5%"
},
@@ -1748,6 +1961,7 @@
"hex": "#f5d0fe",
"rgb": "rgb(245,208,254)",
"hsl": "hsl(288.3,95.8%,90.6%)",
+ "oklch": "oklch(0.90,0.07,320)",
"rgbChannel": "245 208 254",
"hslChannel": "288.3 95.8% 90.6%"
},
@@ -1756,6 +1970,7 @@
"hex": "#f0abfc",
"rgb": "rgb(240,171,252)",
"hsl": "hsl(291.1,93.1%,82.9%)",
+ "oklch": "oklch(0.83,0.13,321)",
"rgbChannel": "240 171 252",
"hslChannel": "291.1 93.1% 82.9%"
},
@@ -1764,6 +1979,7 @@
"hex": "#e879f9",
"rgb": "rgb(232,121,249)",
"hsl": "hsl(292,91.4%,72.5%)",
+ "oklch": "oklch(0.75,0.21,322)",
"rgbChannel": "232 121 249",
"hslChannel": "292 91.4% 72.5%"
},
@@ -1772,6 +1988,7 @@
"hex": "#d946ef",
"rgb": "rgb(217,70,239)",
"hsl": "hsl(292.2,84.1%,60.6%)",
+ "oklch": "oklch(0.67,0.26,322)",
"rgbChannel": "217 70 239",
"hslChannel": "292.2 84.1% 60.6%"
},
@@ -1780,6 +1997,7 @@
"hex": "#c026d3",
"rgb": "rgb(192,38,211)",
"hsl": "hsl(293.4,69.5%,48.8%)",
+ "oklch": "oklch(0.59,0.26,323)",
"rgbChannel": "192 38 211",
"hslChannel": "293.4 69.5% 48.8%"
},
@@ -1788,6 +2006,7 @@
"hex": "#a21caf",
"rgb": "rgb(162,28,175)",
"hsl": "hsl(294.7,72.4%,39.8%)",
+ "oklch": "oklch(0.52,0.23,324)",
"rgbChannel": "162 28 175",
"hslChannel": "294.7 72.4% 39.8%"
},
@@ -1796,6 +2015,7 @@
"hex": "#86198f",
"rgb": "rgb(134,25,143)",
"hsl": "hsl(295.4,70.2%,32.9%)",
+ "oklch": "oklch(0.45,0.19,325)",
"rgbChannel": "134 25 143",
"hslChannel": "295.4 70.2% 32.9%"
},
@@ -1804,6 +2024,7 @@
"hex": "#701a75",
"rgb": "rgb(112,26,117)",
"hsl": "hsl(296.7,63.6%,28%)",
+ "oklch": "oklch(0.40,0.16,326)",
"rgbChannel": "112 26 117",
"hslChannel": "296.7 63.6% 28%"
},
@@ -1812,6 +2033,7 @@
"hex": "#4a044e",
"rgb": "rgb(74,4,78)",
"hsl": "hsl(296.8,90.2%,16.1%)",
+ "oklch": "oklch(0.29,0.13,326)",
"rgbChannel": "74 4 78",
"hslChannel": "296.8 90.2% 16.1%"
}
@@ -1822,6 +2044,7 @@
"hex": "#fdf2f8",
"rgb": "rgb(253,242,248)",
"hsl": "hsl(327.3,73.3%,97.1%)",
+ "oklch": "oklch(0.97,0.01,343)",
"rgbChannel": "253 242 248",
"hslChannel": "327.3 73.3% 97.1%"
},
@@ -1830,6 +2053,7 @@
"hex": "#fce7f3",
"rgb": "rgb(252,231,243)",
"hsl": "hsl(325.7,77.8%,94.7%)",
+ "oklch": "oklch(0.95,0.03,342)",
"rgbChannel": "252 231 243",
"hslChannel": "325.7 77.8% 94.7%"
},
@@ -1838,6 +2062,7 @@
"hex": "#fbcfe8",
"rgb": "rgb(251,207,232)",
"hsl": "hsl(325.9,84.6%,89.8%)",
+ "oklch": "oklch(0.90,0.06,343)",
"rgbChannel": "251 207 232",
"hslChannel": "325.9 84.6% 89.8%"
},
@@ -1846,6 +2071,7 @@
"hex": "#f9a8d4",
"rgb": "rgb(249,168,212)",
"hsl": "hsl(327.4,87.1%,81.8%)",
+ "oklch": "oklch(0.82,0.11,346)",
"rgbChannel": "249 168 212",
"hslChannel": "327.4 87.1% 81.8%"
},
@@ -1854,6 +2080,7 @@
"hex": "#f472b6",
"rgb": "rgb(244,114,182)",
"hsl": "hsl(328.6,85.5%,70.2%)",
+ "oklch": "oklch(0.73,0.18,350)",
"rgbChannel": "244 114 182",
"hslChannel": "328.6 85.5% 70.2%"
},
@@ -1862,6 +2089,7 @@
"hex": "#ec4899",
"rgb": "rgb(236,72,153)",
"hsl": "hsl(330.4,81.2%,60.4%)",
+ "oklch": "oklch(0.66,0.21,354)",
"rgbChannel": "236 72 153",
"hslChannel": "330.4 81.2% 60.4%"
},
@@ -1870,6 +2098,7 @@
"hex": "#db2777",
"rgb": "rgb(219,39,119)",
"hsl": "hsl(333.3,71.4%,50.6%)",
+ "oklch": "oklch(0.59,0.22,1)",
"rgbChannel": "219 39 119",
"hslChannel": "333.3 71.4% 50.6%"
},
@@ -1878,6 +2107,7 @@
"hex": "#be185d",
"rgb": "rgb(190,24,93)",
"hsl": "hsl(335.1,77.6%,42%)",
+ "oklch": "oklch(0.52,0.20,4)",
"rgbChannel": "190 24 93",
"hslChannel": "335.1 77.6% 42%"
},
@@ -1886,6 +2116,7 @@
"hex": "#9d174d",
"rgb": "rgb(157,23,77)",
"hsl": "hsl(335.8,74.4%,35.3%)",
+ "oklch": "oklch(0.46,0.17,4)",
"rgbChannel": "157 23 77",
"hslChannel": "335.8 74.4% 35.3%"
},
@@ -1894,6 +2125,7 @@
"hex": "#831843",
"rgb": "rgb(131,24,67)",
"hsl": "hsl(335.9,69%,30.4%)",
+ "oklch": "oklch(0.41,0.14,2)",
"rgbChannel": "131 24 67",
"hslChannel": "335.9 69% 30.4%"
},
@@ -1902,6 +2134,7 @@
"hex": "#500724",
"rgb": "rgb(80,7,36)",
"hsl": "hsl(336.2,83.9%,17.1%)",
+ "oklch": "oklch(0.28,0.10,4)",
"rgbChannel": "80 7 36",
"hslChannel": "336.2 83.9% 17.1%"
}
@@ -1912,6 +2145,7 @@
"hex": "#fff1f2",
"rgb": "rgb(255,241,242)",
"hsl": "hsl(355.7,100%,97.3%)",
+ "oklch": "oklch(0.97,0.02,12)",
"rgbChannel": "255 241 242",
"hslChannel": "355.7 100% 97.3%"
},
@@ -1920,6 +2154,7 @@
"hex": "#ffe4e6",
"rgb": "rgb(255,228,230)",
"hsl": "hsl(355.6,100%,94.7%)",
+ "oklch": "oklch(0.94,0.03,13)",
"rgbChannel": "255 228 230",
"hslChannel": "355.6 100% 94.7%"
},
@@ -1928,6 +2163,7 @@
"hex": "#fecdd3",
"rgb": "rgb(254,205,211)",
"hsl": "hsl(352.7,96.1%,90%)",
+ "oklch": "oklch(0.89,0.06,10)",
"rgbChannel": "254 205 211",
"hslChannel": "352.7 96.1% 90%"
},
@@ -1936,6 +2172,7 @@
"hex": "#fda4af",
"rgb": "rgb(253,164,175)",
"hsl": "hsl(352.6,95.7%,81.8%)",
+ "oklch": "oklch(0.81,0.11,12)",
"rgbChannel": "253 164 175",
"hslChannel": "352.6 95.7% 81.8%"
},
@@ -1944,6 +2181,7 @@
"hex": "#fb7185",
"rgb": "rgb(251,113,133)",
"hsl": "hsl(351.3,94.5%,71.4%)",
+ "oklch": "oklch(0.72,0.17,13)",
"rgbChannel": "251 113 133",
"hslChannel": "351.3 94.5% 71.4%"
},
@@ -1952,6 +2190,7 @@
"hex": "#f43f5e",
"rgb": "rgb(244,63,94)",
"hsl": "hsl(349.7,89.2%,60.2%)",
+ "oklch": "oklch(0.65,0.22,16)",
"rgbChannel": "244 63 94",
"hslChannel": "349.7 89.2% 60.2%"
},
@@ -1960,6 +2199,7 @@
"hex": "#e11d48",
"rgb": "rgb(225,29,72)",
"hsl": "hsl(346.8,77.2%,49.8%)",
+ "oklch": "oklch(0.59,0.22,18)",
"rgbChannel": "225 29 72",
"hslChannel": "346.8 77.2% 49.8%"
},
@@ -1968,6 +2208,7 @@
"hex": "#be123c",
"rgb": "rgb(190,18,60)",
"hsl": "hsl(345.3,82.7%,40.8%)",
+ "oklch": "oklch(0.51,0.20,17)",
"rgbChannel": "190 18 60",
"hslChannel": "345.3 82.7% 40.8%"
},
@@ -1976,6 +2217,7 @@
"hex": "#9f1239",
"rgb": "rgb(159,18,57)",
"hsl": "hsl(343.4,79.7%,34.7%)",
+ "oklch": "oklch(0.45,0.17,14)",
"rgbChannel": "159 18 57",
"hslChannel": "343.4 79.7% 34.7%"
},
@@ -1984,6 +2226,7 @@
"hex": "#881337",
"rgb": "rgb(136,19,55)",
"hsl": "hsl(341.5,75.5%,30.4%)",
+ "oklch": "oklch(0.41,0.15,10)",
"rgbChannel": "136 19 55",
"hslChannel": "341.5 75.5% 30.4%"
},
@@ -1992,6 +2235,7 @@
"hex": "#4c0519",
"rgb": "rgb(76,5,25)",
"hsl": "hsl(343.1,87.7%,15.9%)",
+ "oklch": "oklch(0.27,0.10,12)",
"rgbChannel": "76 5 25",
"hslChannel": "343.1 87.7% 15.9%"
}
diff --git a/apps/www/public/r/styles/default/stepper-demo.json b/apps/www/public/r/styles/default/stepper-demo.json
index fc5b662b963..6a48974d5c2 100644
--- a/apps/www/public/r/styles/default/stepper-demo.json
+++ b/apps/www/public/r/styles/default/stepper-demo.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-demo.tsx",
- "content": "import {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperDemo() {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperDemo() {\n return (\n \n {({ methods }) => (\n \n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/default/stepper-description.json b/apps/www/public/r/styles/default/stepper-description.json
index 6a110c6f99d..4cfbf2201b0 100644
--- a/apps/www/public/r/styles/default/stepper-description.json
+++ b/apps/www/public/r/styles/default/stepper-description.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-description.tsx",
- "content": "import {\n Stepper,\n StepperAction,\n StepperControls,\n StepperDescription,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n description: \"This is the first step\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n description: \"This is the second step\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n description: \"This is the third step\",\n }\n)\n\nexport default function StepperDemo() {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {step.description}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport {\n Stepper,\n StepperControls,\n StepperDescription,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n description: \"This is the first step\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n description: \"This is the second step\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n description: \"This is the third step\",\n }\n)\n\nexport default function StepperDemo() {\n return (\n \n {({ methods }) => (\n \n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {step.description}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/default/stepper-form.json b/apps/www/public/r/styles/default/stepper-form.json
index 5d6a43cce8d..4f6a19a2c84 100644
--- a/apps/www/public/r/styles/default/stepper-form.json
+++ b/apps/www/public/r/styles/default/stepper-form.json
@@ -10,7 +10,7 @@
"files": [
{
"path": "examples/stepper-form.tsx",
- "content": "import { zodResolver } from \"@hookform/resolvers/zod\"\nimport { useForm, useFormContext } from \"react-hook-form\"\nimport { z } from \"zod\"\n\nimport { Form } from \"@/registry/default/ui/form\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst shippingSchema = z.object({\n address: z.string().min(1, \"Address is required\"),\n city: z.string().min(1, \"City is required\"),\n postalCode: z.string().min(5, \"Postal code is required\"),\n})\n\nconst paymentSchema = z.object({\n cardNumber: z.string().min(16, \"Card number is required\"),\n expirationDate: z.string().min(5, \"Expiration date is required\"),\n cvv: z.string().min(3, \"CVV is required\"),\n})\n\ntype ShippingFormValues = z.infer\ntype PaymentFormValues = z.infer\n\nconst stepperInstance = defineStepper(\n {\n id: \"shipping\",\n title: \"Shipping\",\n schema: shippingSchema,\n },\n {\n id: \"payment\",\n title: \"Payment\",\n schema: paymentSchema,\n },\n {\n id: \"complete\",\n title: \"Complete\",\n schema: z.object({}),\n }\n)\n\nexport default function StepperForm() {\n return (\n \n \n \n )\n}\n\nconst FormStepperComponent = () => {\n const { steps, useStepper, utils } = stepperInstance\n const methods = useStepper()\n\n const form = useForm({\n mode: \"onTouched\",\n resolver: zodResolver(methods.current.schema),\n })\n\n const onSubmit = (values: z.infer) => {\n console.log(`Form values for step ${methods.current.id}:`, values)\n }\n\n const currentIndex = utils.getIndex(methods.current.id)\n\n return (\n \n \n )\n}\n\nconst ShippingForm = () => {\n const {\n register,\n formState: { errors },\n } = useFormContext()\n\n return (\n \n )\n}\n\nfunction PaymentForm() {\n const {\n register,\n formState: { errors },\n } = useFormContext()\n\n return (\n \n )\n}\n\nfunction CompleteComponent() {\n return Thank you! Your order is complete.
\n}\n",
+ "content": "import * as React from \"react\"\nimport { zodResolver } from \"@hookform/resolvers/zod\"\nimport { useForm, useFormContext } from \"react-hook-form\"\nimport { z } from \"zod\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Form } from \"@/registry/default/ui/form\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst shippingSchema = z.object({\n address: z.string().min(1, \"Address is required\"),\n city: z.string().min(1, \"City is required\"),\n postalCode: z.string().min(5, \"Postal code is required\"),\n})\n\nconst paymentSchema = z.object({\n cardNumber: z.string().min(16, \"Card number is required\"),\n expirationDate: z.string().min(5, \"Expiration date is required\"),\n cvv: z.string().min(3, \"CVV is required\"),\n})\n\ntype ShippingFormValues = z.infer\ntype PaymentFormValues = z.infer\n\nconst ShippingForm = () => {\n const {\n register,\n formState: { errors },\n } = useFormContext()\n\n return (\n \n )\n}\n\nfunction PaymentForm() {\n const {\n register,\n formState: { errors },\n } = useFormContext()\n\n return (\n \n )\n}\n\nfunction CompleteComponent() {\n return Thank you! Your order is complete.
\n}\n\nconst stepperInstance = defineStepper(\n {\n id: \"shipping\",\n title: \"Shipping\",\n schema: shippingSchema,\n Component: ShippingForm,\n },\n {\n id: \"payment\",\n title: \"Payment\",\n schema: paymentSchema,\n Component: PaymentForm,\n },\n {\n id: \"complete\",\n title: \"Complete\",\n schema: z.object({}),\n Component: CompleteComponent,\n }\n)\n\nexport default function StepperForm() {\n return (\n \n \n \n )\n}\n\nconst FormStepperComponent = () => {\n const { useStepper } = stepperInstance\n const methods = useStepper()\n\n const form = useForm({\n mode: \"onTouched\",\n resolver: zodResolver(methods.current.schema),\n })\n\n const onSubmit = (values: z.infer) => {\n console.log(`Form values for step ${methods.current.id}:`, values)\n }\n\n return (\n \n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/default/stepper-icon.json b/apps/www/public/r/styles/default/stepper-icon.json
index fe6947c6478..c31631c523a 100644
--- a/apps/www/public/r/styles/default/stepper-icon.json
+++ b/apps/www/public/r/styles/default/stepper-icon.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-icon.tsx",
- "content": "import { HomeIcon, SettingsIcon, UserIcon } from \"lucide-react\"\n\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n icon: ,\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n icon: ,\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n icon: ,\n }\n)\n\nexport default function StepperIcon() {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n icon={step.icon}\n >\n {step.title}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\nimport { HomeIcon, SettingsIcon, UserIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n icon: ,\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n icon: ,\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n icon: ,\n }\n)\n\nexport default function StepperDemo() {\n return (\n \n {({ methods }) => (\n \n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n icon={step.icon}\n >\n {step.title}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/default/stepper-label-orientation.json b/apps/www/public/r/styles/default/stepper-label-orientation.json
index 8a3a1ec6800..52552c2870c 100644
--- a/apps/www/public/r/styles/default/stepper-label-orientation.json
+++ b/apps/www/public/r/styles/default/stepper-label-orientation.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-label-orientation.tsx",
- "content": "import * as React from \"react\"\n\nimport { Label } from \"@/registry/default/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/default/ui/radio-group\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\ntype LabelOrientation = \"horizontal\" | \"vertical\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperVariants() {\n const steps = stepperInstance.steps\n\n const [labelOrientation, setLabelOrientation] =\n React.useState(\"horizontal\")\n return (\n \n
\n setLabelOrientation(value as LabelOrientation)\n }\n >\n \n \n \n
\n \n \n \n
\n \n
\n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n
\n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/default/ui/radio-group\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\ntype LabelOrientation = \"horizontal\" | \"vertical\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperVariants() {\n const [labelOrientation, setLabelOrientation] =\n React.useState(\"horizontal\")\n return (\n \n
\n setLabelOrientation(value as LabelOrientation)\n }\n >\n \n \n \n
\n \n \n \n
\n \n
\n {({ methods }) => (\n \n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n
\n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/default/stepper-responsive-variant.json b/apps/www/public/r/styles/default/stepper-responsive-variant.json
index d223e5cff32..1d212773ace 100644
--- a/apps/www/public/r/styles/default/stepper-responsive-variant.json
+++ b/apps/www/public/r/styles/default/stepper-responsive-variant.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-responsive-variant.tsx",
- "content": "import { useMediaQuery } from \"@/hooks/use-media-query\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperResponsiveVariant() {\n const steps = stepperInstance.steps\n const isMobile = useMediaQuery(\"(max-width: 768px)\")\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {isMobile && (\n \n {({ step }) => (\n \n Content for {step.id}\n
\n )}\n \n )}\n \n ))}\n \n {!isMobile &&\n steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { useMediaQuery } from \"@/hooks/use-media-query\"\nimport { Button } from \"@/registry/default/ui/button\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperResponsiveVariant() {\n const isMobile = useMediaQuery(\"(max-width: 768px)\")\n return (\n \n {({ methods }) => (\n <>\n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {isMobile &&\n methods.when(step.id, (step) => (\n \n \n Content for {step.id}\n
\n \n ))}\n \n ))}\n \n {!isMobile &&\n methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n >\n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/default/stepper-tracking.json b/apps/www/public/r/styles/default/stepper-tracking.json
index 6bc678c8290..332fb48efd2 100644
--- a/apps/www/public/r/styles/default/stepper-tracking.json
+++ b/apps/www/public/r/styles/default/stepper-tracking.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-tracking.tsx",
- "content": "import * as React from \"react\"\n\nimport { Label } from \"@/registry/default/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/default/ui/radio-group\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n },\n {\n id: \"step-4\",\n title: \"Step 4\",\n },\n {\n id: \"step-5\",\n title: \"Step 5\",\n },\n {\n id: \"step-6\",\n title: \"Step 6\",\n }\n)\n\nexport default function StepperVerticalFollow() {\n const steps = stepperInstance.steps\n\n const [tracking, setTracking] = React.useState(false)\n return (\n \n
setTracking(value === \"true\")}\n >\n \n \n \n
\n \n \n \n
\n \n
\n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n \n
\n Content for {step.id}\n
\n
\n \n Previous\n Next\n Reset\n \n \n \n ))}\n \n >\n )}\n \n
\n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/default/ui/radio-group\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n },\n {\n id: \"step-4\",\n title: \"Step 4\",\n },\n {\n id: \"step-5\",\n title: \"Step 5\",\n },\n {\n id: \"step-6\",\n title: \"Step 6\",\n }\n)\n\nexport default function StepperVerticalFollow() {\n const [tracking, setTracking] = React.useState(false)\n return (\n \n
setTracking(value === \"true\")}\n >\n \n \n \n
\n \n \n \n
\n \n
\n {({ methods }) => (\n <>\n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {methods.when(step.id, () => (\n \n \n
\n Content for {step.id}\n
\n
\n \n {!methods.isLast && (\n \n )}\n \n \n \n ))}\n \n ))}\n \n >\n )}\n \n
\n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/default/stepper-variants.json b/apps/www/public/r/styles/default/stepper-variants.json
index 3e5ee2c4c88..7a72008bdcd 100644
--- a/apps/www/public/r/styles/default/stepper-variants.json
+++ b/apps/www/public/r/styles/default/stepper-variants.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-variants.tsx",
- "content": "import * as React from \"react\"\n\nimport { Label } from \"@/registry/default/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/default/ui/radio-group\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\ntype Variant = \"horizontal\" | \"vertical\" | \"circle\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperVariants() {\n const steps = stepperInstance.steps\n\n const [variant, setVariant] = React.useState(\"horizontal\")\n return (\n \n
setVariant(value as Variant)}\n >\n \n \n \n
\n \n \n \n
\n \n \n \n
\n \n {variant === \"horizontal\" &&
}\n {variant === \"vertical\" &&
}\n {variant === \"circle\" &&
}\n
\n )\n}\n\nconst HorizontalStepper = () => {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n\nconst VerticalStepper = () => {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n \n ))}\n \n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n\nconst CircleStepper = () => {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n \n {methods.current.title}\n \n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/default/ui/radio-group\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/default/ui/stepper\"\n\ntype Variant = \"horizontal\" | \"vertical\" | \"circle\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperVariants() {\n const [variant, setVariant] = React.useState(\"horizontal\")\n return (\n \n
setVariant(value as Variant)}\n >\n \n \n \n
\n \n \n \n
\n \n \n \n
\n \n {variant === \"horizontal\" &&
}\n {variant === \"vertical\" &&
}\n {variant === \"circle\" &&
}\n
\n )\n}\n\nconst HorizontalStepper = () => {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n \n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n\nconst VerticalStepper = () => {\n return (\n \n {({ methods }) => (\n <>\n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {methods.when(step.id, () => (\n \n Content for {step.id}
\n \n ))}\n \n ))}\n \n \n {!methods.isLast && (\n \n )}\n \n \n >\n )}\n \n )\n}\n\nconst CircleStepper = () => {\n return (\n \n {({ methods }) => (\n <>\n \n \n {methods.current.title}\n \n \n {methods.when(methods.current.id, () => (\n \n \n Content for {methods.current.id}\n
\n \n ))}\n \n {!methods.isLast && (\n \n )}\n \n \n >\n )}\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/default/stepper.json b/apps/www/public/r/styles/default/stepper.json
index c18aae4a179..40329946988 100644
--- a/apps/www/public/r/styles/default/stepper.json
+++ b/apps/www/public/r/styles/default/stepper.json
@@ -14,7 +14,7 @@
"files": [
{
"path": "ui/stepper.tsx",
- "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport * as Stepperize from \"@stepperize/react\"\nimport { VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/default/ui/button\"\n\ntype StepperProviderProps = StepperConfig & {\n children: React.ReactNode\n}\n\ntype StepperVariant = \"horizontal\" | \"vertical\" | \"circle\"\ntype StepperLabelOrientation = \"horizontal\" | \"vertical\"\n\ntype StepperConfig = {\n instance: ReturnType>\n variant?: StepperVariant\n labelOrientation?: StepperLabelOrientation\n tracking?: boolean\n}\n\nconst StepContext = React.createContext>({\n instance: {} as ReturnType>,\n variant: \"horizontal\",\n})\n\nconst StepperProvider = ({\n children,\n ...props\n}: StepperProviderProps) => {\n const Scope = props.instance.Scoped\n return (\n \n {children}\n \n )\n}\n\nconst useStepper = (): StepperConfig => {\n const context = React.useContext(StepContext)\n if (!context) {\n throw new Error(\"useStepper must be used within a Stepper\")\n }\n return context\n}\n\nfunction Stepper({\n children,\n variant = \"horizontal\",\n className,\n labelOrientation = \"horizontal\",\n tracking = false,\n ...props\n}: StepperConfig &\n Omit, \"children\"> & {\n children:\n | React.ReactNode\n | ((props: { methods: Stepperize.Stepper }) => React.ReactNode)\n }) {\n const { instance } = props\n\n const methods = instance.useStepper() as Stepperize.Stepper\n\n return (\n \n \n {typeof children === \"function\" ? children({ methods }) : children}\n
\n \n )\n}\n\nconst StepperNavigation = ({\n children,\n className,\n \"aria-label\": ariaLabel = \"Stepper Navigation\",\n ...props\n}: Omit, \"children\"> & {\n children: React.ReactNode\n}) => {\n const { variant, instance } = useStepper()\n\n const methods = instance.useStepper() as Stepperize.Stepper\n\n return (\n \n )\n}\n\nconst listVariants = cva(\"stepper-navigation-list flex gap-2\", {\n variants: {\n variant: {\n horizontal: \"flex-row items-center justify-between\",\n vertical: \"flex-col\",\n circle: \"flex-row items-center justify-between\",\n },\n },\n})\n\nconst StepperStep = ({\n children,\n className,\n of,\n icon,\n ...props\n}: React.ComponentProps<\"button\"> & { of: T; icon?: Icon }) => {\n const id = React.useId()\n const { instance, variant, labelOrientation } = useStepper()\n\n const methods = instance.useStepper() as Stepperize.Stepper\n\n const currentStep = methods.current\n\n const isLast = instance.utils.getLast().id === of.id\n const stepIndex = instance.utils.getIndex(of.id)\n const currentIndex = instance.utils.getIndex(currentStep?.id ?? \"\")\n const isActive = currentStep?.id === of.id\n\n const dataState = getStepState(currentIndex, stepIndex)\n const childMap = useStepChildren(children)\n\n const title = childMap.get(\"title\")\n const description = childMap.get(\"description\")\n const panel = childMap.get(\"panel\")\n\n if (variant === \"circle\") {\n return (\n \n \n \n {title}\n {description}\n
\n \n )\n }\n\n return (\n <>\n \n \n {variant === \"horizontal\" && labelOrientation === \"vertical\" && (\n \n )}\n \n {title}\n {description}\n
\n \n\n {variant === \"horizontal\" && labelOrientation === \"horizontal\" && (\n \n )}\n\n {variant === \"vertical\" && (\n \n {!isLast && (\n
\n \n
\n )}\n
{panel}
\n
\n )}\n >\n )\n}\n\nconst StepperSeparator = ({\n orientation,\n isLast,\n labelOrientation,\n state,\n disabled,\n}: {\n isLast: boolean\n state: string\n disabled?: boolean\n} & VariantProps) => {\n if (isLast) return null\n return (\n \n )\n}\n\nconst classForSeparator = cva(\n [\n \"bg-muted\",\n \"data-[state=completed]:bg-primary data-[disabled]:opacity-50\",\n \"transition-all duration-300 ease-in-out\",\n ],\n {\n variants: {\n orientation: {\n horizontal: \"h-0.5 flex-1\",\n vertical: \"h-full w-0.5\",\n },\n labelOrientation: {\n vertical:\n \"absolute left-[calc(50%+30px)] right-[calc(-50%+20px)] top-5 block shrink-0\",\n },\n },\n }\n)\n\nconst onStepKeyDown = (\n e: React.KeyboardEvent,\n nextStep: Stepperize.Step,\n prevStep: Stepperize.Step\n) => {\n const { key } = e\n const directions = {\n next: [\"ArrowRight\", \"ArrowDown\"],\n prev: [\"ArrowLeft\", \"ArrowUp\"],\n }\n\n if (directions.next.includes(key) || directions.prev.includes(key)) {\n const direction = directions.next.includes(key) ? \"next\" : \"prev\"\n const step = direction === \"next\" ? nextStep : prevStep\n\n if (!step) return\n\n const stepElement = document.getElementById(`step-${step.id}`)\n if (!stepElement) return\n\n const isActive =\n stepElement.parentElement?.getAttribute(\"data-state\") !== \"inactive\"\n if (isActive || direction === \"prev\") {\n stepElement.focus()\n }\n }\n}\n\nconst getStepState = (currentIndex: number, stepIndex: number) => {\n if (currentIndex === stepIndex) return \"active\"\n if (currentIndex > stepIndex) return \"completed\"\n return \"inactive\"\n}\n\nconst extractChildren = (children: React.ReactNode) => {\n const childrenArray = React.Children.toArray(children)\n const map = new Map()\n\n for (const child of childrenArray) {\n if (React.isValidElement(child)) {\n if (child.type === StepperTitle) {\n map.set(\"title\", child)\n } else if (child.type === StepperDescription) {\n map.set(\"description\", child)\n } else if (child.type === StepperPanel) {\n map.set(\"panel\", child)\n }\n }\n }\n\n return map\n}\n\nconst useStepChildren = (children: React.ReactNode) => {\n return React.useMemo(() => extractChildren(children), [children])\n}\n\nconst StepperTitle = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"h4\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"h4\"\n\n return (\n \n {children}\n \n )\n}\n\nconst StepperDescription = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"p\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"p\"\n\n return (\n \n {children}\n \n )\n}\n\ntype CircleStepIndicatorProps = {\n currentStep: number\n totalSteps: number\n size?: number\n strokeWidth?: number\n}\n\nconst CircleStepIndicator = ({\n currentStep,\n totalSteps,\n size = 80,\n strokeWidth = 6,\n}: CircleStepIndicatorProps) => {\n const radius = (size - strokeWidth) / 2\n const circumference = radius * 2 * Math.PI\n const fillPercentage = (currentStep / totalSteps) * 100\n const dashOffset = circumference - (circumference * fillPercentage) / 100\n\n return (\n \n
\n
\n \n {currentStep} of {totalSteps}\n \n
\n
\n )\n}\n\nconst StepperPanel = ({\n children,\n className,\n when,\n asChild,\n ...props\n}: Omit, \"children\"> & {\n asChild?: boolean\n when: T\n children:\n | React.ReactNode\n | ((props: {\n step: T\n onBeforeAction: (\n action: StepAction,\n callback: (params: {\n prevStep: Stepperize.Step\n nextStep: Stepperize.Step\n }) => Promise | boolean\n ) => void\n }) => React.ReactNode)\n}) => {\n const Comp = asChild ? Slot : \"div\"\n const { instance, tracking } = useStepper()\n\n const methods = instance.useStepper()\n\n if (instance.utils.getIndex(when.id) === -1) {\n throw new Error(`Step ${when.id} does not exist in the stepper instance`)\n }\n\n const onBeforeAction = React.useCallback(\n async (\n action: StepAction,\n callback: (params: {\n prevStep: Stepperize.Step\n nextStep: Stepperize.Step\n }) => Promise | boolean\n ) => {\n const prevStep = methods.current\n const nextStep =\n action === \"next\"\n ? instance.utils.getNext(prevStep.id)\n : action === \"prev\"\n ? instance.utils.getPrev(prevStep.id)\n : instance.utils.getFirst()\n\n const shouldProceed = await callback({ prevStep, nextStep })\n if (shouldProceed) {\n if (action === \"next\") methods.next()\n if (action === \"prev\") methods.prev()\n if (action === \"reset\") methods.reset()\n }\n },\n [methods, instance.utils]\n )\n\n return (\n <>\n {methods.when(when.id, (step) => (\n scrollIntoStepperPanel(node, tracking)}\n {...props}\n >\n {typeof children === \"function\"\n ? children({ step: step as T, onBeforeAction })\n : children}\n \n ))}\n >\n )\n}\n\nfunction scrollIntoStepperPanel(\n node: HTMLDivElement | null,\n tracking?: boolean\n) {\n if (tracking) {\n node?.scrollIntoView({ behavior: \"smooth\", block: \"center\" })\n }\n}\n\nconst StepperControls = ({\n children,\n asChild,\n className,\n ...props\n}: Omit, \"children\"> & {\n asChild?: boolean\n children:\n | React.ReactNode\n | ((props: {\n methods: Stepperize.Stepper\n }) => React.ReactNode)\n}) => {\n const Comp = asChild ? Slot : \"div\"\n const { instance } = useStepper()\n\n const methods = instance.useStepper()\n\n return (\n \n {typeof children === \"function\" ? children({ methods }) : children}\n \n )\n}\n\ntype StepAction = \"next\" | \"prev\" | \"reset\"\n\ntype StepperActionProps = {\n action: StepAction\n children: React.ReactNode\n asChild?: boolean\n onBeforeAction?: ({\n event,\n prevStep,\n nextStep,\n }: {\n event: React.MouseEvent\n prevStep: Stepperize.Step\n nextStep: Stepperize.Step\n }) => Promise | boolean\n className?: string\n}\n\nconst StepperAction = ({\n action,\n children,\n asChild = false,\n onBeforeAction,\n className,\n disabled,\n ...props\n}: React.ComponentProps<\"button\"> & StepperActionProps) => {\n const { instance } = useStepper()\n const methods = instance.useStepper()\n\n const currentStep = methods.current\n\n const isDisabled = (action: StepAction) =>\n action === \"prev\" && methods.isFirst\n\n const actionMap = React.useMemo(\n () => ({\n next: methods.next,\n prev: methods.prev,\n reset: methods.reset,\n }),\n [methods]\n )\n\n const handleClick = React.useCallback(\n async (event: React.MouseEvent) => {\n if (onBeforeAction) {\n const nextStep =\n action === \"next\"\n ? instance.utils.getNext(currentStep.id)\n : action === \"prev\"\n ? instance.utils.getPrev(currentStep.id)\n : instance.utils.getFirst()\n const shouldProceed = await onBeforeAction({\n event,\n prevStep: currentStep,\n nextStep,\n })\n if (!shouldProceed) {\n return\n }\n }\n\n actionMap[action]?.()\n },\n [onBeforeAction, actionMap, action, instance.utils, currentStep]\n )\n\n const Comp = asChild ? Slot : Button\n\n if (\n (methods.isLast && (action === \"next\" || action === \"prev\")) ||\n (!methods.isLast && action === \"reset\")\n ) {\n return null\n }\n\n return (\n \n {children}\n \n )\n}\n\nconst defineStepper: typeof Stepperize.defineStepper = Stepperize.defineStepper\n\nexport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperDescription,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n}\n",
+ "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport * as Stepperize from \"@stepperize/react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/default/ui/button\"\n\ntype StepperVariant = \"horizontal\" | \"vertical\" | \"circle\"\ntype StepperLabelOrientation = \"horizontal\" | \"vertical\"\n\ntype StepperConfig = {\n instance: ReturnType>\n variant?: StepperVariant\n labelOrientation?: StepperLabelOrientation\n tracking?: boolean\n}\n\ntype StepperProviderProps = StepperConfig & {\n children: React.ReactNode\n}\n\nconst StepContext = React.createContext | null>(null)\n\nconst StepperProvider = ({\n children,\n ...props\n}: StepperProviderProps) => {\n const { instance } = props\n const Scoped = instance.Scoped\n return (\n \n {children}\n \n )\n}\n\nconst useStepper = (): StepperConfig => {\n const context = React.useContext(StepContext)\n if (!context) {\n throw new Error(\"useStepper must be used within a StepperProvider.\")\n }\n return context\n}\n\ntype StepperProps = StepperConfig &\n Omit, \"children\"> & {\n children:\n | React.ReactNode\n | ((props: { methods: Stepperize.Stepper }) => React.ReactNode)\n }\n\nconst Stepper = ({\n children,\n variant = \"horizontal\",\n labelOrientation = \"horizontal\",\n tracking = false,\n instance,\n ...props\n}: StepperProps) => (\n \n {children}\n \n)\n\nconst StepperContainer = ({\n children,\n className,\n ...props\n}: Omit, \"children\"> & {\n children:\n | React.ReactNode\n | ((props: { methods: Stepperize.Stepper }) => React.ReactNode)\n}) => {\n const { instance } = useStepper()\n const methods = instance.useStepper()\n\n return (\n \n {typeof children === \"function\" ? children({ methods }) : children}\n
\n )\n}\n\nconst StepperNavigation = ({\n children,\n className,\n \"aria-label\": ariaLabel = \"Stepper Navigation\",\n ...props\n}: Omit, \"children\"> & {\n children: React.ReactNode\n}) => {\n const { variant } = useStepper()\n\n return (\n \n )\n}\n\nconst listVariants = cva(\"stepper-navigation-list flex gap-2\", {\n variants: {\n variant: {\n horizontal: \"flex-row items-center justify-between\",\n vertical: \"flex-col\",\n circle: \"flex-row items-center justify-between\",\n },\n },\n})\n\nconst StepperStep = ({\n children,\n className,\n of,\n icon,\n ...props\n}: React.ComponentProps<\"button\"> & { of: T; icon?: Icon }) => {\n const { instance, variant, labelOrientation } = useStepper()\n\n const methods = instance.useStepper()\n\n const currentStep = methods.current\n\n const isLast = instance.utils.getLast().id === of.id\n const stepIndex = instance.utils.getIndex(of.id)\n const currentIndex = instance.utils.getIndex(currentStep?.id ?? \"\")\n const isActive = currentStep?.id === of.id\n\n const dataState = getStepState(currentIndex, stepIndex)\n const childMap = useStepChildren(children)\n\n const title = childMap.get(\"title\")\n const description = childMap.get(\"description\")\n const panel = childMap.get(\"panel\")\n\n if (variant === \"circle\") {\n return (\n \n \n \n {title}\n {description}\n
\n \n )\n }\n\n return (\n <>\n \n \n {variant === \"horizontal\" && labelOrientation === \"vertical\" && (\n \n )}\n \n {title}\n {description}\n
\n \n\n {variant === \"horizontal\" && labelOrientation === \"horizontal\" && (\n \n )}\n\n {variant === \"vertical\" && (\n \n {!isLast && (\n
\n \n
\n )}\n
{panel}
\n
\n )}\n >\n )\n}\n\nconst StepperSeparator = ({\n orientation,\n isLast,\n labelOrientation,\n state,\n disabled,\n}: {\n isLast: boolean\n state: string\n disabled?: boolean\n} & VariantProps) => {\n if (isLast) {\n return null\n }\n return (\n \n )\n}\n\nconst classForSeparator = cva(\n [\n \"bg-muted\",\n \"data-[state=completed]:bg-primary data-[disabled]:opacity-50\",\n \"transition-all duration-300 ease-in-out\",\n ],\n {\n variants: {\n orientation: {\n horizontal: \"h-0.5 flex-1\",\n vertical: \"h-full w-0.5\",\n },\n labelOrientation: {\n vertical:\n \"absolute left-[calc(50%+30px)] right-[calc(-50%+20px)] top-5 block shrink-0\",\n },\n },\n }\n)\n\nconst onStepKeyDown = (\n e: React.KeyboardEvent,\n nextStep: Stepperize.Step,\n prevStep: Stepperize.Step\n) => {\n const { key } = e\n const directions = {\n next: [\"ArrowRight\", \"ArrowDown\"],\n prev: [\"ArrowLeft\", \"ArrowUp\"],\n }\n\n if (directions.next.includes(key) || directions.prev.includes(key)) {\n const direction = directions.next.includes(key) ? \"next\" : \"prev\"\n const step = direction === \"next\" ? nextStep : prevStep\n\n if (!step) {\n return\n }\n\n const stepElement = document.getElementById(`step-${step.id}`)\n if (!stepElement) {\n return\n }\n\n const isActive =\n stepElement.parentElement?.getAttribute(\"data-state\") !== \"inactive\"\n if (isActive || direction === \"prev\") {\n stepElement.focus()\n }\n }\n}\n\nconst getStepState = (currentIndex: number, stepIndex: number) => {\n if (currentIndex === stepIndex) {\n return \"active\"\n }\n if (currentIndex > stepIndex) {\n return \"completed\"\n }\n return \"inactive\"\n}\n\nconst extractChildren = (children: React.ReactNode) => {\n const childrenArray = React.Children.toArray(children)\n const map = new Map()\n\n for (const child of childrenArray) {\n if (React.isValidElement(child)) {\n if (child.type === StepperTitle) {\n map.set(\"title\", child)\n } else if (child.type === StepperDescription) {\n map.set(\"description\", child)\n } else if (child.type === StepperPanel) {\n map.set(\"panel\", child)\n }\n }\n }\n\n return map\n}\n\nconst useStepChildren = (children: React.ReactNode) => {\n return React.useMemo(() => extractChildren(children), [children])\n}\n\nconst StepperTitle = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"h4\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"h4\"\n\n return (\n \n {children}\n \n )\n}\n\nconst StepperDescription = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"p\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"p\"\n\n return (\n \n {children}\n \n )\n}\n\ntype CircleStepIndicatorProps = {\n currentStep: number\n totalSteps: number\n size?: number\n strokeWidth?: number\n}\n\nconst CircleStepIndicator = ({\n currentStep,\n totalSteps,\n size = 80,\n strokeWidth = 6,\n}: CircleStepIndicatorProps) => {\n const radius = (size - strokeWidth) / 2\n const circumference = radius * 2 * Math.PI\n const fillPercentage = (currentStep / totalSteps) * 100\n const dashOffset = circumference - (circumference * fillPercentage) / 100\n return (\n \n
\n
\n \n {currentStep} of {totalSteps}\n \n
\n
\n )\n}\n\nconst StepperPanel = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"div\"> & {\n asChild?: boolean\n}) => {\n const Comp = asChild ? Slot : \"div\"\n const { tracking } = useStepper()\n\n return (\n scrollIntoStepperPanel(node, tracking)}\n {...props}\n >\n {children}\n \n )\n}\n\nfunction scrollIntoStepperPanel(\n node: HTMLDivElement | null,\n tracking?: boolean\n) {\n if (tracking) {\n node?.scrollIntoView({ behavior: \"smooth\", block: \"center\" })\n }\n}\n\nconst StepperControls = ({\n children,\n asChild,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"div\"\n return (\n \n {children}\n \n )\n}\n\nconst defineStepper: typeof Stepperize.defineStepper = Stepperize.defineStepper\n\nexport {\n defineStepper,\n Stepper,\n StepperControls,\n StepperDescription,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n}\n",
"type": "registry:ui",
"target": ""
}
diff --git a/apps/www/public/r/styles/new-york/stepper-demo.json b/apps/www/public/r/styles/new-york/stepper-demo.json
index 8732ce9be87..28bd7d4a481 100644
--- a/apps/www/public/r/styles/new-york/stepper-demo.json
+++ b/apps/www/public/r/styles/new-york/stepper-demo.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-demo.tsx",
- "content": "import {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperDemo() {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperDemo() {\n return (\n \n {({ methods }) => (\n \n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/new-york/stepper-description.json b/apps/www/public/r/styles/new-york/stepper-description.json
index 5b3d1ba2d5f..ce1a4098be2 100644
--- a/apps/www/public/r/styles/new-york/stepper-description.json
+++ b/apps/www/public/r/styles/new-york/stepper-description.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-description.tsx",
- "content": "import {\n Stepper,\n StepperAction,\n StepperControls,\n StepperDescription,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n description: \"This is the first step\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n description: \"This is the second step\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n description: \"This is the third step\",\n }\n)\n\nexport default function StepperDemo() {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {step.description}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport {\n Stepper,\n StepperControls,\n StepperDescription,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n description: \"This is the first step\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n description: \"This is the second step\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n description: \"This is the third step\",\n }\n)\n\nexport default function StepperDemo() {\n return (\n \n {({ methods }) => (\n \n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {step.description}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/new-york/stepper-form.json b/apps/www/public/r/styles/new-york/stepper-form.json
index f177415f0e8..c9529b817da 100644
--- a/apps/www/public/r/styles/new-york/stepper-form.json
+++ b/apps/www/public/r/styles/new-york/stepper-form.json
@@ -10,7 +10,7 @@
"files": [
{
"path": "examples/stepper-form.tsx",
- "content": "import { zodResolver } from \"@hookform/resolvers/zod\"\nimport { useForm, useFormContext } from \"react-hook-form\"\nimport { z } from \"zod\"\n\nimport { Form } from \"@/registry/new-york/ui/form\"\nimport { Input } from \"@/registry/new-york/ui/input\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst shippingSchema = z.object({\n address: z.string().min(1, \"Address is required\"),\n city: z.string().min(1, \"City is required\"),\n postalCode: z.string().min(5, \"Postal code is required\"),\n})\n\nconst paymentSchema = z.object({\n cardNumber: z.string().min(16, \"Card number is required\"),\n expirationDate: z.string().min(5, \"Expiration date is required\"),\n cvv: z.string().min(3, \"CVV is required\"),\n})\n\ntype ShippingFormValues = z.infer\ntype PaymentFormValues = z.infer\n\nconst stepperInstance = defineStepper(\n {\n id: \"shipping\",\n title: \"Shipping\",\n schema: shippingSchema,\n },\n {\n id: \"payment\",\n title: \"Payment\",\n schema: paymentSchema,\n },\n {\n id: \"complete\",\n title: \"Complete\",\n schema: z.object({}),\n }\n)\n\nexport default function StepperForm() {\n return (\n \n \n \n )\n}\n\nconst FormStepperComponent = () => {\n const { steps, useStepper, utils } = stepperInstance\n const methods = useStepper()\n\n const form = useForm({\n mode: \"onTouched\",\n resolver: zodResolver(methods.current.schema),\n })\n\n const onSubmit = (values: z.infer) => {\n console.log(`Form values for step ${methods.current.id}:`, values)\n }\n\n const currentIndex = utils.getIndex(methods.current.id)\n\n return (\n \n \n )\n}\n\nconst ShippingForm = () => {\n const {\n register,\n formState: { errors },\n } = useFormContext()\n\n return (\n \n )\n}\n\nfunction PaymentForm() {\n const {\n register,\n formState: { errors },\n } = useFormContext()\n\n return (\n \n )\n}\n\nfunction CompleteComponent() {\n return Thank you! Your order is complete.
\n}\n",
+ "content": "import * as React from \"react\"\nimport { zodResolver } from \"@hookform/resolvers/zod\"\nimport { useForm, useFormContext } from \"react-hook-form\"\nimport { z } from \"zod\"\n\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport { Form } from \"@/registry/new-york/ui/form\"\nimport { Input } from \"@/registry/new-york/ui/input\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst shippingSchema = z.object({\n address: z.string().min(1, \"Address is required\"),\n city: z.string().min(1, \"City is required\"),\n postalCode: z.string().min(5, \"Postal code is required\"),\n})\n\nconst paymentSchema = z.object({\n cardNumber: z.string().min(16, \"Card number is required\"),\n expirationDate: z.string().min(5, \"Expiration date is required\"),\n cvv: z.string().min(3, \"CVV is required\"),\n})\n\ntype ShippingFormValues = z.infer\ntype PaymentFormValues = z.infer\n\nconst ShippingForm = () => {\n const {\n register,\n formState: { errors },\n } = useFormContext()\n\n return (\n \n )\n}\n\nfunction PaymentForm() {\n const {\n register,\n formState: { errors },\n } = useFormContext()\n\n return (\n \n )\n}\n\nfunction CompleteComponent() {\n return Thank you! Your order is complete.
\n}\n\nconst stepperInstance = defineStepper(\n {\n id: \"shipping\",\n title: \"Shipping\",\n schema: shippingSchema,\n Component: ShippingForm,\n },\n {\n id: \"payment\",\n title: \"Payment\",\n schema: paymentSchema,\n Component: PaymentForm,\n },\n {\n id: \"complete\",\n title: \"Complete\",\n schema: z.object({}),\n Component: CompleteComponent,\n }\n)\n\nexport default function StepperForm() {\n return (\n \n \n \n )\n}\n\nconst FormStepperComponent = () => {\n const { useStepper } = stepperInstance\n const methods = useStepper()\n\n const form = useForm({\n mode: \"onTouched\",\n resolver: zodResolver(methods.current.schema),\n })\n\n const onSubmit = (values: z.infer) => {\n console.log(`Form values for step ${methods.current.id}:`, values)\n }\n\n return (\n \n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/new-york/stepper-icon.json b/apps/www/public/r/styles/new-york/stepper-icon.json
index e9573a8f65e..d91ad347537 100644
--- a/apps/www/public/r/styles/new-york/stepper-icon.json
+++ b/apps/www/public/r/styles/new-york/stepper-icon.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-icon.tsx",
- "content": "import { HomeIcon, SettingsIcon, UserIcon } from \"lucide-react\"\n\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n icon: ,\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n icon: ,\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n icon: ,\n }\n)\n\nexport default function StepperIcon() {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n icon={step.icon}\n >\n {step.title}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\nimport { HomeIcon, SettingsIcon, UserIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n icon: ,\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n icon: ,\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n icon: ,\n }\n)\n\nexport default function StepperDemo() {\n return (\n \n {({ methods }) => (\n \n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n icon={step.icon}\n >\n {step.title}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/new-york/stepper-label-orientation.json b/apps/www/public/r/styles/new-york/stepper-label-orientation.json
index c6e985863df..d5005d0045b 100644
--- a/apps/www/public/r/styles/new-york/stepper-label-orientation.json
+++ b/apps/www/public/r/styles/new-york/stepper-label-orientation.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-label-orientation.tsx",
- "content": "import * as React from \"react\"\n\nimport { Label } from \"@/registry/new-york/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/new-york/ui/radio-group\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\ntype LabelOrientation = \"horizontal\" | \"vertical\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperVariants() {\n const steps = stepperInstance.steps\n\n const [labelOrientation, setLabelOrientation] =\n React.useState(\"horizontal\")\n return (\n \n
\n setLabelOrientation(value as LabelOrientation)\n }\n >\n \n \n \n
\n \n \n \n
\n \n
\n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n
\n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport { Label } from \"@/registry/new-york/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/new-york/ui/radio-group\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\ntype LabelOrientation = \"horizontal\" | \"vertical\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperVariants() {\n const [labelOrientation, setLabelOrientation] =\n React.useState(\"horizontal\")\n return (\n \n
\n setLabelOrientation(value as LabelOrientation)\n }\n >\n \n \n \n
\n \n \n \n
\n \n
\n {({ methods }) => (\n \n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n
\n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/new-york/stepper-responsive-variant.json b/apps/www/public/r/styles/new-york/stepper-responsive-variant.json
index 0b858184023..0800e76a9e6 100644
--- a/apps/www/public/r/styles/new-york/stepper-responsive-variant.json
+++ b/apps/www/public/r/styles/new-york/stepper-responsive-variant.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-responsive-variant.tsx",
- "content": "import { useMediaQuery } from \"@/hooks/use-media-query\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperResponsiveVariant() {\n const steps = stepperInstance.steps\n const isMobile = useMediaQuery(\"(max-width: 768px)\")\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {isMobile && (\n \n {({ step }) => (\n \n Content for {step.id}\n
\n )}\n \n )}\n \n ))}\n \n {!isMobile &&\n steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { useMediaQuery } from \"@/hooks/use-media-query\"\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperResponsiveVariant() {\n const isMobile = useMediaQuery(\"(max-width: 768px)\")\n return (\n \n {({ methods }) => (\n <>\n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {isMobile &&\n methods.when(step.id, (step) => (\n \n \n Content for {step.id}\n
\n \n ))}\n \n ))}\n \n {!isMobile &&\n methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n >\n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/new-york/stepper-tracking.json b/apps/www/public/r/styles/new-york/stepper-tracking.json
index 1b8733dc0ed..bb990294c11 100644
--- a/apps/www/public/r/styles/new-york/stepper-tracking.json
+++ b/apps/www/public/r/styles/new-york/stepper-tracking.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-tracking.tsx",
- "content": "import * as React from \"react\"\n\nimport { Label } from \"@/registry/new-york/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/new-york/ui/radio-group\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n },\n {\n id: \"step-4\",\n title: \"Step 4\",\n },\n {\n id: \"step-5\",\n title: \"Step 5\",\n },\n {\n id: \"step-6\",\n title: \"Step 6\",\n }\n)\n\nexport default function StepperVerticalFollow() {\n const steps = stepperInstance.steps\n\n const [tracking, setTracking] = React.useState(false)\n return (\n \n
setTracking(value === \"true\")}\n >\n \n \n \n
\n \n \n \n
\n \n
\n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n \n
\n Content for {step.id}\n
\n
\n \n Previous\n Next\n Reset\n \n \n \n ))}\n \n >\n )}\n \n
\n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport { Label } from \"@/registry/new-york/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/new-york/ui/radio-group\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n },\n {\n id: \"step-4\",\n title: \"Step 4\",\n },\n {\n id: \"step-5\",\n title: \"Step 5\",\n },\n {\n id: \"step-6\",\n title: \"Step 6\",\n }\n)\n\nexport default function StepperVerticalFollow() {\n const [tracking, setTracking] = React.useState(false)\n return (\n \n
setTracking(value === \"true\")}\n >\n \n \n \n
\n \n \n \n
\n \n
\n {({ methods }) => (\n <>\n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {methods.when(step.id, () => (\n \n \n
\n Content for {step.id}\n
\n
\n \n {!methods.isLast && (\n \n )}\n \n \n \n ))}\n \n ))}\n \n >\n )}\n \n
\n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/new-york/stepper-variants.json b/apps/www/public/r/styles/new-york/stepper-variants.json
index fa53f00b7ee..b158ed315d5 100644
--- a/apps/www/public/r/styles/new-york/stepper-variants.json
+++ b/apps/www/public/r/styles/new-york/stepper-variants.json
@@ -9,7 +9,7 @@
"files": [
{
"path": "examples/stepper-variants.tsx",
- "content": "import * as React from \"react\"\n\nimport { Label } from \"@/registry/new-york/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/new-york/ui/radio-group\"\nimport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\ntype Variant = \"horizontal\" | \"vertical\" | \"circle\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperVariants() {\n const steps = stepperInstance.steps\n\n const [variant, setVariant] = React.useState(\"horizontal\")\n return (\n \n
setVariant(value as Variant)}\n >\n \n \n \n
\n \n \n \n
\n \n \n \n
\n \n {variant === \"horizontal\" &&
}\n {variant === \"vertical\" &&
}\n {variant === \"circle\" &&
}\n
\n )\n}\n\nconst HorizontalStepper = () => {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n\nconst VerticalStepper = () => {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n \n ))}\n \n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n\nconst CircleStepper = () => {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n <>\n \n \n {methods.current.title}\n \n \n {steps.map((step) => (\n \n {({ step }) => (\n Content for {step.id}
\n )}\n \n ))}\n \n Previous\n Next\n Reset\n \n >\n )}\n \n )\n}\n",
+ "content": "import * as React from \"react\"\n\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport { Label } from \"@/registry/new-york/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/new-york/ui/radio-group\"\nimport {\n Stepper,\n StepperControls,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n} from \"@/registry/new-york/ui/stepper\"\n\ntype Variant = \"horizontal\" | \"vertical\" | \"circle\"\n\nconst stepperInstance = defineStepper(\n {\n id: \"step-1\",\n title: \"Step 1\",\n },\n {\n id: \"step-2\",\n title: \"Step 2\",\n },\n {\n id: \"step-3\",\n title: \"Step 3\",\n }\n)\n\nexport default function StepperVariants() {\n const [variant, setVariant] = React.useState(\"horizontal\")\n return (\n \n
setVariant(value as Variant)}\n >\n \n \n \n
\n \n \n \n
\n \n \n \n
\n \n {variant === \"horizontal\" &&
}\n {variant === \"vertical\" &&
}\n {variant === \"circle\" &&
}\n
\n )\n}\n\nconst HorizontalStepper = () => {\n const steps = stepperInstance.steps\n return (\n \n {({ methods }) => (\n \n \n {steps.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n \n ))}\n \n {methods.switch({\n \"step-1\": (step) => ,\n \"step-2\": (step) => ,\n \"step-3\": (step) => ,\n })}\n \n {!methods.isLast && (\n \n )}\n \n \n \n )}\n \n )\n}\n\nconst Content = ({ id }: { id: string }) => {\n return (\n \n Content for {id}
\n \n )\n}\n\nconst VerticalStepper = () => {\n return (\n \n {({ methods }) => (\n <>\n \n {methods.all.map((step) => (\n methods.goTo(step.id)}\n >\n {step.title}\n {methods.when(step.id, () => (\n \n Content for {step.id}
\n \n ))}\n \n ))}\n \n \n {!methods.isLast && (\n \n )}\n \n \n >\n )}\n \n )\n}\n\nconst CircleStepper = () => {\n return (\n \n {({ methods }) => (\n <>\n \n \n {methods.current.title}\n \n \n {methods.when(methods.current.id, () => (\n \n \n Content for {methods.current.id}\n
\n \n ))}\n \n {!methods.isLast && (\n \n )}\n \n \n >\n )}\n \n )\n}\n",
"type": "registry:example",
"target": ""
}
diff --git a/apps/www/public/r/styles/new-york/stepper.json b/apps/www/public/r/styles/new-york/stepper.json
index a1ba04d15ee..df1a9f4d3a5 100644
--- a/apps/www/public/r/styles/new-york/stepper.json
+++ b/apps/www/public/r/styles/new-york/stepper.json
@@ -14,7 +14,7 @@
"files": [
{
"path": "ui/stepper.tsx",
- "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport * as Stepperize from \"@stepperize/react\"\nimport { VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york/ui/button\"\n\ntype StepperProviderProps = StepperConfig & {\n children: React.ReactNode\n}\n\ntype StepperVariant = \"horizontal\" | \"vertical\" | \"circle\"\ntype StepperLabelOrientation = \"horizontal\" | \"vertical\"\n\ntype StepperConfig = {\n instance: ReturnType>\n variant?: StepperVariant\n labelOrientation?: StepperLabelOrientation\n tracking?: boolean\n}\n\nconst StepContext = React.createContext>({\n instance: {} as ReturnType>,\n variant: \"horizontal\",\n})\n\nconst StepperProvider = ({\n children,\n ...props\n}: StepperProviderProps) => {\n const Scope = props.instance.Scoped\n return (\n \n {children}\n \n )\n}\n\nconst useStepper = (): StepperConfig => {\n const context = React.useContext(StepContext)\n if (!context) {\n throw new Error(\"useStepper must be used within a Stepper\")\n }\n return context\n}\n\nfunction Stepper({\n children,\n variant = \"horizontal\",\n className,\n labelOrientation = \"horizontal\",\n tracking = false,\n ...props\n}: StepperConfig &\n Omit, \"children\"> & {\n children:\n | React.ReactNode\n | ((props: { methods: Stepperize.Stepper }) => React.ReactNode)\n }) {\n const { instance } = props\n\n const methods = instance.useStepper() as Stepperize.Stepper\n\n return (\n \n \n {typeof children === \"function\" ? children({ methods }) : children}\n
\n \n )\n}\n\nconst StepperNavigation = ({\n children,\n className,\n \"aria-label\": ariaLabel = \"Stepper Navigation\",\n ...props\n}: Omit, \"children\"> & {\n children: React.ReactNode\n}) => {\n const { variant, instance } = useStepper()\n\n const methods = instance.useStepper() as Stepperize.Stepper\n\n return (\n \n )\n}\n\nconst listVariants = cva(\"stepper-navigation-list flex gap-2\", {\n variants: {\n variant: {\n horizontal: \"flex-row items-center justify-between\",\n vertical: \"flex-col\",\n circle: \"flex-row items-center justify-between\",\n },\n },\n})\n\nconst StepperStep = ({\n children,\n className,\n of,\n icon,\n ...props\n}: React.ComponentProps<\"button\"> & { of: T; icon?: Icon }) => {\n const id = React.useId()\n const { instance, variant, labelOrientation } = useStepper()\n\n const methods = instance.useStepper() as Stepperize.Stepper\n\n const currentStep = methods.current\n\n const isLast = instance.utils.getLast().id === of.id\n const stepIndex = instance.utils.getIndex(of.id)\n const currentIndex = instance.utils.getIndex(currentStep?.id ?? \"\")\n const isActive = currentStep?.id === of.id\n\n const dataState = getStepState(currentIndex, stepIndex)\n const childMap = useStepChildren(children)\n\n const title = childMap.get(\"title\")\n const description = childMap.get(\"description\")\n const panel = childMap.get(\"panel\")\n\n if (variant === \"circle\") {\n return (\n \n \n \n {title}\n {description}\n
\n \n )\n }\n\n return (\n <>\n \n \n {variant === \"horizontal\" && labelOrientation === \"vertical\" && (\n \n )}\n \n {title}\n {description}\n
\n \n\n {variant === \"horizontal\" && labelOrientation === \"horizontal\" && (\n \n )}\n\n {variant === \"vertical\" && (\n \n {!isLast && (\n
\n \n
\n )}\n
{panel}
\n
\n )}\n >\n )\n}\n\nconst StepperSeparator = ({\n orientation,\n isLast,\n labelOrientation,\n state,\n disabled,\n}: {\n isLast: boolean\n state: string\n disabled?: boolean\n} & VariantProps) => {\n if (isLast) return null\n return (\n \n )\n}\n\nconst classForSeparator = cva(\n [\n \"bg-muted\",\n \"data-[state=completed]:bg-primary data-[disabled]:opacity-50\",\n \"transition-all duration-300 ease-in-out\",\n ],\n {\n variants: {\n orientation: {\n horizontal: \"h-0.5 flex-1\",\n vertical: \"h-full w-0.5\",\n },\n labelOrientation: {\n vertical:\n \"absolute left-[calc(50%+30px)] right-[calc(-50%+20px)] top-5 block shrink-0\",\n },\n },\n }\n)\n\nconst onStepKeyDown = (\n e: React.KeyboardEvent,\n nextStep: Stepperize.Step,\n prevStep: Stepperize.Step\n) => {\n const { key } = e\n const directions = {\n next: [\"ArrowRight\", \"ArrowDown\"],\n prev: [\"ArrowLeft\", \"ArrowUp\"],\n }\n\n if (directions.next.includes(key) || directions.prev.includes(key)) {\n const direction = directions.next.includes(key) ? \"next\" : \"prev\"\n const step = direction === \"next\" ? nextStep : prevStep\n\n if (!step) return\n\n const stepElement = document.getElementById(`step-${step.id}`)\n if (!stepElement) return\n\n const isActive =\n stepElement.parentElement?.getAttribute(\"data-state\") !== \"inactive\"\n if (isActive || direction === \"prev\") {\n stepElement.focus()\n }\n }\n}\n\nconst getStepState = (currentIndex: number, stepIndex: number) => {\n if (currentIndex === stepIndex) return \"active\"\n if (currentIndex > stepIndex) return \"completed\"\n return \"inactive\"\n}\n\nconst extractChildren = (children: React.ReactNode) => {\n const childrenArray = React.Children.toArray(children)\n const map = new Map()\n\n for (const child of childrenArray) {\n if (React.isValidElement(child)) {\n if (child.type === StepperTitle) {\n map.set(\"title\", child)\n } else if (child.type === StepperDescription) {\n map.set(\"description\", child)\n } else if (child.type === StepperPanel) {\n map.set(\"panel\", child)\n }\n }\n }\n\n return map\n}\n\nconst useStepChildren = (children: React.ReactNode) => {\n return React.useMemo(() => extractChildren(children), [children])\n}\n\nconst StepperTitle = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"h4\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"h4\"\n\n return (\n \n {children}\n \n )\n}\n\nconst StepperDescription = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"p\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"p\"\n\n return (\n \n {children}\n \n )\n}\n\ntype CircleStepIndicatorProps = {\n currentStep: number\n totalSteps: number\n size?: number\n strokeWidth?: number\n}\n\nconst CircleStepIndicator = ({\n currentStep,\n totalSteps,\n size = 80,\n strokeWidth = 6,\n}: CircleStepIndicatorProps) => {\n const radius = (size - strokeWidth) / 2\n const circumference = radius * 2 * Math.PI\n const fillPercentage = (currentStep / totalSteps) * 100\n const dashOffset = circumference - (circumference * fillPercentage) / 100\n\n return (\n \n
\n
\n \n {currentStep} of {totalSteps}\n \n
\n
\n )\n}\n\nconst StepperPanel = ({\n children,\n className,\n when,\n asChild,\n ...props\n}: Omit, \"children\"> & {\n asChild?: boolean\n when: T\n children:\n | React.ReactNode\n | ((props: {\n step: T\n onBeforeAction: (\n action: StepAction,\n callback: (params: {\n prevStep: Stepperize.Step\n nextStep: Stepperize.Step\n }) => Promise | boolean\n ) => void\n }) => React.ReactNode)\n}) => {\n const Comp = asChild ? Slot : \"div\"\n const { instance, tracking } = useStepper()\n\n const methods = instance.useStepper()\n\n if (instance.utils.getIndex(when.id) === -1) {\n throw new Error(`Step ${when.id} does not exist in the stepper instance`)\n }\n\n const onBeforeAction = React.useCallback(\n async (\n action: StepAction,\n callback: (params: {\n prevStep: Stepperize.Step\n nextStep: Stepperize.Step\n }) => Promise | boolean\n ) => {\n const prevStep = methods.current\n const nextStep =\n action === \"next\"\n ? instance.utils.getNext(prevStep.id)\n : action === \"prev\"\n ? instance.utils.getPrev(prevStep.id)\n : instance.utils.getFirst()\n\n const shouldProceed = await callback({ prevStep, nextStep })\n if (shouldProceed) {\n if (action === \"next\") methods.next()\n if (action === \"prev\") methods.prev()\n if (action === \"reset\") methods.reset()\n }\n },\n [methods, instance.utils]\n )\n\n return (\n <>\n {methods.when(when.id, (step) => (\n scrollIntoStepperPanel(node, tracking)}\n {...props}\n >\n {typeof children === \"function\"\n ? children({ step: step as T, onBeforeAction })\n : children}\n \n ))}\n >\n )\n}\n\nfunction scrollIntoStepperPanel(\n node: HTMLDivElement | null,\n tracking?: boolean\n) {\n if (tracking) {\n node?.scrollIntoView({ behavior: \"smooth\", block: \"center\" })\n }\n}\n\nconst StepperControls = ({\n children,\n asChild,\n className,\n ...props\n}: Omit, \"children\"> & {\n asChild?: boolean\n children:\n | React.ReactNode\n | ((props: {\n methods: Stepperize.Stepper\n }) => React.ReactNode)\n}) => {\n const Comp = asChild ? Slot : \"div\"\n const { instance } = useStepper()\n\n const methods = instance.useStepper()\n\n return (\n \n {typeof children === \"function\" ? children({ methods }) : children}\n \n )\n}\n\ntype StepAction = \"next\" | \"prev\" | \"reset\"\n\ntype StepperActionProps = {\n action: StepAction\n children: React.ReactNode\n asChild?: boolean\n onBeforeAction?: ({\n event,\n prevStep,\n nextStep,\n }: {\n event: React.MouseEvent\n prevStep: Stepperize.Step\n nextStep: Stepperize.Step\n }) => Promise | boolean\n className?: string\n}\n\nconst StepperAction = ({\n action,\n children,\n asChild = false,\n onBeforeAction,\n className,\n disabled,\n ...props\n}: React.ComponentProps<\"button\"> & StepperActionProps) => {\n const { instance } = useStepper()\n const methods = instance.useStepper()\n\n const currentStep = methods.current\n\n const isDisabled = (action: StepAction) =>\n action === \"prev\" && methods.isFirst\n\n const actionMap = React.useMemo(\n () => ({\n next: methods.next,\n prev: methods.prev,\n reset: methods.reset,\n }),\n [methods]\n )\n\n const handleClick = React.useCallback(\n async (event: React.MouseEvent) => {\n if (onBeforeAction) {\n const nextStep =\n action === \"next\"\n ? instance.utils.getNext(currentStep.id)\n : action === \"prev\"\n ? instance.utils.getPrev(currentStep.id)\n : instance.utils.getFirst()\n const shouldProceed = await onBeforeAction({\n event,\n prevStep: currentStep,\n nextStep,\n })\n if (!shouldProceed) {\n return\n }\n }\n\n actionMap[action]?.()\n },\n [onBeforeAction, actionMap, action, instance.utils, currentStep]\n )\n\n const Comp = asChild ? Slot : Button\n\n if (\n (methods.isLast && (action === \"next\" || action === \"prev\")) ||\n (!methods.isLast && action === \"reset\")\n ) {\n return null\n }\n\n return (\n \n {children}\n \n )\n}\n\nconst defineStepper: typeof Stepperize.defineStepper = Stepperize.defineStepper\n\nexport {\n Stepper,\n StepperAction,\n StepperControls,\n StepperDescription,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n defineStepper,\n}\n",
+ "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport * as Stepperize from \"@stepperize/react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york/ui/button\"\n\ntype StepperVariant = \"horizontal\" | \"vertical\" | \"circle\"\ntype StepperLabelOrientation = \"horizontal\" | \"vertical\"\n\ntype StepperConfig = {\n instance: ReturnType>\n variant?: StepperVariant\n labelOrientation?: StepperLabelOrientation\n tracking?: boolean\n}\n\ntype StepperProviderProps = StepperConfig & {\n children: React.ReactNode\n}\n\nconst StepContext = React.createContext | null>(null)\n\nconst StepperProvider = ({\n children,\n ...props\n}: StepperProviderProps) => {\n const { instance } = props\n const Scoped = instance.Scoped\n return (\n \n {children}\n \n )\n}\n\nconst useStepper = (): StepperConfig => {\n const context = React.useContext(StepContext)\n if (!context) {\n throw new Error(\"useStepper must be used within a StepperProvider.\")\n }\n return context\n}\n\ntype StepperProps = StepperConfig &\n Omit, \"children\"> & {\n children:\n | React.ReactNode\n | ((props: { methods: Stepperize.Stepper }) => React.ReactNode)\n }\n\nconst Stepper = ({\n children,\n variant = \"horizontal\",\n labelOrientation = \"horizontal\",\n tracking = false,\n instance,\n ...props\n}: StepperProps) => (\n \n {children}\n \n)\n\nconst StepperContainer = ({\n children,\n className,\n ...props\n}: Omit, \"children\"> & {\n children:\n | React.ReactNode\n | ((props: { methods: Stepperize.Stepper }) => React.ReactNode)\n}) => {\n const { instance } = useStepper()\n const methods = instance.useStepper()\n\n return (\n \n {typeof children === \"function\" ? children({ methods }) : children}\n
\n )\n}\n\nconst StepperNavigation = ({\n children,\n className,\n \"aria-label\": ariaLabel = \"Stepper Navigation\",\n ...props\n}: Omit, \"children\"> & {\n children: React.ReactNode\n}) => {\n const { variant } = useStepper()\n\n return (\n \n )\n}\n\nconst listVariants = cva(\"stepper-navigation-list flex gap-2\", {\n variants: {\n variant: {\n horizontal: \"flex-row items-center justify-between\",\n vertical: \"flex-col\",\n circle: \"flex-row items-center justify-between\",\n },\n },\n})\n\nconst StepperStep = ({\n children,\n className,\n of,\n icon,\n ...props\n}: React.ComponentProps<\"button\"> & { of: T; icon?: Icon }) => {\n const { instance, variant, labelOrientation } = useStepper()\n\n const methods = instance.useStepper()\n\n const currentStep = methods.current\n\n const isLast = instance.utils.getLast().id === of.id\n const stepIndex = instance.utils.getIndex(of.id)\n const currentIndex = instance.utils.getIndex(currentStep?.id ?? \"\")\n const isActive = currentStep?.id === of.id\n\n const dataState = getStepState(currentIndex, stepIndex)\n const childMap = useStepChildren(children)\n\n const title = childMap.get(\"title\")\n const description = childMap.get(\"description\")\n const panel = childMap.get(\"panel\")\n\n if (variant === \"circle\") {\n return (\n \n \n \n {title}\n {description}\n
\n \n )\n }\n\n return (\n <>\n \n \n {variant === \"horizontal\" && labelOrientation === \"vertical\" && (\n \n )}\n \n {title}\n {description}\n
\n \n\n {variant === \"horizontal\" && labelOrientation === \"horizontal\" && (\n \n )}\n\n {variant === \"vertical\" && (\n \n {!isLast && (\n
\n \n
\n )}\n
{panel}
\n
\n )}\n >\n )\n}\n\nconst StepperSeparator = ({\n orientation,\n isLast,\n labelOrientation,\n state,\n disabled,\n}: {\n isLast: boolean\n state: string\n disabled?: boolean\n} & VariantProps) => {\n if (isLast) {\n return null\n }\n return (\n \n )\n}\n\nconst classForSeparator = cva(\n [\n \"bg-muted\",\n \"data-[state=completed]:bg-primary data-[disabled]:opacity-50\",\n \"transition-all duration-300 ease-in-out\",\n ],\n {\n variants: {\n orientation: {\n horizontal: \"h-0.5 flex-1\",\n vertical: \"h-full w-0.5\",\n },\n labelOrientation: {\n vertical:\n \"absolute left-[calc(50%+30px)] right-[calc(-50%+20px)] top-5 block shrink-0\",\n },\n },\n }\n)\n\nconst onStepKeyDown = (\n e: React.KeyboardEvent,\n nextStep: Stepperize.Step,\n prevStep: Stepperize.Step\n) => {\n const { key } = e\n const directions = {\n next: [\"ArrowRight\", \"ArrowDown\"],\n prev: [\"ArrowLeft\", \"ArrowUp\"],\n }\n\n if (directions.next.includes(key) || directions.prev.includes(key)) {\n const direction = directions.next.includes(key) ? \"next\" : \"prev\"\n const step = direction === \"next\" ? nextStep : prevStep\n\n if (!step) {\n return\n }\n\n const stepElement = document.getElementById(`step-${step.id}`)\n if (!stepElement) {\n return\n }\n\n const isActive =\n stepElement.parentElement?.getAttribute(\"data-state\") !== \"inactive\"\n if (isActive || direction === \"prev\") {\n stepElement.focus()\n }\n }\n}\n\nconst getStepState = (currentIndex: number, stepIndex: number) => {\n if (currentIndex === stepIndex) {\n return \"active\"\n }\n if (currentIndex > stepIndex) {\n return \"completed\"\n }\n return \"inactive\"\n}\n\nconst extractChildren = (children: React.ReactNode) => {\n const childrenArray = React.Children.toArray(children)\n const map = new Map()\n\n for (const child of childrenArray) {\n if (React.isValidElement(child)) {\n if (child.type === StepperTitle) {\n map.set(\"title\", child)\n } else if (child.type === StepperDescription) {\n map.set(\"description\", child)\n } else if (child.type === StepperPanel) {\n map.set(\"panel\", child)\n }\n }\n }\n\n return map\n}\n\nconst useStepChildren = (children: React.ReactNode) => {\n return React.useMemo(() => extractChildren(children), [children])\n}\n\nconst StepperTitle = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"h4\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"h4\"\n\n return (\n \n {children}\n \n )\n}\n\nconst StepperDescription = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"p\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"p\"\n\n return (\n \n {children}\n \n )\n}\n\ntype CircleStepIndicatorProps = {\n currentStep: number\n totalSteps: number\n size?: number\n strokeWidth?: number\n}\n\nconst CircleStepIndicator = ({\n currentStep,\n totalSteps,\n size = 80,\n strokeWidth = 6,\n}: CircleStepIndicatorProps) => {\n const radius = (size - strokeWidth) / 2\n const circumference = radius * 2 * Math.PI\n const fillPercentage = (currentStep / totalSteps) * 100\n const dashOffset = circumference - (circumference * fillPercentage) / 100\n return (\n \n
\n
\n \n {currentStep} of {totalSteps}\n \n
\n
\n )\n}\n\nconst StepperPanel = ({\n children,\n className,\n asChild,\n ...props\n}: React.ComponentProps<\"div\"> & {\n asChild?: boolean\n}) => {\n const Comp = asChild ? Slot : \"div\"\n const { tracking } = useStepper()\n\n return (\n scrollIntoStepperPanel(node, tracking)}\n {...props}\n >\n {children}\n \n )\n}\n\nfunction scrollIntoStepperPanel(\n node: HTMLDivElement | null,\n tracking?: boolean\n) {\n if (tracking) {\n node?.scrollIntoView({ behavior: \"smooth\", block: \"center\" })\n }\n}\n\nconst StepperControls = ({\n children,\n asChild,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : \"div\"\n return (\n \n {children}\n \n )\n}\n\nconst defineStepper: typeof Stepperize.defineStepper = Stepperize.defineStepper\n\nexport {\n defineStepper,\n Stepper,\n StepperControls,\n StepperDescription,\n StepperNavigation,\n StepperPanel,\n StepperStep,\n StepperTitle,\n}\n",
"type": "registry:ui",
"target": ""
}
diff --git a/apps/www/registry/default/examples/stepper-demo.tsx b/apps/www/registry/default/examples/stepper-demo.tsx
index d77ef0677c3..50bf927e75b 100644
--- a/apps/www/registry/default/examples/stepper-demo.tsx
+++ b/apps/www/registry/default/examples/stepper-demo.tsx
@@ -1,6 +1,8 @@
+import * as React from "react"
+
+import { Button } from "@/registry/default/ui/button"
import {
Stepper,
- StepperAction,
StepperControls,
StepperNavigation,
StepperPanel,
@@ -25,7 +27,6 @@ const stepperInstance = defineStepper(
)
export default function StepperDemo() {
- const steps = stepperInstance.steps
return (
{({ methods }) => (
- <>
+
- {steps.map((step) => (
+ {methods.all.map((step) => (
))}
- {steps.map((step) => (
-
- {({ step }) => (
- Content for {step.id}
- )}
-
- ))}
+ {methods.switch({
+ "step-1": (step) => ,
+ "step-2": (step) => ,
+ "step-3": (step) => ,
+ })}
- Previous
- Next
- Reset
+ {!methods.isLast && (
+
+ )}
+
- >
+
)}
)
}
+
+const Content = ({ id }: { id: string }) => {
+ return (
+
+ Content for {id}
+
+ )
+}
diff --git a/apps/www/registry/default/examples/stepper-description.tsx b/apps/www/registry/default/examples/stepper-description.tsx
index 5bb54592c7b..f28f20a384b 100644
--- a/apps/www/registry/default/examples/stepper-description.tsx
+++ b/apps/www/registry/default/examples/stepper-description.tsx
@@ -1,6 +1,8 @@
+import * as React from "react"
+
+import { Button } from "@/registry/default/ui/button"
import {
Stepper,
- StepperAction,
StepperControls,
StepperDescription,
StepperNavigation,
@@ -29,7 +31,6 @@ const stepperInstance = defineStepper(
)
export default function StepperDemo() {
- const steps = stepperInstance.steps
return (
{({ methods }) => (
- <>
+
- {steps.map((step) => (
+ {methods.all.map((step) => (
))}
- {steps.map((step) => (
-
- {({ step }) => (
- Content for {step.id}
- )}
-
- ))}
+ {methods.switch({
+ "step-1": (step) => ,
+ "step-2": (step) => ,
+ "step-3": (step) => ,
+ })}
- Previous
- Next
- Reset
+ {!methods.isLast && (
+
+ )}
+
- >
+
)}
)
}
+
+const Content = ({ id }: { id: string }) => {
+ return (
+
+ Content for {id}
+
+ )
+}
diff --git a/apps/www/registry/default/examples/stepper-form.tsx b/apps/www/registry/default/examples/stepper-form.tsx
index a5c3184d98a..dbbbdb069d7 100644
--- a/apps/www/registry/default/examples/stepper-form.tsx
+++ b/apps/www/registry/default/examples/stepper-form.tsx
@@ -1,12 +1,13 @@
+import * as React from "react"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm, useFormContext } from "react-hook-form"
import { z } from "zod"
+import { Button } from "@/registry/default/ui/button"
import { Form } from "@/registry/default/ui/form"
import { Input } from "@/registry/default/ui/input"
import {
Stepper,
- StepperAction,
StepperControls,
StepperNavigation,
StepperStep,
@@ -29,93 +30,6 @@ const paymentSchema = z.object({
type ShippingFormValues = z.infer
type PaymentFormValues = z.infer
-const stepperInstance = defineStepper(
- {
- id: "shipping",
- title: "Shipping",
- schema: shippingSchema,
- },
- {
- id: "payment",
- title: "Payment",
- schema: paymentSchema,
- },
- {
- id: "complete",
- title: "Complete",
- schema: z.object({}),
- }
-)
-
-export default function StepperForm() {
- return (
-
-
-
- )
-}
-
-const FormStepperComponent = () => {
- const { steps, useStepper, utils } = stepperInstance
- const methods = useStepper()
-
- const form = useForm({
- mode: "onTouched",
- resolver: zodResolver(methods.current.schema),
- })
-
- const onSubmit = (values: z.infer) => {
- console.log(`Form values for step ${methods.current.id}:`, values)
- }
-
- const currentIndex = utils.getIndex(methods.current.id)
-
- return (
-
-
- )
-}
-
const ShippingForm = () => {
const {
register,
@@ -249,3 +163,100 @@ function PaymentForm() {
function CompleteComponent() {
return Thank you! Your order is complete.
}
+
+const stepperInstance = defineStepper(
+ {
+ id: "shipping",
+ title: "Shipping",
+ schema: shippingSchema,
+ Component: ShippingForm,
+ },
+ {
+ id: "payment",
+ title: "Payment",
+ schema: paymentSchema,
+ Component: PaymentForm,
+ },
+ {
+ id: "complete",
+ title: "Complete",
+ schema: z.object({}),
+ Component: CompleteComponent,
+ }
+)
+
+export default function StepperForm() {
+ return (
+
+
+
+ )
+}
+
+const FormStepperComponent = () => {
+ const { useStepper } = stepperInstance
+ const methods = useStepper()
+
+ const form = useForm({
+ mode: "onTouched",
+ resolver: zodResolver(methods.current.schema),
+ })
+
+ const onSubmit = (values: z.infer) => {
+ console.log(`Form values for step ${methods.current.id}:`, values)
+ }
+
+ return (
+
+
+ )
+}
diff --git a/apps/www/registry/default/examples/stepper-icon.tsx b/apps/www/registry/default/examples/stepper-icon.tsx
index 45caf09fb9e..a6039f007ee 100644
--- a/apps/www/registry/default/examples/stepper-icon.tsx
+++ b/apps/www/registry/default/examples/stepper-icon.tsx
@@ -1,8 +1,9 @@
+import * as React from "react"
import { HomeIcon, SettingsIcon, UserIcon } from "lucide-react"
+import { Button } from "@/registry/default/ui/button"
import {
Stepper,
- StepperAction,
StepperControls,
StepperNavigation,
StepperPanel,
@@ -29,8 +30,7 @@ const stepperInstance = defineStepper(
}
)
-export default function StepperIcon() {
- const steps = stepperInstance.steps
+export default function StepperDemo() {
return (
{({ methods }) => (
- <>
+
- {steps.map((step) => (
+ {methods.all.map((step) => (
))}
- {steps.map((step) => (
-
- {({ step }) => (
- Content for {step.id}
- )}
-
- ))}
+ {methods.switch({
+ "step-1": (step) => ,
+ "step-2": (step) => ,
+ "step-3": (step) => ,
+ })}
- Previous
- Next
- Reset
+ {!methods.isLast && (
+
+ )}
+
- >
+
)}
)
}
+
+const Content = ({ id }: { id: string }) => {
+ return (
+
+ Content for {id}
+
+ )
+}
diff --git a/apps/www/registry/default/examples/stepper-label-orientation.tsx b/apps/www/registry/default/examples/stepper-label-orientation.tsx
index 136a02d15d4..f50027a9695 100644
--- a/apps/www/registry/default/examples/stepper-label-orientation.tsx
+++ b/apps/www/registry/default/examples/stepper-label-orientation.tsx
@@ -1,10 +1,10 @@
import * as React from "react"
+import { Button } from "@/registry/default/ui/button"
import { Label } from "@/registry/default/ui/label"
import { RadioGroup, RadioGroupItem } from "@/registry/default/ui/radio-group"
import {
Stepper,
- StepperAction,
StepperControls,
StepperNavigation,
StepperPanel,
@@ -31,8 +31,6 @@ const stepperInstance = defineStepper(
)
export default function StepperVariants() {
- const steps = stepperInstance.steps
-
const [labelOrientation, setLabelOrientation] =
React.useState("horizontal")
return (
@@ -59,9 +57,9 @@ export default function StepperVariants() {
labelOrientation={labelOrientation}
>
{({ methods }) => (
- <>
+
- {steps.map((step) => (
+ {methods.all.map((step) => (
))}
- {steps.map((step) => (
-
- {({ step }) => (
- Content for {step.id}
- )}
-
- ))}
+ {methods.switch({
+ "step-1": (step) => ,
+ "step-2": (step) => ,
+ "step-3": (step) => ,
+ })}
- Previous
- Next
- Reset
+ {!methods.isLast && (
+
+ )}
+
- >
+
)}
)
}
+
+const Content = ({ id }: { id: string }) => {
+ return (
+
+ Content for {id}
+
+ )
+}
diff --git a/apps/www/registry/default/examples/stepper-responsive-variant.tsx b/apps/www/registry/default/examples/stepper-responsive-variant.tsx
index 85fb106db93..5f2cc917961 100644
--- a/apps/www/registry/default/examples/stepper-responsive-variant.tsx
+++ b/apps/www/registry/default/examples/stepper-responsive-variant.tsx
@@ -1,7 +1,9 @@
+import * as React from "react"
+
import { useMediaQuery } from "@/hooks/use-media-query"
+import { Button } from "@/registry/default/ui/button"
import {
Stepper,
- StepperAction,
StepperControls,
StepperNavigation,
StepperPanel,
@@ -26,7 +28,6 @@ const stepperInstance = defineStepper(
)
export default function StepperResponsiveVariant() {
- const steps = stepperInstance.steps
const isMobile = useMediaQuery("(max-width: 768px)")
return (
(
<>
- {steps.map((step) => (
+ {methods.all.map((step) => (
methods.goTo(step.id)}
>
{step.title}
- {isMobile && (
-
- {({ step }) => (
+ {isMobile &&
+ methods.when(step.id, (step) => (
+
Content for {step.id}
- )}
-
- )}
+
+ ))}
))}
{!isMobile &&
- steps.map((step) => (
-
- {({ step }) => (
- Content for {step.id}
- )}
-
- ))}
+ methods.switch({
+ "step-1": (step) => ,
+ "step-2": (step) => ,
+ "step-3": (step) => ,
+ })}
- Previous
- Next
- Reset
+ {!methods.isLast && (
+
+ )}
+
>
)}
)
}
+
+const Content = ({ id }: { id: string }) => {
+ return (
+
+ Content for {id}
+
+ )
+}
diff --git a/apps/www/registry/default/examples/stepper-tracking.tsx b/apps/www/registry/default/examples/stepper-tracking.tsx
index 9f8a550e06f..d745fdf4d34 100644
--- a/apps/www/registry/default/examples/stepper-tracking.tsx
+++ b/apps/www/registry/default/examples/stepper-tracking.tsx
@@ -1,10 +1,10 @@
import * as React from "react"
+import { Button } from "@/registry/default/ui/button"
import { Label } from "@/registry/default/ui/label"
import { RadioGroup, RadioGroupItem } from "@/registry/default/ui/radio-group"
import {
Stepper,
- StepperAction,
StepperControls,
StepperNavigation,
StepperPanel,
@@ -41,8 +41,6 @@ const stepperInstance = defineStepper(
)
export default function StepperVerticalFollow() {
- const steps = stepperInstance.steps
-
const [tracking, setTracking] = React.useState(false)
return (
@@ -68,25 +66,40 @@ export default function StepperVerticalFollow() {
{({ methods }) => (
<>
- {steps.map((step) => (
+ {methods.all.map((step) => (
methods.goTo(step.id)}
>
{step.title}
-
-
-
- Content for {step.id}
-
-
-
- Previous
- Next
- Reset
-
-
+ {methods.when(step.id, () => (
+
+
+
+ Content for {step.id}
+
+
+
+ {!methods.isLast && (
+
+ )}
+
+
+
+ ))}
))}
diff --git a/apps/www/registry/default/examples/stepper-variants.tsx b/apps/www/registry/default/examples/stepper-variants.tsx
index f8aaef2a02d..06c12a65141 100644
--- a/apps/www/registry/default/examples/stepper-variants.tsx
+++ b/apps/www/registry/default/examples/stepper-variants.tsx
@@ -1,10 +1,10 @@
import * as React from "react"
+import { Button } from "@/registry/default/ui/button"
import { Label } from "@/registry/default/ui/label"
import { RadioGroup, RadioGroupItem } from "@/registry/default/ui/radio-group"
import {
Stepper,
- StepperAction,
StepperControls,
StepperNavigation,
StepperPanel,
@@ -31,8 +31,6 @@ const stepperInstance = defineStepper(
)
export default function StepperVariants() {
- const steps = stepperInstance.steps
-
const [variant, setVariant] = React.useState
("horizontal")
return (
@@ -69,7 +67,7 @@ const HorizontalStepper = () => {
variant="horizontal"
>
{({ methods }) => (
- <>
+
{steps.map((step) => (
{
))}
- {steps.map((step) => (
-
- {({ step }) => (
- Content for {step.id}
- )}
-
- ))}
+ {methods.switch({
+ "step-1": (step) => ,
+ "step-2": (step) => ,
+ "step-3": (step) => ,
+ })}
- Previous
- Next
- Reset
+ {!methods.isLast && (
+
+ )}
+
- >
+
)}
)
}
+const Content = ({ id }: { id: string }) => {
+ return (
+
+ Content for {id}
+
+ )
+}
+
const VerticalStepper = () => {
- const steps = stepperInstance.steps
return (
{
{({ methods }) => (
<>
- {steps.map((step) => (
+ {methods.all.map((step) => (
methods.goTo(step.id)}
>
{step.title}
-
- {({ step }) => (
+ {methods.when(step.id, () => (
+
Content for {step.id}
- )}
-
+
+ ))}
))}
- Previous
- Next
- Reset
+ {!methods.isLast && (
+
+ )}
+
>
)}
@@ -145,7 +158,6 @@ const VerticalStepper = () => {
}
const CircleStepper = () => {
- const steps = stepperInstance.steps
return (
{({ methods }) => (
@@ -155,21 +167,26 @@ const CircleStepper = () => {
{methods.current.title}
- {steps.map((step) => (
-
- {({ step }) => (
- Content for {step.id}
- )}
+ {methods.when(methods.current.id, () => (
+
+
+ Content for {methods.current.id}
+
))}
- Previous
- Next
- Reset
+ {!methods.isLast && (
+
+ )}
+
>
)}
diff --git a/apps/www/registry/default/examples/stepper-with-description.tsx b/apps/www/registry/default/examples/stepper-with-description.tsx
deleted file mode 100644
index 5b50b9d014a..00000000000
--- a/apps/www/registry/default/examples/stepper-with-description.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-import {
- Stepper,
- StepperAction,
- StepperControls,
- StepperDescription,
- StepperNavigation,
- StepperPanel,
- StepperStep,
- StepperTitle,
- defineStepper,
-} from "@/registry/default/ui/stepper"
-
-const stepperInstance = defineStepper(
- {
- id: "step-1",
- title: "Step 1",
- description: "This is the first step",
- },
- {
- id: "step-2",
- title: "Step 2",
- description: "This is the second step",
- },
- {
- id: "step-3",
- title: "Step 3",
- description: "This is the third step",
- }
-)
-
-export default function StepperWithDescription() {
- const steps = stepperInstance.steps
- return (
-
- {({ methods }) => (
- <>
-
- {steps.map((step) => (
- methods.goTo(step.id)}
- >
- {step.title}
- {step.description}
-
- ))}
-
- {steps.map((step) => (
-
- {({ step }) => (
- Content for {step.id}
- )}
-
- ))}
-
- Previous
- Next
- Reset
-
- >
- )}
-
- )
-}
diff --git a/apps/www/registry/default/ui/stepper.tsx b/apps/www/registry/default/ui/stepper.tsx
index 77ebbc599d7..053155850ac 100644
--- a/apps/www/registry/default/ui/stepper.tsx
+++ b/apps/www/registry/default/ui/stepper.tsx
@@ -3,15 +3,11 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import * as Stepperize from "@stepperize/react"
-import { VariantProps, cva } from "class-variance-authority"
+import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { Button } from "@/registry/default/ui/button"
-type StepperProviderProps = StepperConfig & {
- children: React.ReactNode
-}
-
type StepperVariant = "horizontal" | "vertical" | "circle"
type StepperLabelOrientation = "horizontal" | "vertical"
@@ -22,59 +18,74 @@ type StepperConfig = {
tracking?: boolean
}
-const StepContext = React.createContext>({
- instance: {} as ReturnType>,
- variant: "horizontal",
-})
+type StepperProviderProps = StepperConfig & {
+ children: React.ReactNode
+}
+
+const StepContext = React.createContext | null>(null)
const StepperProvider = ({
children,
...props
}: StepperProviderProps) => {
- const Scope = props.instance.Scoped
+ const { instance } = props
+ const Scoped = instance.Scoped
return (
-
+
{children}
-
+
)
}
const useStepper = (): StepperConfig => {
const context = React.useContext(StepContext)
if (!context) {
- throw new Error("useStepper must be used within a Stepper")
+ throw new Error("useStepper must be used within a StepperProvider.")
}
return context
}
-function Stepper({
+type StepperProps = StepperConfig &
+ Omit, "children"> & {
+ children:
+ | React.ReactNode
+ | ((props: { methods: Stepperize.Stepper }) => React.ReactNode)
+ }
+
+const Stepper = ({
children,
variant = "horizontal",
- className,
labelOrientation = "horizontal",
tracking = false,
+ instance,
...props
-}: StepperConfig &
- Omit, "children"> & {
- children:
- | React.ReactNode
- | ((props: { methods: Stepperize.Stepper }) => React.ReactNode)
- }) {
- const { instance } = props
+}: StepperProps) => (
+
+ {children}
+
+)
- const methods = instance.useStepper() as Stepperize.Stepper
+const StepperContainer = ({
+ children,
+ className,
+ ...props
+}: Omit, "children"> & {
+ children:
+ | React.ReactNode
+ | ((props: { methods: Stepperize.Stepper }) => React.ReactNode)
+}) => {
+ const { instance } = useStepper()
+ const methods = instance.useStepper()
return (
-
-
- {typeof children === "function" ? children({ methods }) : children}
-
-
+
+ {typeof children === "function" ? children({ methods }) : children}
+
)
}
@@ -86,9 +97,7 @@ const StepperNavigation = ({
}: Omit, "children"> & {
children: React.ReactNode
}) => {
- const { variant, instance } = useStepper()
-
- const methods = instance.useStepper() as Stepperize.Stepper
+ const { variant } = useStepper()
return (