Steps
Process step indicator with wait/process/finish/error states, horizontal/vertical directions and optional clickable navigation. Horizontal steps wrap at a fixed basis width, and titles always stay on a single line.
Basic Usage
- Grind
- Paint
- Seal
<script setup lang="ts">
</script>
<template>
<LhSteps :current="1">
<LhStep title="Grind" />
<LhStep title="Paint" />
<LhStep title="Seal" />
</LhSteps>
</template><script>
export default {}
</script>
<template>
<LhSteps :current="1">
<LhStep title="Grind" />
<LhStep title="Paint" />
<LhStep title="Seal" />
</LhSteps>
</template>With Descriptions
- RegisterFill in the basics
- VerifyEmail and phone
- ActivateGrant permissions
<script setup lang="ts">
</script>
<template>
<LhSteps :current="1">
<LhStep title="Register" description="Fill in the basics" />
<LhStep title="Verify" description="Email and phone" />
<LhStep title="Activate" description="Grant permissions" />
</LhSteps>
</template><script>
export default {}
</script>
<template>
<LhSteps :current="1">
<LhStep title="Register" description="Fill in the basics" />
<LhStep title="Verify" description="Email and phone" />
<LhStep title="Activate" description="Grant permissions" />
</LhSteps>
</template>The icon prop sets a custom icon per step (a built-in LhIcon name such as user/check/star); without it, finished/error steps show a check/cross and the rest show their index. Use the #icon slot to fully customize the icon rendering.
- Register
- Verify
- Activate
<script setup lang="ts">
</script>
<template>
<LhSteps :current="1">
<LhStep icon="user" title="Register" />
<LhStep icon="check" title="Verify" />
<LhStep icon="star" title="Activate" />
</LhSteps>
</template><script>
export default {}
</script>
<template>
<LhSteps :current="1">
<LhStep icon="user" title="Register" />
<LhStep icon="check" title="Verify" />
<LhStep icon="star" title="Activate" />
</LhSteps>
</template>Error Status
- Upload
- Validate
- Finish
<script setup lang="ts">
</script>
<template>
<LhSteps :current="1" status="error">
<LhStep title="Upload" />
<LhStep title="Validate" />
<LhStep title="Finish" />
</LhSteps>
</template><script>
export default {}
</script>
<template>
<LhSteps :current="1" status="error">
<LhStep title="Upload" />
<LhStep title="Validate" />
<LhStep title="Finish" />
</LhSteps>
</template>
statusoverrides every step globally — handy for custom presentations.
Clickable Navigation
- PickChoose a model
- TraceTrace or recall
- MountMount the work
Current step: 1
<script setup lang="ts">
import { ref } from 'vue'
const current = ref(1)
</script>
<template>
<LhSteps v-model:current="current" clickable>
<LhStep title="Pick" description="Choose a model" />
<LhStep title="Trace" description="Trace or recall" />
<LhStep title="Mount" description="Mount the work" />
</LhSteps>
</template><script>
export default {
data() {
return { current: 1 }
},
}
</script>
<template>
<LhSteps v-model:current="current" clickable>
<LhStep title="Pick" description="Choose a model" />
<LhStep title="Trace" description="Trace or recall" />
<LhStep title="Mount" description="Mount the work" />
</LhSteps>
</template>Vertical Direction
- StartHidden tip
- MoveCentered stroke
- RestReturn the brush
<script setup lang="ts">
</script>
<template>
<LhSteps :current="1" direction="vertical">
<LhStep title="Start" description="Hidden tip" />
<LhStep title="Move" description="Centered stroke" />
<LhStep title="Rest" description="Return the brush" />
</LhSteps>
</template><script>
export default {}
</script>
<template>
<LhSteps :current="1" direction="vertical">
<LhStep title="Start" description="Hidden tip" />
<LhStep title="Move" description="Centered stroke" />
<LhStep title="Rest" description="Return the brush" />
</LhSteps>
</template>Fixed-Width Wrapping
Horizontal steps are laid out at the --lh-steps-item-basis basis width (default 160px): when they fit, the steps share one row evenly; when they do not, whole steps wrap to the next line instead of breaking the title. Titles are always single-line and truncate with an ellipsis when too long. After wrapping, the connector of the last step on each line is hidden so it does not point into empty space.
- PickChoose a model
- TraceTrace or recall
- InscribeSign and seal
- MountMount the work
<script setup lang="ts">
</script>
<template>
<LhSteps :current="1">
<LhStep title="Pick" description="Choose a model" />
<LhStep title="Trace" description="Trace or recall" />
<LhStep title="Inscribe" description="Sign and seal" />
<LhStep title="Mount" description="Mount the work" />
</LhSteps>
</template><script>
export default {}
</script>
<template>
<LhSteps :current="1">
<LhStep title="Pick" description="Choose a model" />
<LhStep title="Trace" description="Trace or recall" />
<LhStep title="Inscribe" description="Sign and seal" />
<LhStep title="Mount" description="Mount the work" />
</LhSteps>
</template>The demo above is constrained to
280pxto show the wrapping. To change the wrapping rhythm, overridesteps-item-basisviathemeVars(the--lh-prefix is added automatically):<LhSteps :theme-vars="{ 'steps-item-basis': '220px' }">, or configure it globally throughLhConfigProvider'scomponentTheme.steps.
Steps API
LhSteps Props
| Prop | Description | Type | Default |
|---|---|---|---|
| current | Current step index (v-model:current, 0-based) | number | 0 |
| direction | Direction | "horizontal" | "vertical" | 'horizontal' |
| clickable | Whether steps can be clicked for navigation | boolean | false |
| status | Overrides the status of all steps globally (for custom presentations) | "wait" | "process" | "finish" | "error" | — |
| themeVars | Component-level theme variables (keys get the --lh- prefix automatically) | { [x: string]: string; } | — |
| sx | Quick layout props | LhSxProps | — |
LhSteps Events
| Event | Description | Callback |
|---|---|---|
| update:current | Current step changed (v-model) | (index: number) |
| change | Current step changed | (index: number) |
LhStep Props
| Prop | Description | Type | Default |
|---|---|---|---|
| title | Step title (or the title slot) | string | '' |
| description | Step description (or the description slot) | string | '' |
| icon | Custom icon name (a built-in LhIcon name; defaults to check/cross for finish/error, otherwise the index) | LhIconName | — |
Slots
| Slot | Description | Component |
|---|---|---|
| default | Step items (LhStep list) | LhSteps |
| title | Custom title | LhStep |
| description | Custom description | LhStep |
| icon | Custom icon (overrides the icon prop's default rendering) | LhStep |
| description | Custom description | LhStep |
Component Variables
The following CSS variables are defined with defaults on .lh-steps and can be overridden globally or per component via themeVars (keys get the --lh- prefix automatically):
| Variable | Description | Default |
|---|---|---|
--lh-steps-item-basis | Basis width of each horizontal step; steps wrap at this width when they no longer fit | 160px |
Accessibility
- The container is
<ol role="list">; semantic order matches the process order - The current step automatically gets
aria-current="step" - With
clickable, the head of finished/current steps is a real<button>whose aria-label comes from the locale (steps.finish/steps.error/steps.step); waiting steps are not clickable so users are not invited to skip ahead - Connectors are drawn with pseudo-elements and never enter the accessibility tree
Type Definitions
The TypeScript type structures exported by this component (auto-extracted from packages/components/steps/src/types.ts and @lh-ui/share/core/* sources; click each entry to expand; see the Props table above for attribute descriptions):
LhStepsProps
export interface LhStepsProps {
current?: number
direction?: LhStepsDirection
clickable?: boolean
status?: LhStepStatus
themeVars?: Record<string, string>
sx?: LhSxProps
}LhStepProps
export interface LhStepProps {
title?: string
description?: string
icon?: LhIconName
}LhIconName (from @lh-ui/share/core/icon (svgs.ts))
export type LhIconName = keyof typeof LH_ICON_SVGS_CONSTLhStepsDirection (from @lh-ui/share/core/steps)
export type LhStepsDirection = 'horizontal' | 'vertical'LhStepStatus (from @lh-ui/share/core/steps)
export type LhStepStatus = 'wait' | 'process' | 'finish' | 'error'