Horizontal step indicator with numbered or dot markers, check-on-complete pop, and connectors that fill as progress advances
$ npx lumioui add steps
import { Steps } from "@/components/ui/steps/steps";
Files installed into your repo
components/ui/steps/steps.tsx
Registry dependencies (installed automatically)
Native packages required
@lumioui/core@latestreact-native-reanimated@*
Props9
| steps | string[] | StepsItem[] | Steps to display — strings or { label } objects. |
| current? | number | Controlled current index (0-based). |
| defaultCurrent? | number | Uncontrolled starting index. Default 0. |
| onCurrentChange? | (index: number) => void | Fired when a step is tapped (controlled or uncontrolled). |
| variant? | "numbered" | "dots" | "numbered" = numbered circles with a check on done; "dots" = compact dots. |
| labels? | boolean | Labels under the markers. Default true for "numbered", false for "dots". |
| interactive? | boolean | Tappable steps. Default true. |
| haptic? | "selection" | "light" | false | Haptic on step change. Default "selection". |
| className? | string | |
Steps — Dotsdots.tsx
Live preview offline the relay is unreachable — check back shortly
steps/variants/dots.tsx open Horizontal step indicator with numbered or dot markers, check-on-complete pop, and connectors that fill as progress advances
import { StepsDots } from "@/components/ui/steps/variants/dots";
export function Example() {
return (
<StepsDots />
);
}
import * as React from "react";
import { View } from "react-native";
import { Steps } from "../steps";
import { Button } from "../../button/button";
import { Glass } from "../../glass/glass";
import { Text } from "../../text/text";
/** StepsDots — compact onboarding dots with a Next/Back driver on glass. */
export function StepsDots() {
const [step, setStep] = React.useState(0);
const total = 4;
return (
<View className="w-full gap-3">
<Glass interactive curvature="edge" className="w-full gap-4 rounded-2xl p-4">
<Steps
variant="dots"
steps={["Welcome", "Profile", "Alerts", "Done"]}
current={step}
onCurrentChange={setStep}
/>
<View className="flex-row items-center justify-between">
<Button
variant="ghost"
size="sm"
disabled={step === 0}
onPress={() => setStep((s) => Math.max(0, s - 1))}
>
Back
</Button>
<Text variant="muted">Step {step + 1} of {total}</Text>
<Button
size="sm"
disabled={step === total - 1}
onPress={() => setStep((s) => Math.min(total - 1, s + 1))}
>
Next
</Button>
</View>
</Glass>
</View>
);
}
Steps — Numberednumbered.tsx
Live preview offline the relay is unreachable — check back shortly
steps/variants/numbered.tsx open Horizontal step indicator with numbered or dot markers, check-on-complete pop, and connectors that fill as progress advances
import { StepsNumbered } from "@/components/ui/steps/variants/numbered";
export function Example() {
return (
<StepsNumbered />
);
}
import * as React from "react";
import { View } from "react-native";
import { Steps } from "../steps";
import { Glass } from "../../glass/glass";
import { Icon } from "../../icon/icon";
import { Text } from "../../text/text";
const STEP_BODY: Record<number, { title: string; sub: string }> = {
0: { title: "Cart", sub: "2 items · Tonkotsu ×2, Gyoza" },
1: { title: "Shipping", sub: "14 Rua das Flores, Lisboa" },
2: { title: "Payment", sub: "VISA •• 4902" },
3: { title: "Review", sub: "Total $43.40 · arrives Thu" },
};
/** StepsNumbered — checkout progress staged on glass with the active step's summary below. */
export function StepsNumbered() {
const [step, setStep] = React.useState(1);
const body = STEP_BODY[step] ?? STEP_BODY[0]!;
return (
<View className="w-full gap-3">
<Glass interactive curvature="edge" className="w-full gap-3 rounded-2xl p-4">
<Text variant="small" className="font-semibold">Checkout</Text>
<Steps
steps={["Cart", "Shipping", "Payment", "Review"]}
current={step}
onCurrentChange={setStep}
/>
<Glass interactive curvature="edge" className="flex-row items-center gap-3 rounded-xl px-3 py-2.5">
<Icon name="check-circle" size="sm" color="primary" />
<View className="flex-1">
<Text variant="small" className="font-semibold">{body.title}</Text>
<Text variant="muted">{body.sub}</Text>
</View>
<Text variant="muted" className="text-xs">Step {step + 1}/4</Text>
</Glass>
<Text variant="muted" className="text-xs">Tap a step to jump back to it.</Text>
</Glass>
</View>
);
}