Skip to main content

Steps

Guides users through a process step by step, supporting horizontal / vertical layouts, clickable navigation, and an overall status override.

Basic usage​

Basic usage
  1. Draft
    Define composition and lines
  2. Blend
    Layer and blend the ink
  3. Color
    Apply the danqing colors
  4. Inscribe
    Sign and seal to finish
  1. Draft
  2. Blend
  3. Color
    Needs rework here
  4. Inscribe
  1. Draft
    Define composition and lines
  2. Blend
    Layer and blend the ink
  3. Color
  4. Inscribe
import { useState } from 'react'
import { LhSteps, LhStep } from '@lh-ui/react'

export default function Demo() {
const [current, setCurrent] = useState(1)

return (
<LhSteps current={current} onChange={(index) => setCurrent(index)}>
<LhStep title="Draft" description="Define composition and lines" />
<LhStep title="Wash" description="Layer the ink wash" />
<LhStep title="Color" description="Dot on the danqing colors" />
<LhStep title="Inscribe" description="Add the inscription and seal" />
</LhSteps>
)
}

Steps Props​

PropDescriptionTypeOptionsDefault
currentCurrent step index (0-based, controlled)number——
defaultCurrentCurrent step default (uncontrolled)number—0
directionDirection'horizontal' | 'vertical'—'horizontal'
clickableWhether steps are clickable for navigationboolean—false
statusOverall status overriding every step (for custom displays)'wait' | 'process' | 'finish' | 'error'——
themeVarsComponent-level theme variables (keys are automatically prefixed with --lh-)Record<string, string>——
sxShorthand layout propsSxProps——

Step Props​

PropDescriptionTypeDefault
titleStep titleReactNode—
descriptionStep descriptionReactNode—
iconCustom icon name (when omitted, finish / error use a check / cross and the rest show the index)LhIconName—

Steps events​

EventDescriptionCallback signatureVue equivalent
onChangeEmitted when the current step changes (only when clickable is set)(index: number) => void@change
Controlled / uncontrolled

Passing current makes the component controlled (no internal state); passing defaultCurrent uses the internal uncontrolled state. onChange fires in both modes.

Clickable range

Even when clickable is true, only "finished" and "in progress" steps render as <button> elements; future steps (wait state) are always <span> elements, preventing jumps to unreached process nodes — consistent with lh-ui-plus.

Child node restriction

children must be LhStep elements directly (you may render them with .map); they cannot be wrapped in a custom component — the parent injects indices by filtering child element types via Children.toArray, and wrapping breaks index injection and status computation.

Theme variables​

Keys of themeVars are automatically prefixed with --lh- and written to the root element's inline style:

<LhSteps current={1} themeVars={{ 'steps-item-basis': '72px' }}>
<LhStep title="Draft" />
<LhStep title="Wash" />
</LhSteps>

Accessibility​

The list is <ol role="list">; the current step emits aria-current="step", and each step's status is expressed jointly by an aria-label (locale pack steps.step template, e.g. "Step 2") and status class names.

ref​

forwardRef<HTMLOListElement> — the <ol> root element. LhStep forwards HTMLLIElement.

Styles​

import '@lh-ui/react/theme.css'
import '@lh-ui/react/style/steps'