Skip to content

Commit a8405ce

Browse files
authored
feat: new carousel component
1 parent d0990b6 commit a8405ce

File tree

10 files changed

+4212
-11
lines changed

10 files changed

+4212
-11
lines changed

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
"@types/react-bootstrap": "^0.32.37",
109109
"@types/react-dom": "^18.2.24",
110110
"@types/react-transition-group": "^4.4.10",
111-
"bootstrap-italia": "^2.13.4",
111+
"bootstrap-italia": "^2.14.0",
112112
"browserslist-config-design-italia": "^1.0.0",
113113
"eslint": "^9.10.0",
114114
"eslint-plugin-mdx": "^3.1.5",
@@ -135,6 +135,8 @@
135135
"vite": "^5.2.7"
136136
},
137137
"dependencies": {
138+
"@splidejs/react-splide": "^0.7.12",
139+
"accessible-autocomplete": "^3.0.1",
138140
"classnames": "^2.3.1",
139141
"is-number": "^7.0.0",
140142
"react-bootstrap": "^2.10.6",

src/Carousel/Carousel.tsx

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
import React, { FC } from 'react';
2+
import classNames from 'classnames';
3+
4+
import {Splide, SplideProps} from '@splidejs/react-splide'
5+
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7+
const CONFIG_DEFAULT: any = {
8+
slideFocus: false,
9+
rewind: true,
10+
perMove: 1,
11+
i18n: {
12+
prev: 'Slide precedente',
13+
next: 'Slide successiva',
14+
first: 'Vai alla prima slide',
15+
last: 'Vai all’ultima slide',
16+
slideX: 'Vai alla slide %s',
17+
pageX: 'Vai a pagina %s',
18+
play: 'Attiva autoplay',
19+
pause: 'Pausa autoplay',
20+
carousel: 'Carosello',
21+
select: 'Seleziona una slide da mostrare',
22+
slide: 'slide',
23+
slideLabel: '%s di %s',
24+
},
25+
}
26+
27+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
28+
const CONFIGS: any= {
29+
'landscape-three-cols': {
30+
type: 'slide',
31+
perPage: 3,
32+
gap: 24,
33+
padding: { left: 0, right: 0 },
34+
arrows: false,
35+
breakpoints: {
36+
768: {
37+
perPage: 1,
38+
gap: 24,
39+
padding: { left: 0, right: 0 },
40+
arrows: false,
41+
},
42+
992: {
43+
perPage: 2,
44+
gap: 24,
45+
padding: { left: 40, right: 40 },
46+
arrows: false,
47+
},
48+
},
49+
},
50+
'landscape-three-cols-arrows': {
51+
type: 'slide',
52+
perPage: 3,
53+
gap: 24,
54+
padding: { left: 0, right: 0 },
55+
arrows: true,
56+
breakpoints: {
57+
768: {
58+
perPage: 1,
59+
gap: 24,
60+
padding: { left: 40, right: 40 },
61+
arrows: true,
62+
},
63+
992: {
64+
perPage: 2,
65+
gap: 24,
66+
padding: { left: 40, right: 40 },
67+
arrows: true,
68+
},
69+
},
70+
},
71+
'big-image': {
72+
type: 'loop',
73+
perPage: 1,
74+
gap: 48,
75+
padding: { left: 320, right: 320 },
76+
arrows: false,
77+
breakpoints: {
78+
768: {
79+
perPage: 1,
80+
gap: 0,
81+
padding: { left: 0, right: 0 },
82+
arrows: false,
83+
},
84+
992: {
85+
perPage: 1,
86+
gap: 24,
87+
padding: { left: 160, right: 160 },
88+
arrows: false,
89+
},
90+
},
91+
},
92+
'standard-image': {
93+
type: 'loop',
94+
perPage: 3,
95+
gap: 24,
96+
padding: { left: 48, right: 48 },
97+
arrows: false,
98+
breakpoints: {
99+
768: {
100+
perPage: 1,
101+
gap: 24,
102+
padding: { left: 40, right: 40 },
103+
arrows: false,
104+
},
105+
992: {
106+
perPage: 2,
107+
gap: 24,
108+
padding: { left: 48, right: 48 },
109+
arrows: false,
110+
},
111+
},
112+
},
113+
'landscape': {
114+
type: 'slide',
115+
perPage: 1,
116+
gap: 24,
117+
padding: { left: 0, right: 0 },
118+
arrows: false,
119+
breakpoints: {
120+
768: {
121+
perPage: 1,
122+
gap: 24,
123+
padding: { left: 0, right: 0 },
124+
arrows: false,
125+
},
126+
992: {
127+
perPage: 1,
128+
gap: 24,
129+
padding: { left: 24, right: 24 },
130+
arrows: false,
131+
},
132+
},
133+
},
134+
'calendar-wrapper': {
135+
type: 'slide',
136+
perPage: 4,
137+
gap: 0,
138+
padding: { left: 0, right: 0 },
139+
arrows: false,
140+
breakpoints: {
141+
560: {
142+
perPage: 1,
143+
gap: 0,
144+
padding: { left: 24, right: 24 },
145+
arrows: false,
146+
},
147+
768: {
148+
perPage: 2,
149+
gap: 0,
150+
padding: { left: 0, right: 0 },
151+
arrows: false,
152+
},
153+
992: {
154+
perPage: 3,
155+
gap: 0,
156+
padding: { left: 0, right: 0 },
157+
arrows: false,
158+
},
159+
},
160+
},
161+
}
162+
163+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
164+
const EXTRA_CLASSES: any= {
165+
'landscape-three-cols': [
166+
'it-carousel-landscape-abstract-three-cols'
167+
],
168+
'landscape-three-cols-arrows': [
169+
'it-carousel-landscape-abstract-three-cols-arrow-visible'
170+
],
171+
'big-image': [
172+
'it-carousel-landscape-abstract-three-cols',
173+
'it-full-carousel',
174+
'it-big-img'
175+
],
176+
'standard-image': [
177+
'it-carousel-landscape-abstract-three-cols',
178+
'it-full-carousel',
179+
'it-standard-image'
180+
],
181+
'landscape': [
182+
'it-carousel-landscape-abstract'
183+
],
184+
'calendar-wrapper': [
185+
'it-calendar-wrapper'
186+
]
187+
}
188+
189+
export interface CarouselProps extends SplideProps {
190+
type: string;
191+
children?: React.ReactNode;
192+
}
193+
194+
// Splide wrapper
195+
export const Carousel: FC<CarouselProps> = ({
196+
className = '',
197+
type,
198+
children,
199+
...attributes
200+
}) => {
201+
let conf = Object.assign({}, CONFIG_DEFAULT)
202+
if (['big-image', 'standard-image'].includes(type)){
203+
conf = Object.assign({}, conf, CONFIGS['landscape-three-cols'])
204+
}
205+
conf = Object.assign({}, conf, CONFIGS[type])
206+
return <Splide
207+
{...attributes}
208+
className={classNames('it-carousel-wrapper', className, ...EXTRA_CLASSES[type])}
209+
options={conf}>{children}</Splide>;
210+
};

src/Carousel/CarouselSlide.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
import {SplideSlide} from '@splidejs/react-splide'
3+
4+
// Splide wrapper
5+
export const CarouselSlide: React.FC<JSX.IntrinsicElements['li']> = ({
6+
children,
7+
}) => {
8+
9+
return <SplideSlide>
10+
<div className='it-single-slide-wrapper'>
11+
{children}
12+
</div>
13+
</SplideSlide>;
14+
};

src/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ export { CardTag } from './Card/CardTag';
7979
export { CardTagsHeader } from './Card/CardTagsHeader';
8080
export { CardText } from './Card/CardText';
8181
export { CardTitle } from './Card/CardTitle';
82+
export { Carousel } from './Carousel/Carousel';
83+
export { CarouselSlide } from './Carousel/CarouselSlide';
8284
export { Chip } from './Chips/Chip';
8385
export { ChipLabel } from './Chips/ChipLabel';
8486
export { Collapse } from './Collapse/Collapse';
@@ -178,6 +180,7 @@ export type { CardTagProps } from './Card/CardTag';
178180
export type { CardTagsHeaderProps } from './Card/CardTagsHeader';
179181
export type { CardTextProps } from './Card/CardText';
180182
export type { CardTitleProps } from './Card/CardTitle';
183+
export type { CarouselProps } from './Carousel/Carousel';
181184
export type { ChipProps } from './Chips/Chip';
182185
export type { ChipLabelProps } from './Chips/ChipLabel';
183186
export type { DimmerProps } from './Dimmer/Dimmer';

0 commit comments

Comments
 (0)