Skip to content

Commit 7b4d1fd

Browse files
kuusmahboubii
andauthored
Carousel simpler (#36)
* carousel: new simpler carousel, no deps, scroll and css based, slide width is configurable * carousel: add example wit custom slides width * carousel: don't use min width, just use flex widths * carousel: fix forgotten @ts-ignore * carousel: cleanup comments * fix type err Co-authored-by: Amin Mahboubi <aminmahboobi@gmail.com>
1 parent 8ccf792 commit 7b4d1fd

10 files changed

Lines changed: 332 additions & 606 deletions

File tree

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
"dayjs": "^1.9.7",
4747
"ical-expander": "^3.1.0",
4848
"linkifyjs": "^2.1.9",
49-
"pure-react-carousel": "^1.27.6",
5049
"react-markdown": "^5.0.3",
5150
"react-virtuoso": "^0.20.3"
5251
},

src/components/Carousel.mdx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,34 @@ It displays a sliding carousel
7171
`}
7272
/>
7373
</Playground>
74+
75+
## With custom slides width
76+
77+
<Playground>
78+
<MML
79+
source={`
80+
<mml>
81+
<carousel slideWidth="60%">
82+
<item width="150px">
83+
<image src="https://getstream.github.io/mml-react/public/door.jpg" />
84+
<md>**Door**</md>
85+
<text>Locks, hinges, screens, stuck...</text>
86+
<button name="action" value="door">Select</button>
87+
</item>
88+
<item>
89+
<image src="https://getstream.github.io/mml-react/public/window.jpg" />
90+
<md>**Window**</md>
91+
<text>Glass, slide, locks, broken, damage...</text>
92+
<button name="action" value="window">Select</button>
93+
</item>
94+
<item>
95+
<image src="https://getstream.github.io/mml-react/public/sliding-door.jpg" />
96+
<md>**Sliding door**</md>
97+
<text>Locks, hinges, screens, stuck...</text>
98+
<button name="action" value="sliding-door">Select</button>
99+
</item>
100+
</carousel>
101+
</mml>
102+
`}
103+
/>
104+
</Playground>

src/components/Carousel.tsx

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,41 @@
1-
import React, { FC, ReactElement } from 'react';
2-
import { CarouselProvider, Slider } from 'pure-react-carousel';
1+
import React, { FC, ReactElement, Children, cloneElement } from 'react';
32
import { CarouselItemProps } from './CarouselItem';
43

54
export type CarouselProps = {
6-
/** Infinite loop */
7-
infinite?: boolean;
8-
/** Amount of slides per view */
9-
perView?: number;
10-
/** Amount of slides per move */
11-
perMove?: number;
12-
/** Auto calculate slides' height */
13-
autoHeight?: boolean;
14-
/** Ideal slide width */
15-
slideWidth?: number;
16-
/** Ideal slide height */
17-
slideHeight?: number;
18-
/** A list of carousel items */
5+
/**
6+
* The only children of the Carousel are the carousel item.
7+
*/
198
children?: ReactElement<CarouselItemProps>[] | ReactElement<CarouselItemProps>;
9+
/**
10+
* Base slide width set on the `Carousel` component level, it can be overriden for each CarouselItem by setting
11+
* a `width` attribute on the `<item>` component.
12+
*
13+
* It can be set to either a percentage, e.g. `slideWidth="40%"` or to a pixel based value `slideWidth="200px"`.
14+
*
15+
* @default '120px'
16+
*/
17+
slideWidth?: string;
18+
/**
19+
* Additional carousel class name
20+
*/
21+
className?: string;
2022
};
2123

2224
/**
23-
* A carousel is a nice mobile friendly way of letting a user select
24-
* something
25+
* A carousel is a nice mobile friendly way of letting a user select something
26+
*
27+
* Super simple scroll based carousel slightly inspired by [react-scroll-snap-slider](https://github.com/lifarl/react-scroll-snap-slider)
2528
*/
26-
export const Carousel: FC<CarouselProps> = ({
27-
infinite = true,
28-
perView = 2.5,
29-
perMove = 1,
30-
autoHeight = true,
31-
slideWidth = 100,
32-
slideHeight = 125,
33-
children,
34-
}) => {
29+
export const Carousel: FC<CarouselProps> = ({ children, slideWidth = '120px', className = '' }) => {
3530
return (
36-
<div className="mml-carousel">
37-
<CarouselProvider
38-
className="mml"
39-
infinite={infinite}
40-
visibleSlides={perView}
41-
step={perMove}
42-
isIntrinsicHeight={autoHeight}
43-
naturalSlideWidth={slideWidth}
44-
naturalSlideHeight={slideHeight}
45-
totalSlides={React.Children.count(children)}
46-
>
47-
<Slider>{children}</Slider>
48-
</CarouselProvider>
31+
<div className={`mml-carousel ${className}`}>
32+
<div className="mml-carousel__track">
33+
<div className="mml-carousel__slides">
34+
{Children.map(children as ReactElement, (child) =>
35+
cloneElement(child, { className: 'mml-carousel__slide', slideWidth }),
36+
)}
37+
</div>
38+
</div>
4939
</div>
5040
);
5141
};

src/components/CarouselItem.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
import React, { FC, ReactNode } from 'react';
2-
import { Slide } from 'pure-react-carousel';
2+
import { CarouselProps } from './Carousel';
33

44
export type CarouselItemProps = {
5-
/** The error message */
5+
/**
6+
* The carousel item inner components can contain any type of nodes, such as buttons, images, etc.
7+
*/
68
children?: ReactNode;
7-
};
9+
/**
10+
* Determines the slide width, it can be set to either a percentage, e.g. `width="40%"` or to a pixel based value `width="200px"`.
11+
* It defaults to the `slideWidth` prop set at the `<carousel>` level
12+
*
13+
* @default ''
14+
*/
15+
width?: string;
16+
/**
17+
* Additional carousel item class name
18+
*/
19+
className?: string;
20+
} & Pick<CarouselProps, 'slideWidth'>;
821

922
/**
10-
* The only children of the Carousel are the carousel item.
11-
* A carousel item can contain any type of nodes, such as buttons, images etc.
23+
* A carousel item
1224
*/
13-
export const CarouselItem: FC<CarouselItemProps> = ({ children }) => {
14-
//TODO: index should come from parser as prop
25+
export const CarouselItem: FC<CarouselItemProps> = ({ children, slideWidth, width = '', className = '' }) => {
26+
const finalWidth = width || slideWidth;
1527
return (
16-
<Slide index={0} className="mml-carousel-item">
28+
<div className={`mml-carousel-item ${className}`} style={{ flex: `0 0 ${finalWidth}`, minWidth: finalWidth }}>
1729
{children}
18-
</Slide>
30+
</div>
1931
);
2032
};

0 commit comments

Comments
 (0)