Skip to content

Commit 1ccc97d

Browse files
KenAJohmacbruker
andauthored
[FEATURE] Stepper med interactive, completed-option (#1626)
Co-authored-by: Martin Berglund <[email protected]>
1 parent ed2537d commit 1ccc97d

File tree

7 files changed

+226
-48
lines changed

7 files changed

+226
-48
lines changed

@navikt/core/css/stepper.css

+61-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
grid-column: 1;
3737
}
3838

39+
.navds-stepper__step--behind.navds-stepper__step--completed
40+
+ .navds-stepper__line {
41+
background-color: var(--navds-global-color-blue-500);
42+
}
43+
3944
.navds-stepper__line--1 {
4045
grid-row: line-1;
4146
display: none;
@@ -55,7 +60,6 @@
5560
display: grid;
5661
grid-template-columns: [circle] var(--navds-stepper-circle-size) [content] auto;
5762
gap: var(--navds-spacing-2);
58-
align-items: baseline;
5963
justify-content: flex-start;
6064
text-decoration: none;
6165
cursor: pointer;
@@ -73,6 +77,11 @@ button.navds-stepper__step {
7377
text-align: inherit;
7478
}
7579

80+
.navds-stepper__step--non-interactive {
81+
color: var(--navds-global-color-gray-600);
82+
cursor: default;
83+
}
84+
7685
:where(.navds-stepper__step):focus {
7786
outline: none;
7887
box-shadow: var(--navds-shadow-focus);
@@ -91,10 +100,17 @@ button.navds-stepper__step {
91100
line-height: 1;
92101
}
93102

103+
.navds-stepper__circle--success {
104+
border: none;
105+
background: none;
106+
font-size: 28px;
107+
}
108+
94109
.navds-stepper__content {
95110
min-width: fit-content;
96111
line-height: 1.5;
97112
grid-column: content;
113+
padding-top: 0.035rem;
98114
}
99115

100116
/* Horizontal */
@@ -161,11 +177,15 @@ button.navds-stepper__step {
161177
color: var(--navds-semantic-color-interaction-primary-selected);
162178
}
163179

164-
:where(.navds-stepper__step:not(.navds-stepper__step--active):hover)
165-
.navds-stepper__content {
180+
:where(.navds-stepper__step:hover) .navds-stepper__content {
166181
text-decoration: underline;
167182
}
168183

184+
:where(.navds-stepper__step--non-interactive:hover, .navds-stepper__step--active:hover)
185+
.navds-stepper__content {
186+
text-decoration: none;
187+
}
188+
169189
:where(.navds-stepper__step--active) .navds-stepper__circle {
170190
background-color: var(--navds-semantic-color-interaction-primary-selected);
171191
border-color: var(--navds-semantic-color-interaction-primary-selected);
@@ -178,3 +198,41 @@ button.navds-stepper__step {
178198
--navds-semantic-color-interaction-primary-hover-subtle
179199
);
180200
}
201+
202+
/* Non-interactive */
203+
:where(.navds-stepper__step--non-interactive.navds-stepper__step--active)
204+
.navds-stepper__content {
205+
color: var(--navds-global-color-gray-900);
206+
}
207+
208+
.navds-stepper__step--non-interactive.navds-stepper__step--behind.navds-stepper__step--completed
209+
+ .navds-stepper__line {
210+
background-color: var(--navds-global-color-gray-600);
211+
}
212+
213+
:where(.navds-stepper__step--non-interactive.navds-stepper__step--active)
214+
.navds-stepper__circle {
215+
background-color: var(--navds-global-color-gray-900);
216+
border-color: var(--navds-global-color-gray-900);
217+
color: var(--navds-global-color-white);
218+
}
219+
220+
:where(.navds-stepper__step--non-interactive:hover) .navds-stepper__circle {
221+
background-color: transparent;
222+
}
223+
224+
:where(.navds-stepper__step--non-interactive.navds-stepper__step--active:hover)
225+
.navds-stepper__circle {
226+
background-color: var(--navds-global-color-gray-900);
227+
}
228+
229+
:where(.navds-stepper__step--completed.navds-stepper__step--active)
230+
.navds-stepper__circle {
231+
background-color: inherit;
232+
color: var(--navds-global-color-deepblue-500);
233+
}
234+
235+
:where(.navds-stepper__step--completed.navds-stepper__step--active.navds-stepper__step--non-interactive)
236+
.navds-stepper__circle {
237+
color: var(--navds-global-color-gray-900);
238+
}

@navikt/core/icons/svg/Success.svg

+13-2
Loading

@navikt/core/react/src/stepper/Step.tsx

+41-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import { SuccessFilled } from "@navikt/ds-icons";
12
import cl from "clsx";
23
import React, { forwardRef, useContext } from "react";
3-
import { StepperContext } from "./Stepper";
44
import { Label, OverridableComponent } from "..";
5+
import { StepperContext } from "./Stepper";
56

67
export interface StepperStepProps
78
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
@@ -14,6 +15,16 @@ export interface StepperStepProps
1415
* @private
1516
*/
1617
unsafe_index?: number;
18+
/**
19+
* Makes step-indicator a checkmark
20+
* @default false
21+
*/
22+
completed?: boolean;
23+
/**
24+
* Makes step non-interactive if false. Step will be set to a <div>, overriding `as`-prop
25+
* @default true
26+
*/
27+
interactive?: boolean;
1728
}
1829

1930
export interface StepperStepType
@@ -24,7 +35,15 @@ export const StepComponent: OverridableComponent<
2435
HTMLAnchorElement
2536
> = forwardRef(
2637
(
27-
{ className, children, as: Component = "a", unsafe_index = 0, ...rest },
38+
{
39+
className,
40+
children,
41+
as: Component = "a",
42+
unsafe_index = 0,
43+
completed = false,
44+
interactive,
45+
...rest
46+
},
2847
ref
2948
) => {
3049
const context = useContext(StepperContext);
@@ -34,26 +53,40 @@ export const StepComponent: OverridableComponent<
3453
}
3554
const { activeStep } = context;
3655

56+
const isInteractive = interactive ?? context?.interactive;
57+
58+
const Comp = isInteractive ? Component : "div";
59+
3760
return (
38-
<Component
61+
<Comp
3962
{...rest}
4063
aria-current={activeStep === unsafe_index}
4164
ref={ref}
4265
className={cl("navds-stepper__step", className, {
4366
"navds-stepper__step--active": activeStep === unsafe_index,
67+
"navds-stepper__step--behind": activeStep > unsafe_index,
68+
"navds-stepper__step--non-interactive": !isInteractive,
69+
"navds-stepper__step--completed": completed,
4470
})}
4571
onClick={(e) => {
46-
context.onStepChange(unsafe_index + 1);
72+
isInteractive && context.onStepChange(unsafe_index + 1);
4773
rest?.onClick?.(e);
4874
}}
4975
>
50-
<Label className="navds-stepper__circle" as="span" aria-hidden="true">
51-
{unsafe_index + 1}
52-
</Label>
76+
{completed ? (
77+
<SuccessFilled
78+
aria-hidden
79+
className="navds-stepper__circle navds-stepper__circle--success"
80+
/>
81+
) : (
82+
<Label className="navds-stepper__circle" as="span" aria-hidden="true">
83+
{unsafe_index + 1}
84+
</Label>
85+
)}
5386
<Label as="span" className="navds-stepper__content">
5487
{children}
5588
</Label>
56-
</Component>
89+
</Comp>
5790
);
5891
}
5992
);

@navikt/core/react/src/stepper/Stepper.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ export interface StepperProps extends React.HTMLAttributes<HTMLOListElement> {
2222
* @note Stepper index starts at 1, not 0
2323
*/
2424
onStepChange?: (step: number) => void;
25+
/**
26+
* Makes stepper non-interactive if false
27+
* @default true
28+
*/
29+
interactive?: boolean;
2530
}
2631

2732
interface StepperComponent
@@ -36,6 +41,7 @@ interface StepperContextProps {
3641
onStepChange: (step: number) => void;
3742
lastIndex: number;
3843
orientation: "horizontal" | "vertical";
44+
interactive: boolean;
3945
}
4046

4147
export const StepperContext = createContext<StepperContextProps | null>(null);
@@ -51,6 +57,7 @@ export const Stepper: StepperComponent = forwardRef<
5157
activeStep,
5258
orientation = "vertical",
5359
onStepChange = () => {},
60+
interactive = true,
5461
...rest
5562
},
5663
ref
@@ -72,6 +79,7 @@ export const Stepper: StepperComponent = forwardRef<
7279
onStepChange,
7380
lastIndex: React.Children.count(children),
7481
orientation,
82+
interactive,
7583
}}
7684
>
7785
{React.Children.map(children, (step, index) => {

0 commit comments

Comments
 (0)