@cdx-ui/components 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/coverage.svg +1 -1
- package/docs/components/bar-chart/content.md +703 -0
- package/docs/components/content.md +9 -1
- package/docs/components/line-chart/content.md +567 -0
- package/docs/components/pie-chart/content.md +493 -0
- package/docs/components/progress-segmented/content.md +1 -1
- package/docs/components/select/content.md +144 -2
- package/docs/components/stepper/content.md +599 -0
- package/docs/components/system-alert/content.md +533 -0
- package/docs/foundations/expressions/icons/content.md +1 -1
- package/docs/foundations/styles/tokens/all-tokens/content.md +2 -1
- package/docs/llms.txt +10 -0
- package/docs/patterns/content.md +1 -0
- package/docs/patterns/dashboard/content.md +423 -19
- package/docs/patterns/insights/content.md +590 -0
- package/docs/resources/release-notes/0.3.4/content.md +27 -0
- package/docs/resources/release-notes/0.3.5/content.md +7 -0
- package/docs/resources/release-notes/content.md +2 -0
- package/lib/commonjs/components/BarChart/geometry.js +1130 -0
- package/lib/commonjs/components/BarChart/geometry.js.map +1 -0
- package/lib/commonjs/components/BarChart/index.js +942 -0
- package/lib/commonjs/components/BarChart/index.js.map +1 -0
- package/lib/commonjs/components/BarChart/styles.js +26 -0
- package/lib/commonjs/components/BarChart/styles.js.map +1 -0
- package/lib/commonjs/components/Button/index.js +2 -2
- package/lib/commonjs/components/Button/index.js.map +1 -1
- package/lib/commonjs/components/Chip/styles.js +3 -1
- package/lib/commonjs/components/Chip/styles.js.map +1 -1
- package/lib/commonjs/components/LineChart/geometry.js +698 -0
- package/lib/commonjs/components/LineChart/geometry.js.map +1 -0
- package/lib/commonjs/components/LineChart/index.js +747 -0
- package/lib/commonjs/components/LineChart/index.js.map +1 -0
- package/lib/commonjs/components/LineChart/styles.js +25 -0
- package/lib/commonjs/components/LineChart/styles.js.map +1 -0
- package/lib/commonjs/components/PieChart/geometry.js +216 -0
- package/lib/commonjs/components/PieChart/geometry.js.map +1 -0
- package/lib/commonjs/components/PieChart/index.js +476 -0
- package/lib/commonjs/components/PieChart/index.js.map +1 -0
- package/lib/commonjs/components/PieChart/styles.js +88 -0
- package/lib/commonjs/components/PieChart/styles.js.map +1 -0
- package/lib/commonjs/components/ProgressCircle/ProgressCircleRing.js +9 -31
- package/lib/commonjs/components/ProgressCircle/ProgressCircleRing.js.map +1 -1
- package/lib/commonjs/components/ProgressCircle/ProgressRing.js +52 -0
- package/lib/commonjs/components/ProgressCircle/ProgressRing.js.map +1 -0
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +8 -7
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/commonjs/components/Stepper/index.js +369 -0
- package/lib/commonjs/components/Stepper/index.js.map +1 -0
- package/lib/commonjs/components/Stepper/styles.js +211 -0
- package/lib/commonjs/components/Stepper/styles.js.map +1 -0
- package/lib/commonjs/components/Stepper/useStepperLabelFit.js +22 -0
- package/lib/commonjs/components/Stepper/useStepperLabelFit.js.map +1 -0
- package/lib/commonjs/components/Stepper/useStepperLabelFit.web.js +52 -0
- package/lib/commonjs/components/Stepper/useStepperLabelFit.web.js.map +1 -0
- package/lib/commonjs/components/Stepper/useStepperRingColors.js +31 -0
- package/lib/commonjs/components/Stepper/useStepperRingColors.js.map +1 -0
- package/lib/commonjs/components/SystemAlert/animation.js +218 -0
- package/lib/commonjs/components/SystemAlert/animation.js.map +1 -0
- package/lib/commonjs/components/SystemAlert/index.js +525 -0
- package/lib/commonjs/components/SystemAlert/index.js.map +1 -0
- package/lib/commonjs/components/SystemAlert/styles.js +178 -0
- package/lib/commonjs/components/SystemAlert/styles.js.map +1 -0
- package/lib/commonjs/components/SystemAlert/useSystemAlertStatusBarStyle.js +53 -0
- package/lib/commonjs/components/SystemAlert/useSystemAlertStatusBarStyle.js.map +1 -0
- package/lib/commonjs/components/Tabs/index.js +4 -0
- package/lib/commonjs/components/Tabs/index.js.map +1 -1
- package/lib/commonjs/components/Tabs/styles.js +1 -1
- package/lib/commonjs/components/Tabs/styles.js.map +1 -1
- package/lib/commonjs/components/chart/ChartInspector.js +610 -0
- package/lib/commonjs/components/chart/ChartInspector.js.map +1 -0
- package/lib/commonjs/components/chart/format.js +93 -0
- package/lib/commonjs/components/chart/format.js.map +1 -0
- package/lib/commonjs/components/chart/index.js +2 -0
- package/lib/commonjs/components/chart/index.js.map +1 -0
- package/lib/commonjs/components/chart/motion.js +97 -0
- package/lib/commonjs/components/chart/motion.js.map +1 -0
- package/lib/commonjs/components/chart/palette.js +178 -0
- package/lib/commonjs/components/chart/palette.js.map +1 -0
- package/lib/commonjs/components/chart/size.js +34 -0
- package/lib/commonjs/components/chart/size.js.map +1 -0
- package/lib/commonjs/components/chart/ticks.js +59 -0
- package/lib/commonjs/components/chart/ticks.js.map +1 -0
- package/lib/commonjs/components/chart/types.js +6 -0
- package/lib/commonjs/components/chart/types.js.map +1 -0
- package/lib/commonjs/components/chart/useChartHostWidth.js +27 -0
- package/lib/commonjs/components/chart/useChartHostWidth.js.map +1 -0
- package/lib/commonjs/components/index.js +60 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/figma/SystemAlert.Button.figma.js +28 -0
- package/lib/commonjs/figma/SystemAlert.Button.figma.js.map +1 -0
- package/lib/commonjs/figma/SystemAlert.Close.figma.js +22 -0
- package/lib/commonjs/figma/SystemAlert.Close.figma.js.map +1 -0
- package/lib/commonjs/figma/SystemAlert.Description.figma.js +20 -0
- package/lib/commonjs/figma/SystemAlert.Description.figma.js.map +1 -0
- package/lib/commonjs/figma/SystemAlert.IconButton.figma.js +31 -0
- package/lib/commonjs/figma/SystemAlert.IconButton.figma.js.map +1 -0
- package/lib/commonjs/figma/SystemAlert.figma.js +48 -0
- package/lib/commonjs/figma/SystemAlert.figma.js.map +1 -0
- package/lib/module/components/BarChart/geometry.js +1110 -0
- package/lib/module/components/BarChart/geometry.js.map +1 -0
- package/lib/module/components/BarChart/index.js +936 -0
- package/lib/module/components/BarChart/index.js.map +1 -0
- package/lib/module/components/BarChart/styles.js +22 -0
- package/lib/module/components/BarChart/styles.js.map +1 -0
- package/lib/module/components/Button/index.js +2 -2
- package/lib/module/components/Button/index.js.map +1 -1
- package/lib/module/components/Chip/styles.js +3 -1
- package/lib/module/components/Chip/styles.js.map +1 -1
- package/lib/module/components/LineChart/geometry.js +685 -0
- package/lib/module/components/LineChart/geometry.js.map +1 -0
- package/lib/module/components/LineChart/index.js +741 -0
- package/lib/module/components/LineChart/index.js.map +1 -0
- package/lib/module/components/LineChart/styles.js +21 -0
- package/lib/module/components/LineChart/styles.js.map +1 -0
- package/lib/module/components/PieChart/geometry.js +209 -0
- package/lib/module/components/PieChart/geometry.js.map +1 -0
- package/lib/module/components/PieChart/index.js +471 -0
- package/lib/module/components/PieChart/index.js.map +1 -0
- package/lib/module/components/PieChart/styles.js +84 -0
- package/lib/module/components/PieChart/styles.js.map +1 -0
- package/lib/module/components/ProgressCircle/ProgressCircleRing.js +10 -32
- package/lib/module/components/ProgressCircle/ProgressCircleRing.js.map +1 -1
- package/lib/module/components/ProgressCircle/ProgressRing.js +48 -0
- package/lib/module/components/ProgressCircle/ProgressRing.js.map +1 -0
- package/lib/module/components/ScrollShadow/useScrollShadow.js +8 -7
- package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/module/components/Stepper/index.js +360 -0
- package/lib/module/components/Stepper/index.js.map +1 -0
- package/lib/module/components/Stepper/styles.js +206 -0
- package/lib/module/components/Stepper/styles.js.map +1 -0
- package/lib/module/components/Stepper/useStepperLabelFit.js +18 -0
- package/lib/module/components/Stepper/useStepperLabelFit.js.map +1 -0
- package/lib/module/components/Stepper/useStepperLabelFit.web.js +48 -0
- package/lib/module/components/Stepper/useStepperLabelFit.web.js.map +1 -0
- package/lib/module/components/Stepper/useStepperRingColors.js +28 -0
- package/lib/module/components/Stepper/useStepperRingColors.js.map +1 -0
- package/lib/module/components/SystemAlert/animation.js +213 -0
- package/lib/module/components/SystemAlert/animation.js.map +1 -0
- package/lib/module/components/SystemAlert/index.js +515 -0
- package/lib/module/components/SystemAlert/index.js.map +1 -0
- package/lib/module/components/SystemAlert/styles.js +174 -0
- package/lib/module/components/SystemAlert/styles.js.map +1 -0
- package/lib/module/components/SystemAlert/useSystemAlertStatusBarStyle.js +49 -0
- package/lib/module/components/SystemAlert/useSystemAlertStatusBarStyle.js.map +1 -0
- package/lib/module/components/Tabs/index.js +4 -0
- package/lib/module/components/Tabs/index.js.map +1 -1
- package/lib/module/components/Tabs/styles.js +1 -1
- package/lib/module/components/Tabs/styles.js.map +1 -1
- package/lib/module/components/chart/ChartInspector.js +600 -0
- package/lib/module/components/chart/ChartInspector.js.map +1 -0
- package/lib/module/components/chart/format.js +84 -0
- package/lib/module/components/chart/format.js.map +1 -0
- package/lib/module/components/chart/index.js +2 -0
- package/lib/module/components/chart/index.js.map +1 -0
- package/lib/module/components/chart/motion.js +89 -0
- package/lib/module/components/chart/motion.js.map +1 -0
- package/lib/module/components/chart/palette.js +168 -0
- package/lib/module/components/chart/palette.js.map +1 -0
- package/lib/module/components/chart/size.js +29 -0
- package/lib/module/components/chart/size.js.map +1 -0
- package/lib/module/components/chart/ticks.js +55 -0
- package/lib/module/components/chart/ticks.js.map +1 -0
- package/lib/module/components/chart/types.js +4 -0
- package/lib/module/components/chart/types.js.map +1 -0
- package/lib/module/components/chart/useChartHostWidth.js +23 -0
- package/lib/module/components/chart/useChartHostWidth.js.map +1 -0
- package/lib/module/components/index.js +5 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/figma/SystemAlert.Button.figma.js +22 -0
- package/lib/module/figma/SystemAlert.Button.figma.js.map +1 -0
- package/lib/module/figma/SystemAlert.Close.figma.js +18 -0
- package/lib/module/figma/SystemAlert.Close.figma.js.map +1 -0
- package/lib/module/figma/SystemAlert.Description.figma.js +14 -0
- package/lib/module/figma/SystemAlert.Description.figma.js.map +1 -0
- package/lib/module/figma/SystemAlert.IconButton.figma.js +25 -0
- package/lib/module/figma/SystemAlert.IconButton.figma.js.map +1 -0
- package/lib/module/figma/SystemAlert.figma.js +42 -0
- package/lib/module/figma/SystemAlert.figma.js.map +1 -0
- package/lib/typescript/components/BarChart/geometry.d.ts +236 -0
- package/lib/typescript/components/BarChart/geometry.d.ts.map +1 -0
- package/lib/typescript/components/BarChart/index.d.ts +193 -0
- package/lib/typescript/components/BarChart/index.d.ts.map +1 -0
- package/lib/typescript/components/BarChart/styles.d.ts +32 -0
- package/lib/typescript/components/BarChart/styles.d.ts.map +1 -0
- package/lib/typescript/components/Chip/styles.d.ts.map +1 -1
- package/lib/typescript/components/LineChart/geometry.d.ts +248 -0
- package/lib/typescript/components/LineChart/geometry.d.ts.map +1 -0
- package/lib/typescript/components/LineChart/index.d.ts +105 -0
- package/lib/typescript/components/LineChart/index.d.ts.map +1 -0
- package/lib/typescript/components/LineChart/styles.d.ts +12 -0
- package/lib/typescript/components/LineChart/styles.d.ts.map +1 -0
- package/lib/typescript/components/PieChart/geometry.d.ts +43 -0
- package/lib/typescript/components/PieChart/geometry.d.ts.map +1 -0
- package/lib/typescript/components/PieChart/index.d.ts +147 -0
- package/lib/typescript/components/PieChart/index.d.ts.map +1 -0
- package/lib/typescript/components/PieChart/styles.d.ts +27 -0
- package/lib/typescript/components/PieChart/styles.d.ts.map +1 -0
- package/lib/typescript/components/ProgressCircle/ProgressCircleRing.d.ts.map +1 -1
- package/lib/typescript/components/ProgressCircle/ProgressRing.d.ts +17 -0
- package/lib/typescript/components/ProgressCircle/ProgressRing.d.ts.map +1 -0
- package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
- package/lib/typescript/components/Stepper/index.d.ts +68 -0
- package/lib/typescript/components/Stepper/index.d.ts.map +1 -0
- package/lib/typescript/components/Stepper/styles.d.ts +46 -0
- package/lib/typescript/components/Stepper/styles.d.ts.map +1 -0
- package/lib/typescript/components/Stepper/useStepperLabelFit.d.ts +15 -0
- package/lib/typescript/components/Stepper/useStepperLabelFit.d.ts.map +1 -0
- package/lib/typescript/components/Stepper/useStepperLabelFit.web.d.ts +10 -0
- package/lib/typescript/components/Stepper/useStepperLabelFit.web.d.ts.map +1 -0
- package/lib/typescript/components/Stepper/useStepperRingColors.d.ts +6 -0
- package/lib/typescript/components/Stepper/useStepperRingColors.d.ts.map +1 -0
- package/lib/typescript/components/SystemAlert/animation.d.ts +56 -0
- package/lib/typescript/components/SystemAlert/animation.d.ts.map +1 -0
- package/lib/typescript/components/SystemAlert/index.d.ts +110 -0
- package/lib/typescript/components/SystemAlert/index.d.ts.map +1 -0
- package/lib/typescript/components/SystemAlert/styles.d.ts +38 -0
- package/lib/typescript/components/SystemAlert/styles.d.ts.map +1 -0
- package/lib/typescript/components/SystemAlert/useSystemAlertStatusBarStyle.d.ts +14 -0
- package/lib/typescript/components/SystemAlert/useSystemAlertStatusBarStyle.d.ts.map +1 -0
- package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
- package/lib/typescript/components/chart/ChartInspector.d.ts +101 -0
- package/lib/typescript/components/chart/ChartInspector.d.ts.map +1 -0
- package/lib/typescript/components/chart/format.d.ts +16 -0
- package/lib/typescript/components/chart/format.d.ts.map +1 -0
- package/lib/typescript/components/chart/index.d.ts +3 -0
- package/lib/typescript/components/chart/index.d.ts.map +1 -0
- package/lib/typescript/components/chart/motion.d.ts +27 -0
- package/lib/typescript/components/chart/motion.d.ts.map +1 -0
- package/lib/typescript/components/chart/palette.d.ts +44 -0
- package/lib/typescript/components/chart/palette.d.ts.map +1 -0
- package/lib/typescript/components/chart/size.d.ts +25 -0
- package/lib/typescript/components/chart/size.d.ts.map +1 -0
- package/lib/typescript/components/chart/ticks.d.ts +3 -0
- package/lib/typescript/components/chart/ticks.d.ts.map +1 -0
- package/lib/typescript/components/chart/types.d.ts +163 -0
- package/lib/typescript/components/chart/types.d.ts.map +1 -0
- package/lib/typescript/components/chart/useChartHostWidth.d.ts +9 -0
- package/lib/typescript/components/chart/useChartHostWidth.d.ts.map +1 -0
- package/lib/typescript/components/index.d.ts +5 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/figma/SystemAlert.Button.figma.d.ts +11 -0
- package/lib/typescript/figma/SystemAlert.Button.figma.d.ts.map +1 -0
- package/lib/typescript/figma/SystemAlert.Close.figma.d.ts +11 -0
- package/lib/typescript/figma/SystemAlert.Close.figma.d.ts.map +1 -0
- package/lib/typescript/figma/SystemAlert.Description.figma.d.ts +8 -0
- package/lib/typescript/figma/SystemAlert.Description.figma.d.ts.map +1 -0
- package/lib/typescript/figma/SystemAlert.IconButton.figma.d.ts +11 -0
- package/lib/typescript/figma/SystemAlert.IconButton.figma.d.ts.map +1 -0
- package/lib/typescript/figma/SystemAlert.figma.d.ts +8 -0
- package/lib/typescript/figma/SystemAlert.figma.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/components/BarChart/geometry.ts +1469 -0
- package/src/components/BarChart/index.tsx +1424 -0
- package/src/components/BarChart/styles.ts +31 -0
- package/src/components/Button/index.tsx +1 -1
- package/src/components/Chip/styles.ts +3 -1
- package/src/components/LineChart/geometry.ts +957 -0
- package/src/components/LineChart/index.tsx +1109 -0
- package/src/components/LineChart/styles.ts +26 -0
- package/src/components/PieChart/geometry.ts +295 -0
- package/src/components/PieChart/index.tsx +715 -0
- package/src/components/PieChart/styles.ts +101 -0
- package/src/components/ProgressCircle/ProgressCircleRing.tsx +10 -39
- package/src/components/ProgressCircle/ProgressRing.tsx +60 -0
- package/src/components/ScrollShadow/useScrollShadow.ts +12 -11
- package/src/components/Stepper/index.tsx +452 -0
- package/src/components/Stepper/styles.ts +234 -0
- package/src/components/Stepper/useStepperLabelFit.ts +21 -0
- package/src/components/Stepper/useStepperLabelFit.web.ts +53 -0
- package/src/components/Stepper/useStepperRingColors.ts +29 -0
- package/src/components/SystemAlert/animation.ts +252 -0
- package/src/components/SystemAlert/index.tsx +684 -0
- package/src/components/SystemAlert/styles.ts +212 -0
- package/src/components/SystemAlert/useSystemAlertStatusBarStyle.ts +57 -0
- package/src/components/Tabs/index.tsx +4 -0
- package/src/components/Tabs/styles.ts +1 -1
- package/src/components/chart/ChartInspector.tsx +726 -0
- package/src/components/chart/format.ts +95 -0
- package/src/components/chart/index.ts +24 -0
- package/src/components/chart/motion.ts +98 -0
- package/src/components/chart/palette.tsx +247 -0
- package/src/components/chart/size.ts +21 -0
- package/src/components/chart/ticks.ts +53 -0
- package/src/components/chart/types.ts +183 -0
- package/src/components/chart/useChartHostWidth.ts +26 -0
- package/src/components/index.ts +5 -0
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
# Stepper (https://design.candescent.com/docs/components/stepper)
|
|
2
|
+
|
|
3
|
+
Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/navigation-stepper--default)
|
|
4
|
+
|
|
5
|
+
`Stepper` shows named steps beside a multi-step flow, such as a wizard or guided setup. For a compact meter without step labels, use [`ProgressSegmented`](https://design.candescent.com/docs/components/progress-segmented/content.md) instead.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Stepper } from '@cdx-ui/components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic
|
|
12
|
+
|
|
13
|
+
`currentStep` is zero-based, so `currentStep={1}` marks the second step as current. Steps before it are complete by default. This differs from `ProgressSegmented.step`, which is one-based.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { Box, Stepper } from '@cdx-ui/components';
|
|
17
|
+
|
|
18
|
+
const steps = ['Role details', 'Permissions', 'Environments', 'Review'];
|
|
19
|
+
|
|
20
|
+
export default function StepperBasicDemo() {
|
|
21
|
+
return (
|
|
22
|
+
<Box className="w-64">
|
|
23
|
+
<Stepper currentStep={1} accessibilityLabel="Create role progress">
|
|
24
|
+
{steps.map((title) => (
|
|
25
|
+
<Stepper.Step key={title}>
|
|
26
|
+
<Stepper.Indicator />
|
|
27
|
+
<Stepper.Title>{title}</Stepper.Title>
|
|
28
|
+
<Stepper.Separator />
|
|
29
|
+
</Stepper.Step>
|
|
30
|
+
))}
|
|
31
|
+
</Stepper>
|
|
32
|
+
</Box>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Progress
|
|
38
|
+
|
|
39
|
+
Pass `isComplete` to override the default completion in either direction, and `progress` (0–100) to draw a partial ring on an incomplete step. A step before `currentStep` is complete by default, so pass `isComplete={false}` to show it as visited but unfinished.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { Box, Stepper } from '@cdx-ui/components';
|
|
43
|
+
|
|
44
|
+
export default function StepperProgressDemo() {
|
|
45
|
+
return (
|
|
46
|
+
<Box className="w-64">
|
|
47
|
+
<Stepper currentStep={2} accessibilityLabel="Marketplace onboarding progress">
|
|
48
|
+
<Stepper.Step>
|
|
49
|
+
<Stepper.Indicator />
|
|
50
|
+
<Stepper.Title>Company profile</Stepper.Title>
|
|
51
|
+
<Stepper.Separator />
|
|
52
|
+
</Stepper.Step>
|
|
53
|
+
<Stepper.Step isComplete={false} progress={60}>
|
|
54
|
+
<Stepper.Indicator />
|
|
55
|
+
<Stepper.Title>Contacts</Stepper.Title>
|
|
56
|
+
<Stepper.Description>3 of 5 fields done</Stepper.Description>
|
|
57
|
+
<Stepper.Separator />
|
|
58
|
+
</Stepper.Step>
|
|
59
|
+
<Stepper.Step progress={25}>
|
|
60
|
+
<Stepper.Indicator />
|
|
61
|
+
<Stepper.Title>Integration details</Stepper.Title>
|
|
62
|
+
<Stepper.Separator />
|
|
63
|
+
</Stepper.Step>
|
|
64
|
+
<Stepper.Step isComplete>
|
|
65
|
+
<Stepper.Indicator />
|
|
66
|
+
<Stepper.Title>Terms of service</Stepper.Title>
|
|
67
|
+
<Stepper.Separator />
|
|
68
|
+
</Stepper.Step>
|
|
69
|
+
<Stepper.Step>
|
|
70
|
+
<Stepper.Indicator />
|
|
71
|
+
<Stepper.Title>Review</Stepper.Title>
|
|
72
|
+
<Stepper.Separator />
|
|
73
|
+
</Stepper.Step>
|
|
74
|
+
</Stepper>
|
|
75
|
+
</Box>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Content
|
|
81
|
+
|
|
82
|
+
`Stepper.Content` renders below the title, outside the step's accessible name, for detail such as a labelled progress bar per section. It always renders when passed, whatever the step's state, so render it only on the steps that need it.
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { Box, ProgressBar, Stepper, Text } from '@cdx-ui/components';
|
|
86
|
+
|
|
87
|
+
const sections = [
|
|
88
|
+
{ label: 'Your company', done: 3, total: 6 },
|
|
89
|
+
{ label: 'Primary contact', done: 0, total: 4 },
|
|
90
|
+
{ label: 'Marketing contact', done: 0, total: 2 },
|
|
91
|
+
{ label: 'Compliance contact', done: 0, total: 2 },
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
const fieldsDone = sections.reduce((sum, { done }) => sum + done, 0);
|
|
95
|
+
const fieldsTotal = sections.reduce((sum, { total }) => sum + total, 0);
|
|
96
|
+
|
|
97
|
+
export default function StepperContentDemo() {
|
|
98
|
+
return (
|
|
99
|
+
<Box className="w-72">
|
|
100
|
+
<Stepper currentStep={1} accessibilityLabel="Basic application progress">
|
|
101
|
+
<Stepper.Step>
|
|
102
|
+
<Stepper.Indicator />
|
|
103
|
+
<Stepper.Title>Existing integration</Stepper.Title>
|
|
104
|
+
<Stepper.Separator />
|
|
105
|
+
</Stepper.Step>
|
|
106
|
+
<Stepper.Step progress={(fieldsDone / fieldsTotal) * 100}>
|
|
107
|
+
<Stepper.Indicator />
|
|
108
|
+
<Stepper.Title>Company overview</Stepper.Title>
|
|
109
|
+
<Stepper.Content>
|
|
110
|
+
{sections.map(({ label, done, total }) => (
|
|
111
|
+
<Box key={label} className="gap-1.5">
|
|
112
|
+
<Box className="flex-row justify-between">
|
|
113
|
+
<Text size="sm" color="secondary">
|
|
114
|
+
{label}
|
|
115
|
+
</Text>
|
|
116
|
+
<Text size="sm" color="secondary">
|
|
117
|
+
{done}/{total}
|
|
118
|
+
</Text>
|
|
119
|
+
</Box>
|
|
120
|
+
<ProgressBar
|
|
121
|
+
value={done}
|
|
122
|
+
max={total}
|
|
123
|
+
accessibilityLabel={`${label}, ${done} of ${total} fields complete`}
|
|
124
|
+
>
|
|
125
|
+
<ProgressBar.Indicator />
|
|
126
|
+
</ProgressBar>
|
|
127
|
+
</Box>
|
|
128
|
+
))}
|
|
129
|
+
</Stepper.Content>
|
|
130
|
+
<Stepper.Separator />
|
|
131
|
+
</Stepper.Step>
|
|
132
|
+
<Stepper.Step>
|
|
133
|
+
<Stepper.Indicator />
|
|
134
|
+
<Stepper.Title>Product & integration</Stepper.Title>
|
|
135
|
+
<Stepper.Separator />
|
|
136
|
+
</Stepper.Step>
|
|
137
|
+
<Stepper.Step>
|
|
138
|
+
<Stepper.Indicator />
|
|
139
|
+
<Stepper.Title>Compliance & documentation</Stepper.Title>
|
|
140
|
+
</Stepper.Step>
|
|
141
|
+
</Stepper>
|
|
142
|
+
</Box>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Horizontal
|
|
148
|
+
|
|
149
|
+
Set `orientation="horizontal"` to lay the steps out in a row, for example above a wizard in a modal. By default each label sits after its indicator, steps take the width their labels need, and the separators stretch to fill the space between them. The layout uses logical start and end, so step order and separators mirror in right-to-left layouts.
|
|
150
|
+
|
|
151
|
+
A horizontal stepper needs room for every label in one row. Keep labels short, and use a vertical stepper on small screens. When the row runs out of room, labels wrap and can collide with the separators. A compact mobile stepper is planned separately.
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
import { Box, ScrollView, Stepper } from '@cdx-ui/components';
|
|
155
|
+
|
|
156
|
+
const steps = ['Details', 'Permissions', 'Members', 'Review'];
|
|
157
|
+
|
|
158
|
+
export default function StepperHorizontalDemo() {
|
|
159
|
+
return (
|
|
160
|
+
<ScrollView horizontal contentContainerClassName="grow">
|
|
161
|
+
<Box className="min-w-140 flex-1">
|
|
162
|
+
<Stepper currentStep={1} orientation="horizontal" accessibilityLabel="New role progress">
|
|
163
|
+
{steps.map((title, index) => (
|
|
164
|
+
<Stepper.Step key={title} progress={index === 1 ? 40 : 0}>
|
|
165
|
+
<Stepper.Indicator />
|
|
166
|
+
<Stepper.Title>{title}</Stepper.Title>
|
|
167
|
+
<Stepper.Separator />
|
|
168
|
+
</Stepper.Step>
|
|
169
|
+
))}
|
|
170
|
+
</Stepper>
|
|
171
|
+
</Box>
|
|
172
|
+
</ScrollView>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Placement
|
|
178
|
+
|
|
179
|
+
Set `labelPlacement="bottom"` to give every step an equal column, with the indicator and label centered and the separator running from one indicator to the next. It fits more steps in the same width than labels placed after the indicators. `labelPlacement` only applies to horizontal steppers. `Stepper.Content` renders below the step's label in either placement, but it is designed for vertical steppers.
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
import { Box, ScrollView, Stepper } from '@cdx-ui/components';
|
|
183
|
+
|
|
184
|
+
const steps = ['Details', 'Permissions', 'Members', 'Review'];
|
|
185
|
+
|
|
186
|
+
export default function StepperHorizontalBottomDemo() {
|
|
187
|
+
return (
|
|
188
|
+
<ScrollView horizontal contentContainerClassName="grow">
|
|
189
|
+
<Box className="min-w-120 flex-1">
|
|
190
|
+
<Stepper
|
|
191
|
+
currentStep={1}
|
|
192
|
+
orientation="horizontal"
|
|
193
|
+
labelPlacement="bottom"
|
|
194
|
+
accessibilityLabel="New role progress, labels below"
|
|
195
|
+
>
|
|
196
|
+
{steps.map((title, index) => (
|
|
197
|
+
<Stepper.Step key={title} progress={index === 1 ? 40 : 0}>
|
|
198
|
+
<Stepper.Indicator />
|
|
199
|
+
<Stepper.Title>{title}</Stepper.Title>
|
|
200
|
+
<Stepper.Separator />
|
|
201
|
+
</Stepper.Step>
|
|
202
|
+
))}
|
|
203
|
+
</Stepper>
|
|
204
|
+
</Box>
|
|
205
|
+
</ScrollView>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Clickable steps
|
|
211
|
+
|
|
212
|
+
Pass `onStepChange` to let users press a step to jump back to it. By default only complete steps are pressable. Set `isLinear={false}` to allow any step, for example when every step can be edited in any order. The current step and steps with `isDisabled` are never pressable. Clickable steps work the same way in both orientations.
|
|
213
|
+
|
|
214
|
+
Navigation stays yours. With `currentStep` set, a press calls `onStepChange` with the step's index, and the stepper does not move until you update `currentStep`. Without `currentStep`, the stepper starts at `defaultStep`, moves itself on a press, and then calls `onStepChange`.
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
import { useState } from 'react';
|
|
218
|
+
import { Box, Button, Stepper, Switch, Text } from '@cdx-ui/components';
|
|
219
|
+
|
|
220
|
+
const steps = ['Role details', 'Permissions', 'Environments', 'Review'];
|
|
221
|
+
|
|
222
|
+
export default function StepperClickableDemo() {
|
|
223
|
+
const [currentStep, setCurrentStep] = useState(2);
|
|
224
|
+
const [canSkipAhead, setCanSkipAhead] = useState(false);
|
|
225
|
+
|
|
226
|
+
return (
|
|
227
|
+
<Box className="gap-6">
|
|
228
|
+
<Box className="flex-row items-center gap-3">
|
|
229
|
+
<Switch
|
|
230
|
+
value={canSkipAhead}
|
|
231
|
+
onValueChange={setCanSkipAhead}
|
|
232
|
+
accessibilityLabel="Allow skipping ahead"
|
|
233
|
+
/>
|
|
234
|
+
<Text>Allow skipping ahead</Text>
|
|
235
|
+
</Box>
|
|
236
|
+
|
|
237
|
+
<Box className="w-64">
|
|
238
|
+
<Stepper
|
|
239
|
+
currentStep={currentStep}
|
|
240
|
+
onStepChange={setCurrentStep}
|
|
241
|
+
isLinear={!canSkipAhead}
|
|
242
|
+
accessibilityLabel="Create role progress"
|
|
243
|
+
>
|
|
244
|
+
{steps.map((title) => (
|
|
245
|
+
<Stepper.Step key={title}>
|
|
246
|
+
<Stepper.Indicator />
|
|
247
|
+
<Stepper.Title>{title}</Stepper.Title>
|
|
248
|
+
<Stepper.Separator />
|
|
249
|
+
</Stepper.Step>
|
|
250
|
+
))}
|
|
251
|
+
</Stepper>
|
|
252
|
+
</Box>
|
|
253
|
+
|
|
254
|
+
<Button
|
|
255
|
+
className="self-start"
|
|
256
|
+
isDisabled={currentStep >= steps.length - 1}
|
|
257
|
+
onPress={() => setCurrentStep((step) => step + 1)}
|
|
258
|
+
>
|
|
259
|
+
<Button.Label>Next</Button.Label>
|
|
260
|
+
</Button>
|
|
261
|
+
</Box>
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Wizard
|
|
267
|
+
|
|
268
|
+
Navigation stays in your form: drive `currentStep` from your own Back and Next buttons. When the step changes, move focus to the new step's heading so screen readers announce it.
|
|
269
|
+
|
|
270
|
+
```tsx
|
|
271
|
+
import { useEffect, useRef, useState, type ComponentRef } from 'react';
|
|
272
|
+
import { Box, Button, Field, Heading, Input, Stepper, Text } from '@cdx-ui/components';
|
|
273
|
+
|
|
274
|
+
const steps = [
|
|
275
|
+
{ title: 'Role details', field: 'Role name', placeholder: 'Billing admin' },
|
|
276
|
+
{ title: 'Permissions', field: 'Permission set', placeholder: 'Payments: read and write' },
|
|
277
|
+
{ title: 'Review', field: null, placeholder: '' },
|
|
278
|
+
] as const;
|
|
279
|
+
|
|
280
|
+
export default function StepperWizardDemo() {
|
|
281
|
+
const [currentStep, setCurrentStep] = useState(0);
|
|
282
|
+
const [values, setValues] = useState<Record<number, string>>({});
|
|
283
|
+
const headingRef = useRef<ComponentRef<typeof Box>>(null);
|
|
284
|
+
const hasNavigated = useRef(false);
|
|
285
|
+
|
|
286
|
+
// Move focus to the new step's heading so screen readers announce the change.
|
|
287
|
+
useEffect(() => {
|
|
288
|
+
if (hasNavigated.current) {
|
|
289
|
+
headingRef.current?.focus();
|
|
290
|
+
}
|
|
291
|
+
}, [currentStep]);
|
|
292
|
+
|
|
293
|
+
const goTo = (index: number) => {
|
|
294
|
+
hasNavigated.current = true;
|
|
295
|
+
setCurrentStep(index);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const isFinished = currentStep >= steps.length;
|
|
299
|
+
const step = isFinished ? null : steps[currentStep];
|
|
300
|
+
const value = values[currentStep] ?? '';
|
|
301
|
+
const canContinue = step?.field === null || value.trim().length > 0;
|
|
302
|
+
|
|
303
|
+
return (
|
|
304
|
+
<Box className="w-full max-w-2xl flex-row flex-wrap gap-8">
|
|
305
|
+
<Box className="w-56">
|
|
306
|
+
<Stepper currentStep={currentStep} accessibilityLabel="Create role progress">
|
|
307
|
+
{steps.map(({ title }) => (
|
|
308
|
+
<Stepper.Step key={title}>
|
|
309
|
+
<Stepper.Indicator />
|
|
310
|
+
<Stepper.Title>{title}</Stepper.Title>
|
|
311
|
+
<Stepper.Separator />
|
|
312
|
+
</Stepper.Step>
|
|
313
|
+
))}
|
|
314
|
+
</Stepper>
|
|
315
|
+
</Box>
|
|
316
|
+
|
|
317
|
+
<Box className="min-w-64 flex-1 gap-4">
|
|
318
|
+
<Box ref={headingRef} tabIndex={-1} className="web:outline-none">
|
|
319
|
+
<Heading size="sm">{step ? step.title : 'Role created'}</Heading>
|
|
320
|
+
</Box>
|
|
321
|
+
|
|
322
|
+
{step?.field ? (
|
|
323
|
+
<Field name={step.field} isRequired>
|
|
324
|
+
<Field.Label>{step.field}</Field.Label>
|
|
325
|
+
<Input>
|
|
326
|
+
<Input.Field
|
|
327
|
+
placeholder={step.placeholder}
|
|
328
|
+
value={value}
|
|
329
|
+
onChangeText={(text) => setValues((prev) => ({ ...prev, [currentStep]: text }))}
|
|
330
|
+
/>
|
|
331
|
+
</Input>
|
|
332
|
+
</Field>
|
|
333
|
+
) : null}
|
|
334
|
+
|
|
335
|
+
{step?.field === null ? (
|
|
336
|
+
<Box className="gap-1">
|
|
337
|
+
{steps
|
|
338
|
+
.filter((item) => item.field !== null)
|
|
339
|
+
.map((item, index) => (
|
|
340
|
+
<Text key={item.title} size="sm">
|
|
341
|
+
{`${item.field}: ${values[index] ?? ''}`}
|
|
342
|
+
</Text>
|
|
343
|
+
))}
|
|
344
|
+
</Box>
|
|
345
|
+
) : null}
|
|
346
|
+
|
|
347
|
+
{isFinished ? <Text size="sm">The role is ready to assign.</Text> : null}
|
|
348
|
+
|
|
349
|
+
<Box className="flex-row gap-3">
|
|
350
|
+
{isFinished ? (
|
|
351
|
+
<Button
|
|
352
|
+
variant="outline"
|
|
353
|
+
onPress={() => {
|
|
354
|
+
setValues({});
|
|
355
|
+
goTo(0);
|
|
356
|
+
}}
|
|
357
|
+
>
|
|
358
|
+
<Button.Label>Start over</Button.Label>
|
|
359
|
+
</Button>
|
|
360
|
+
) : (
|
|
361
|
+
<>
|
|
362
|
+
<Button
|
|
363
|
+
variant="outline"
|
|
364
|
+
isDisabled={currentStep === 0}
|
|
365
|
+
onPress={() => goTo(currentStep - 1)}
|
|
366
|
+
>
|
|
367
|
+
<Button.Label>Back</Button.Label>
|
|
368
|
+
</Button>
|
|
369
|
+
<Button isDisabled={!canContinue} onPress={() => goTo(currentStep + 1)}>
|
|
370
|
+
<Button.Label>
|
|
371
|
+
{currentStep === steps.length - 1 ? 'Create role' : 'Next'}
|
|
372
|
+
</Button.Label>
|
|
373
|
+
</Button>
|
|
374
|
+
</>
|
|
375
|
+
)}
|
|
376
|
+
</Box>
|
|
377
|
+
</Box>
|
|
378
|
+
</Box>
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Custom indicator
|
|
384
|
+
|
|
385
|
+
Children of `Stepper.Indicator` replace the numeral or check inside the disc, while the disc color and progress ring still render. Read the step's state with `useStepperStep()` to tone the glyph.
|
|
386
|
+
|
|
387
|
+
```tsx
|
|
388
|
+
import { Box, Icon, Stepper, useStepperStep, type IconProps } from '@cdx-ui/components';
|
|
389
|
+
import { AdminPanelSettings, Checklist, Group } from '@cdx-ui/icons';
|
|
390
|
+
|
|
391
|
+
function StepGlyph({ as }: Pick<IconProps, 'as'>) {
|
|
392
|
+
const { isCurrent } = useStepperStep();
|
|
393
|
+
|
|
394
|
+
return (
|
|
395
|
+
<Icon
|
|
396
|
+
as={as}
|
|
397
|
+
className={
|
|
398
|
+
isCurrent ? 'size-4 text-content-brand-on-strong' : 'size-4 text-content-neutral-on-strong'
|
|
399
|
+
}
|
|
400
|
+
/>
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const steps = [
|
|
405
|
+
{ title: 'Team details', icon: Group },
|
|
406
|
+
{ title: 'Access', icon: AdminPanelSettings },
|
|
407
|
+
{ title: 'Review', icon: Checklist },
|
|
408
|
+
];
|
|
409
|
+
|
|
410
|
+
export default function StepperCustomIndicatorDemo() {
|
|
411
|
+
return (
|
|
412
|
+
<Box className="w-64">
|
|
413
|
+
<Stepper currentStep={1} accessibilityLabel="Create team progress">
|
|
414
|
+
{steps.map(({ title, icon }) => (
|
|
415
|
+
<Stepper.Step key={title}>
|
|
416
|
+
<Stepper.Indicator>
|
|
417
|
+
<StepGlyph as={icon} />
|
|
418
|
+
</Stepper.Indicator>
|
|
419
|
+
<Stepper.Title>{title}</Stepper.Title>
|
|
420
|
+
<Stepper.Separator />
|
|
421
|
+
</Stepper.Step>
|
|
422
|
+
))}
|
|
423
|
+
</Stepper>
|
|
424
|
+
</Box>
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
## API
|
|
430
|
+
|
|
431
|
+
### Stepper
|
|
432
|
+
|
|
433
|
+
The list root. It owns `currentStep` and numbers its steps by position. Every direct element child is a step: arrays and fragments are unwrapped, and `false` and `null` children are skipped, so conditional steps renumber automatically. A step nested inside another element is not counted.
|
|
434
|
+
|
|
435
|
+
| Prop | Type | Default | Description |
|
|
436
|
+
| --- | --- | --- | --- |
|
|
437
|
+
| `className?` | `string` | — | — |
|
|
438
|
+
| `children?` | `ReactNode` | — | `Stepper.Step` elements. Every direct element child is a step and is numbered by position; arrays and fragments are unwrapped, and `false`/`null` children are skipped. |
|
|
439
|
+
| `currentStep?` | `number` | — | Controlled, zero-based current step. A value outside `0…count-1` means no step is current; a value `>= count` makes every step complete by default. |
|
|
440
|
+
| `defaultStep?` | `number` | `0` | Uncontrolled starting step. Ignored when `currentStep` is set. |
|
|
441
|
+
| `onStepChange?` | `((index: number) => void)` | — | Called with the pressed step's index. Setting it makes eligible steps clickable. |
|
|
442
|
+
| `isLinear?` | `boolean` | `true` | When `true`, only complete steps are clickable. When `false`, every non-current, non-disabled step is. |
|
|
443
|
+
| `orientation?` | `'horizontal' \| 'vertical'` | `'vertical'` | `'horizontal'` lays the steps out in a row. `labelPlacement` chooses where each label sits. |
|
|
444
|
+
| `labelPlacement?` | `'end' \| 'bottom'` | `'end'` | Horizontal only; ignored when `orientation` is `'vertical'`. `'end'` puts each label after its indicator, sizes steps to their labels and stretches the separators between them. `'bottom'` gives every step an equal column with the indicator and label centered. |
|
|
445
|
+
| `getStepAccessibilityText?` | `((state: StepperStepState) => string)` | — | Returns the state phrase appended to each step's title for assistive technology, replacing the English default (for example `"current step, 40% complete"`). |
|
|
446
|
+
| `asChild?` | `boolean` | `false` | — |
|
|
447
|
+
|
|
448
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
449
|
+
|
|
450
|
+
| Attribute | Values | Description |
|
|
451
|
+
| ---------------------- | -------------------------- | ------------------------------------------------ |
|
|
452
|
+
| `data-orientation` | `vertical` \| `horizontal` | Layout direction |
|
|
453
|
+
| `data-label-placement` | `end` \| `bottom` | Label position; only affects horizontal steppers |
|
|
454
|
+
|
|
455
|
+
## Sub-components
|
|
456
|
+
|
|
457
|
+
### Stepper.Step
|
|
458
|
+
|
|
459
|
+
One step in the list. Completion defaults to `index < currentStep`, and an explicit `isComplete` wins in both directions. `progress` is clamped to 0–100 and draws a partial ring while the step is incomplete. It never completes the step on its own, even at 100.
|
|
460
|
+
|
|
461
|
+
The parts below must be direct children of `Stepper.Step`, which arranges them into the indicator track, the label and the body. Only the first of each part is used, and anything else renders in the body after the title. A part wrapped in your own component is not recognized. Leave out `Stepper.Separator` for a compact list with no connector line.
|
|
462
|
+
|
|
463
|
+
| Prop | Type | Default | Description |
|
|
464
|
+
| --- | --- | --- | --- |
|
|
465
|
+
| `className?` | `string` | — | — |
|
|
466
|
+
| `children?` | `ReactNode` | — | `Stepper.Indicator`, `Stepper.Title`, `Stepper.Description`, `Stepper.Content` and `Stepper.Separator`. They must be **direct** children: the step sorts them into regions by component identity, so a `memo()`/HOC wrapper is not recognized and renders as content. Only the first of each slot is used. `asChild` skips the sorting. |
|
|
467
|
+
| `isComplete?` | `boolean` | `index < currentStep` | Whether the step is complete. An explicit value wins in both directions. |
|
|
468
|
+
| `progress?` | `number` | `0` | Partial progress, 0–100. Values outside the range are clamped; non-finite values are `0`. |
|
|
469
|
+
| `isDisabled?` | `boolean` | `false` | Only affects clickability. A disabled step still shows its state. |
|
|
470
|
+
| `asChild?` | `boolean` | `false` | — |
|
|
471
|
+
|
|
472
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
473
|
+
|
|
474
|
+
| Attribute | Values | Description |
|
|
475
|
+
| ---------------------- | -------------------------- | ------------------------------------------------ |
|
|
476
|
+
| `data-orientation` | `vertical` \| `horizontal` | Layout direction |
|
|
477
|
+
| `data-label-placement` | `end` \| `bottom` | Label position; only affects horizontal steppers |
|
|
478
|
+
| `data-current` | `true` \| `false` | Whether this is the current step |
|
|
479
|
+
| `data-complete` | `true` \| `false` | Resolved completion |
|
|
480
|
+
| `data-progress` | `true` \| `false` | `true` while the partial progress ring is drawn |
|
|
481
|
+
| `data-clickable` | `true` \| `false` | Whether the step can be pressed |
|
|
482
|
+
| `data-disabled` | `true` \| `false` | Whether the step has `isDisabled` |
|
|
483
|
+
|
|
484
|
+
The step's indicator and label are wrapped in a trigger (`data-slot="stepper-step-trigger"`), which becomes the button on a clickable step. It emits `data-clickable` and `data-disabled`, plus these interaction attributes while the step is clickable:
|
|
485
|
+
|
|
486
|
+
| Attribute | Values | Description |
|
|
487
|
+
| -------------------- | ----------------- | ------------------------ |
|
|
488
|
+
| `data-hover` | `true` \| `false` | Pointer is over the step |
|
|
489
|
+
| `data-active` | `true` \| `false` | Step is being pressed |
|
|
490
|
+
| `data-focus-visible` | `true` \| `false` | Step has keyboard focus |
|
|
491
|
+
|
|
492
|
+
### Stepper.Indicator
|
|
493
|
+
|
|
494
|
+
The numbered disc. It shows a check when the step is complete, the 1-based step number otherwise, and a progress ring while the step has partial progress. Emits the same `data-current`, `data-complete` and `data-progress` attributes as `Stepper.Step`.
|
|
495
|
+
|
|
496
|
+
| Prop | Type | Default | Description |
|
|
497
|
+
| --- | --- | --- | --- |
|
|
498
|
+
| `className?` | `string` | — | — |
|
|
499
|
+
| `children?` | `ReactNode` | — | Replaces the glyph inside the disc. The disc, tone and progress ring still render. Defaults to a check when the step is complete, otherwise the 1-based step number. |
|
|
500
|
+
| `asChild?` | `boolean` | — | Replaces the whole indicator with the child element via `Slot`. |
|
|
501
|
+
|
|
502
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
503
|
+
|
|
504
|
+
### Stepper.Title
|
|
505
|
+
|
|
506
|
+
The step label. Emphasized on the current step, and emits `data-current`.
|
|
507
|
+
|
|
508
|
+
| Prop | Type | Default | Description |
|
|
509
|
+
| --- | --- | --- | --- |
|
|
510
|
+
| `className?` | `string` | — | — |
|
|
511
|
+
| `children?` | `ReactNode` | — | — |
|
|
512
|
+
| `asChild?` | `boolean` | — | — |
|
|
513
|
+
|
|
514
|
+
Inherits all [`TextProps`](https://reactnative.dev/docs/text#props).
|
|
515
|
+
|
|
516
|
+
### Stepper.Description
|
|
517
|
+
|
|
518
|
+
Secondary text below the title, read as part of the step's name.
|
|
519
|
+
|
|
520
|
+
| Prop | Type | Default | Description |
|
|
521
|
+
| --- | --- | --- | --- |
|
|
522
|
+
| `className?` | `string` | — | — |
|
|
523
|
+
| `children?` | `ReactNode` | — | — |
|
|
524
|
+
| `asChild?` | `boolean` | — | — |
|
|
525
|
+
|
|
526
|
+
Inherits all [`TextProps`](https://reactnative.dev/docs/text#props).
|
|
527
|
+
|
|
528
|
+
### Stepper.Content
|
|
529
|
+
|
|
530
|
+
Detail below the label, such as section rows. Always rendered when passed.
|
|
531
|
+
|
|
532
|
+
| Prop | Type | Default | Description |
|
|
533
|
+
| --- | --- | --- | --- |
|
|
534
|
+
| `className?` | `string` | — | — |
|
|
535
|
+
| `children?` | `ReactNode` | — | — |
|
|
536
|
+
| `asChild?` | `boolean` | — | — |
|
|
537
|
+
|
|
538
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
539
|
+
|
|
540
|
+
### Stepper.Separator
|
|
541
|
+
|
|
542
|
+
The connector line to the next step. In a vertical stepper it stretches with the step's title and content. In a horizontal stepper it runs between this step's indicator, or its label when labels sit after the indicators, and the next step's indicator. It renders nothing on the last step.
|
|
543
|
+
|
|
544
|
+
| Prop | Type | Default | Description |
|
|
545
|
+
| --- | --- | --- | --- |
|
|
546
|
+
| `className?` | `string` | — | — |
|
|
547
|
+
| `children?` | `ReactNode` | — | — |
|
|
548
|
+
| `asChild?` | `boolean` | — | — |
|
|
549
|
+
|
|
550
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
551
|
+
|
|
552
|
+
### useStepperStep
|
|
553
|
+
|
|
554
|
+
Returns the enclosing step's resolved state. Call it inside a `Stepper.Step`, for example in a custom indicator glyph. It throws outside one.
|
|
555
|
+
|
|
556
|
+
```tsx
|
|
557
|
+
const { index, isCurrent, isComplete } = useStepperStep();
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
| Prop | Type | Default | Description |
|
|
561
|
+
| --- | --- | --- | --- |
|
|
562
|
+
| `index` | `number` | — | Zero-based position among the steps. |
|
|
563
|
+
| `count` | `number` | — | Number of steps rendered. |
|
|
564
|
+
| `isCurrent` | `boolean` | — | — |
|
|
565
|
+
| `isComplete` | `boolean` | — | Resolved completion: the explicit `isComplete`, or `index < currentStep`. |
|
|
566
|
+
| `progress` | `number` | — | Clamped to 0–100. Non-finite values are 0. |
|
|
567
|
+
| `hasProgress` | `boolean` | — | True when the partial ring is drawn: `0 < progress` and not complete. |
|
|
568
|
+
| `isLast` | `boolean` | — | — |
|
|
569
|
+
| `isClickable` | `boolean` | — | True when the step renders as a button. |
|
|
570
|
+
| `isDisabled` | `boolean` | — | — |
|
|
571
|
+
| `orientation` | `'horizontal' \| 'vertical'` | — | — |
|
|
572
|
+
| `labelPlacement` | `'end' \| 'bottom'` | — | — |
|
|
573
|
+
|
|
574
|
+
## Anatomy
|
|
575
|
+
|
|
576
|
+
| `data-slot` | Element |
|
|
577
|
+
| ---------------------- | ------------------------------------------------------------------------------ |
|
|
578
|
+
| `stepper` | List root |
|
|
579
|
+
| `stepper-step` | List item for one step |
|
|
580
|
+
| `stepper-step-trigger` | Indicator and label, which carry the step name. The button on a clickable step |
|
|
581
|
+
| `stepper-indicator` | Numbered disc, check and progress ring |
|
|
582
|
+
| `stepper-title` | Step label |
|
|
583
|
+
| `stepper-description` | Secondary label text |
|
|
584
|
+
| `stepper-content` | Detail below the label |
|
|
585
|
+
| `stepper-separator` | Connector line |
|
|
586
|
+
|
|
587
|
+
## Accessibility
|
|
588
|
+
|
|
589
|
+
`Stepper` is a list and each step is a list item in either orientation, so web screen readers announce how many steps there are and each step's position. The list's `accessibilityLabel` defaults to `"Progress"`. Name the flow instead, for example `"Create role progress"`.
|
|
590
|
+
|
|
591
|
+
On web, only the current step carries `aria-current="step"`. Native platforms have no equivalent, so the state is part of each step's accessible name.
|
|
592
|
+
|
|
593
|
+
Each step's accessible name is its title, then its description, then a state phrase: `current step`, `completed`, `incomplete`, or `40% complete`, combined as in `current step, 40% complete`. The announced percentage is rounded and held between 1 and 99 while the step is incomplete. On web the phrase is visually hidden text after the label. On iOS and Android the indicator and label are grouped into one element and the phrase is its accessibility value. `getStepAccessibilityText` receives the step's `StepperStepState` and returns only the state phrase, not the title, so use it to localize or reword the phrase.
|
|
594
|
+
|
|
595
|
+
When `onStepChange` is set, each clickable step's indicator and label become a button inside its list item. The button's name is the step's title and state phrase, as above. Users move between clickable steps with Tab and Shift+Tab and activate one with Enter or Space. Steps that are not clickable are not focusable and have no button role, so upcoming steps are not announced as dimmed buttons. Arrow keys are not handled, because the stepper is a list rather than a composite widget.
|
|
596
|
+
|
|
597
|
+
`Stepper.Indicator` and `Stepper.Separator` are hidden from assistive technologies. `Stepper.Content` stays in the normal reading order, outside the step's name.
|
|
598
|
+
|
|
599
|
+
The stepper does not announce step changes, and it has no live region. In a wizard, move focus to the new step's heading when the step changes, as the Wizard demo does. On web, wrap the heading in a `Box` with `tabIndex={-1}` and call its `focus()`. On iOS and Android, use `AccessibilityInfo.setAccessibilityFocus`.
|