Skip to content

Commit b6142ed

Browse files
feat: added it-stepper (#370)
* feat: added it-stepper * fix: fix stepper styles and implementation, add examples and tests * fix: stepper styles and stories * feat: added `it-stepper` * docs: added changeset * chore: updated examples * docs: updated changeset * fix: fouc styles * chore: updated full.css * fix: lockfile --------- Co-authored-by: Martina Bustacchini <martina.bustacchini@redturtle.it>
1 parent d74f305 commit b6142ed

48 files changed

Lines changed: 3794 additions & 1200 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@italia/section",
4444
"@italia/select",
4545
"@italia/skiplinks",
46+
"@italia/stepper",
4647
"@italia/sticky",
4748
"@italia/tabs",
4849
"@italia/timeline",

.changeset/shy-areas-talk.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@italia/dev-kit-italia': minor
3+
'@italia/stepper': minor
4+
---
5+
6+
Added `it-stepper` component

.storybook/elements.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import '../packages/section/dist/src';
3131
import '../packages/select/dist/src';
3232
import '../packages/skiplinks/dist/src';
3333
import '../packages/sticky/dist/src';
34+
import '../packages/stepper/dist/src';
3435
import '../packages/tabs/dist/src';
3536
import '../packages/thumbnav/dist/src';
3637
import '../packages/timeline/dist/src';

examples/angular-app/package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/angular-app/src/app/app.routes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ export const routes: Routes = [
230230
path: 'sticky',
231231
loadComponent: () => import('./pages/sticky.component').then((c) => c.StickyComponent),
232232
},
233+
{
234+
title: 'Stepper',
235+
path: 'stepper',
236+
loadComponent: () => import('./pages/stepper.component').then((c) => c.StepperComponent),
237+
},
233238
{
234239
title: 'Tables',
235240
path: 'tables',
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<div
2+
class="stepper-examples"
3+
(it-stepper-change)="logStepperEvent($event)"
4+
(it-stepper-save)="logStepperEvent($event)"
5+
(it-stepper-confirm)="logStepperEvent($event)"
6+
>
7+
<h1>Stepper</h1>
8+
9+
<section>
10+
<h2>Solo testo</h2>
11+
<it-stepper current="1" header-variant="text">
12+
<it-stepper-step
13+
*ngFor="let step of steps; let index = index"
14+
[attr.icon]="step.icon"
15+
>
16+
<span slot="label">{{ step.label }}</span>
17+
<div class="p-5 text-center border bg-light"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
18+
</it-stepper-step>
19+
</it-stepper>
20+
</section>
21+
22+
<section>
23+
<h2>Testo e icone</h2>
24+
<it-stepper current="1" header-variant="icons">
25+
<it-stepper-step
26+
*ngFor="let step of steps; let index = index"
27+
[attr.icon]="step.icon"
28+
>
29+
<span slot="label">{{ step.label }}</span>
30+
<div class="p-5 text-center border bg-light"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
31+
</it-stepper-step>
32+
</it-stepper>
33+
</section>
34+
35+
<section>
36+
<h2>Testo e numeri</h2>
37+
<it-stepper current="1" header-variant="numbers">
38+
<it-stepper-step
39+
*ngFor="let step of steps; let index = index"
40+
[attr.icon]="step.icon"
41+
>
42+
<span slot="label">{{ step.label }}</span>
43+
<div class="p-5 text-center border bg-light"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
44+
</it-stepper-step>
45+
</it-stepper>
46+
</section>
47+
48+
<section>
49+
<h2>Navigazione degli step</h2>
50+
<it-stepper current="1" prev-label="Precedente" next-label="Successivo">
51+
<it-stepper-step
52+
*ngFor="let step of steps; let index = index"
53+
[attr.icon]="step.icon"
54+
>
55+
<span slot="label">{{ step.label }}</span>
56+
<div class="p-5 text-center border bg-light"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
57+
</it-stepper-step>
58+
</it-stepper>
59+
</section>
60+
61+
<section>
62+
<h2>Progress bar</h2>
63+
<it-stepper current="1" mobile-progress="bar" mobile-progress-on-desktop>
64+
<it-stepper-step
65+
*ngFor="let step of steps; let index = index"
66+
[attr.icon]="step.icon"
67+
>
68+
<span slot="label">{{ step.label }}</span>
69+
<div class="p-5 text-center border bg-light"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
70+
</it-stepper-step>
71+
</it-stepper>
72+
</section>
73+
74+
<section>
75+
<h2>Pallini</h2>
76+
<it-stepper current="1" mobile-progress="dots" mobile-progress-on-desktop>
77+
<it-stepper-step
78+
*ngFor="let step of steps; let index = index"
79+
[attr.icon]="step.icon"
80+
>
81+
<span slot="label">{{ step.label }}</span>
82+
<div class="p-5 text-center border bg-light"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
83+
</it-stepper-step>
84+
</it-stepper>
85+
</section>
86+
87+
<section>
88+
<h2>Salva</h2>
89+
<it-stepper
90+
current="1"
91+
save-label="Salva"
92+
save-title="Vuoi salvare il progresso?"
93+
save-description="Potrai riprendere il flusso da questo punto in poi."
94+
>
95+
<it-stepper-step
96+
*ngFor="let step of steps; let index = index"
97+
[attr.icon]="step.icon"
98+
>
99+
<span slot="label">{{ step.label }}</span>
100+
<div class="p-5 text-center border bg-light"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
101+
</it-stepper-step>
102+
</it-stepper>
103+
</section>
104+
105+
<section>
106+
<h2>Conferma</h2>
107+
<it-stepper current="1" show-confirm confirm-label="Conferma">
108+
<it-stepper-step
109+
*ngFor="let step of steps; let index = index"
110+
[attr.icon]="step.icon"
111+
>
112+
<span slot="label">{{ step.label }}</span>
113+
<div class="p-5 text-center border bg-light"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
114+
</it-stepper-step>
115+
</it-stepper>
116+
</section>
117+
118+
<section class="bg-dark p-4">
119+
<h2 class="text-white">Sfondo scuro</h2>
120+
<it-stepper current="1" dark>
121+
<it-stepper-step
122+
*ngFor="let step of steps; let index = index"
123+
[attr.icon]="step.icon"
124+
>
125+
<span slot="label">{{ step.label }}</span>
126+
<div class="p-5 text-center border text-white"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
127+
</it-stepper-step>
128+
</it-stepper>
129+
</section>
130+
131+
<section class="stepper-variant-stack bg-dark p-4">
132+
<h2 class="text-white">Sfondo scuro - varianti intestazione</h2>
133+
<it-stepper current="1" dark header-variant="text">
134+
<it-stepper-step
135+
*ngFor="let step of steps; let index = index"
136+
[attr.icon]="step.icon"
137+
>
138+
<span slot="label">{{ step.label }}</span>
139+
<div class="p-5 text-center border text-white"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
140+
</it-stepper-step>
141+
</it-stepper>
142+
<it-stepper current="1" dark header-variant="icons">
143+
<it-stepper-step
144+
*ngFor="let step of steps; let index = index"
145+
[attr.icon]="step.icon"
146+
>
147+
<span slot="label">{{ step.label }}</span>
148+
<div class="p-5 text-center border text-white"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
149+
</it-stepper-step>
150+
</it-stepper>
151+
<it-stepper current="1" dark header-variant="numbers">
152+
<it-stepper-step
153+
*ngFor="let step of steps; let index = index"
154+
[attr.icon]="step.icon"
155+
>
156+
<span slot="label">{{ step.label }}</span>
157+
<div class="p-5 text-center border text-white"><p class="m-0">Contenuto dello step {{ index + 1 }}</p></div>
158+
</it-stepper-step>
159+
</it-stepper>
160+
</section>
161+
</div>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { NgFor } from '@angular/common';
2+
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
3+
4+
@Component({
5+
selector: 'app-stepper',
6+
templateUrl: './stepper.component.html',
7+
imports: [NgFor],
8+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
9+
standalone: true,
10+
styles: [
11+
`
12+
.stepper-examples {
13+
display: flex;
14+
flex-direction: column;
15+
gap: var(--bsi-spacing-xl, 2rem);
16+
}
17+
18+
.stepper-variant-stack {
19+
display: flex;
20+
flex-direction: column;
21+
gap: var(--bsi-spacing-xl);
22+
}
23+
`,
24+
],
25+
})
26+
export class StepperComponent {
27+
steps = [
28+
{ label: 'Primo contenuto', icon: 'it-calendar' },
29+
{ label: 'Secondo contenuto', icon: 'it-lock' },
30+
{ label: 'Terzo contenuto', icon: 'it-settings' },
31+
];
32+
33+
logStepperEvent(event: Event): void {
34+
console.info(event.type, (event as CustomEvent).detail);
35+
}
36+
}

examples/react-app/package-lock.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { useEffect, useRef } from 'react';
2+
3+
const steps = [
4+
{ label: 'Primo contenuto', icon: 'it-calendar' },
5+
{ label: 'Secondo contenuto', icon: 'it-lock' },
6+
{ label: 'Terzo contenuto', icon: 'it-settings' },
7+
];
8+
9+
function StepperExample({ dark = false, headerVariant = '', mobileProgress = '', ...attrs }) {
10+
const stepperAttrs = {
11+
current: 1,
12+
dark: dark || undefined,
13+
'header-variant': headerVariant || undefined,
14+
'mobile-progress': mobileProgress || undefined,
15+
...attrs,
16+
};
17+
18+
return (
19+
<it-stepper {...stepperAttrs}>
20+
{steps.map((step, index) => (
21+
<it-stepper-step key={step.label} icon={step.icon}>
22+
<span slot="label">{step.label}</span>
23+
<div className={`p-5 text-center border ${dark ? 'text-white' : 'bg-light'}`}>
24+
<p className="m-0">Contenuto dello step {index + 1}</p>
25+
</div>
26+
</it-stepper-step>
27+
))}
28+
</it-stepper>
29+
);
30+
}
31+
32+
const Stepper = () => {
33+
const rootRef = useRef(null);
34+
35+
useEffect(() => {
36+
const root = rootRef.current;
37+
if (!root) return undefined;
38+
39+
const logStepperEvent = (event) => console.info(event.type, event.detail);
40+
root.addEventListener('it-stepper-change', logStepperEvent);
41+
root.addEventListener('it-stepper-save', logStepperEvent);
42+
root.addEventListener('it-stepper-confirm', logStepperEvent);
43+
44+
return () => {
45+
root.removeEventListener('it-stepper-change', logStepperEvent);
46+
root.removeEventListener('it-stepper-save', logStepperEvent);
47+
root.removeEventListener('it-stepper-confirm', logStepperEvent);
48+
};
49+
}, []);
50+
51+
return (
52+
<div ref={rootRef} className="stepper-examples">
53+
<style>{`
54+
.stepper-examples {
55+
display: flex;
56+
flex-direction: column;
57+
gap: var(--bsi-spacing-xl, 2rem);
58+
}
59+
60+
.stepper-variant-stack {
61+
display: flex;
62+
flex-direction: column;
63+
gap: var(--bsi-spacing-xl);
64+
}
65+
`}</style>
66+
67+
<h1>Stepper</h1>
68+
69+
<section>
70+
<h2>Solo testo</h2>
71+
<StepperExample headerVariant="text" />
72+
</section>
73+
74+
<section>
75+
<h2>Testo e icone</h2>
76+
<StepperExample headerVariant="icons" />
77+
</section>
78+
79+
<section>
80+
<h2>Testo e numeri</h2>
81+
<StepperExample headerVariant="numbers" />
82+
</section>
83+
84+
<section>
85+
<h2>Navigazione degli step</h2>
86+
<StepperExample {...{ 'prev-label': 'Precedente', 'next-label': 'Successivo' }} />
87+
</section>
88+
89+
<section>
90+
<h2>Progress bar</h2>
91+
<StepperExample mobileProgress="bar" {...{ 'mobile-progress-on-desktop': '' }} />
92+
</section>
93+
94+
<section>
95+
<h2>Pallini</h2>
96+
<StepperExample mobileProgress="dots" {...{ 'mobile-progress-on-desktop': '' }} />
97+
</section>
98+
99+
<section>
100+
<h2>Salva</h2>
101+
<StepperExample
102+
{...{
103+
'save-label': 'Salva',
104+
'save-title': 'Vuoi salvare il progresso?',
105+
'save-description': 'Potrai riprendere il flusso da questo punto in poi.',
106+
}}
107+
/>
108+
</section>
109+
110+
<section>
111+
<h2>Conferma</h2>
112+
<StepperExample {...{ 'show-confirm': '', 'confirm-label': 'Conferma' }} />
113+
</section>
114+
115+
<section className="bg-dark p-4">
116+
<h2 className="text-white">Sfondo scuro</h2>
117+
<StepperExample dark />
118+
</section>
119+
120+
<section className="stepper-variant-stack bg-dark p-4">
121+
<h2 className="text-white">Sfondo scuro - varianti intestazione</h2>
122+
<StepperExample dark headerVariant="text" />
123+
<StepperExample dark headerVariant="icons" />
124+
<StepperExample dark headerVariant="numbers" />
125+
</section>
126+
</div>
127+
);
128+
};
129+
130+
export default Stepper;

0 commit comments

Comments
 (0)