Skip to content

Commit 56f084c

Browse files
author
unknown
committed
1.0.0-beta3
1 parent 1792e24 commit 56f084c

34 files changed

+619
-7
lines changed

README.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MDB 5 React
22

3-
Version: FREE 1.0.0-beta2
3+
Version: FREE 1.0.0-beta3
44

55
Documentation:
66
https://mdbootstrap.com/docs/b5/react/

app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mdb-react-ui-kit-demo",
3-
"version": "1.0.0-beta2",
3+
"version": "1.0.0-beta3",
44
"main": "index.js",
55
"repository": {
66
"type": "git",

app/public/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
<link rel="shortcut icon" href="/favicon.ico" />
1414
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
15+
1516
<!--
1617
Notice the use of %PUBLIC_URL% in the tags above.
1718
It will be replaced with the URL of the `public` folder during the build.
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import clsx from 'clsx';
2+
import React, { useCallback, useEffect, useRef, useState } from 'react';
3+
import type { CarouselProps } from './types';
4+
import MDBCarouselControl from './CarouselControl/CarouselControl';
5+
import MDBCarouselIndicatorItem from './CarouselIndicatorItem/CarouselIndicatorItem';
6+
import { CarouselContext } from './CarouselContext';
7+
const MDBCarousel: React.FC<CarouselProps> = ({
8+
fade,
9+
className,
10+
dark,
11+
children,
12+
carouselRef,
13+
interval,
14+
keyboard,
15+
pause,
16+
touch,
17+
tag: Tag,
18+
showControls,
19+
showIndicators,
20+
...props
21+
}) => {
22+
const [isChanging, setIsChanging] = useState(false);
23+
const [imagesCount, setImagesCount] = useState(0);
24+
const [activeItem, setActiveItem] = useState(0);
25+
const [prevState, setPrevState] = useState(0);
26+
const [startInterval, setStartInterval] = useState(true);
27+
const [clientTouch, setClientTouch] = useState({ initialX: 0, initialY: 0 });
28+
29+
const carouselInnerRef = useRef<HTMLElement>(null);
30+
const carouselReference = carouselRef ? carouselRef : carouselInnerRef;
31+
32+
const classes = clsx('carousel', 'slide', fade && 'carousel-fade', dark && 'carousel-dark', className);
33+
34+
const setPrev = useCallback(() => {
35+
const prevIndex = activeItem === 0 ? imagesCount : activeItem - 1;
36+
37+
setActiveItem(prevIndex);
38+
}, [activeItem, imagesCount]);
39+
40+
const setNext = useCallback(() => {
41+
const nextIndex = activeItem === imagesCount ? 0 : activeItem + 1;
42+
43+
setActiveItem(nextIndex);
44+
}, [activeItem, imagesCount]);
45+
46+
const handleKeydown = useCallback(
47+
(event: KeyboardEvent) => {
48+
console.log(event.key);
49+
switch (event.key) {
50+
case 'ArrowLeft':
51+
event.preventDefault();
52+
setPrev();
53+
break;
54+
55+
case 'ArrowRight':
56+
event.preventDefault();
57+
setNext();
58+
break;
59+
60+
default:
61+
}
62+
},
63+
[setPrev, setNext]
64+
);
65+
66+
const handleControlClick = (isNext: boolean) => {
67+
if (!isChanging && !isNext) {
68+
setPrev();
69+
setIsChanging(true);
70+
71+
setTimeout(() => {
72+
setIsChanging(false);
73+
}, 700);
74+
} else if (!isChanging && isNext) {
75+
setNext();
76+
setIsChanging(true);
77+
78+
setTimeout(() => {
79+
setIsChanging(false);
80+
}, 700);
81+
} else {
82+
return;
83+
}
84+
};
85+
86+
const handleIndicatorClick = (i: number) => {
87+
if (!isChanging) {
88+
setActiveItem(i);
89+
setIsChanging(true);
90+
91+
setTimeout(() => {
92+
setIsChanging(false);
93+
}, 700);
94+
}
95+
};
96+
97+
useEffect(() => {
98+
if (keyboard) {
99+
document.addEventListener('keydown', handleKeydown);
100+
101+
return () => {
102+
document.removeEventListener('keydown', handleKeydown);
103+
};
104+
}
105+
}, [handleKeydown, keyboard]);
106+
107+
useEffect(() => {
108+
if (interval && startInterval) {
109+
const cycleInterval = setInterval(setNext, interval);
110+
111+
return () => {
112+
clearInterval(cycleInterval);
113+
};
114+
}
115+
}, [interval, setNext, startInterval]);
116+
117+
useEffect(() => {
118+
const carouselImgList = carouselReference.current.querySelectorAll('.carousel-item-react img');
119+
120+
setImagesCount(carouselImgList.length - 1);
121+
}, [carouselReference, showIndicators]);
122+
123+
const startTouch = (e: TouchEvent) => {
124+
touch && setClientTouch({ initialX: e.touches[0].clientX, initialY: e.touches[0].clientY });
125+
};
126+
127+
const moveTouch = (e: TouchEvent) => {
128+
setIsChanging(true);
129+
130+
const { initialX, initialY } = clientTouch;
131+
132+
if (!initialX || !initialY) {
133+
return;
134+
}
135+
136+
const currentX = e.touches[0].clientX;
137+
const currentY = e.touches[0].clientY;
138+
139+
const diffX = initialX - currentX;
140+
const diffY = initialY - currentY;
141+
142+
if (Math.abs(diffX) > Math.abs(diffY)) {
143+
// sliding horizontally
144+
if (diffX > 0) {
145+
setNext();
146+
} else {
147+
setPrev();
148+
}
149+
}
150+
151+
setClientTouch({ initialX: 0, initialY: 0 });
152+
};
153+
154+
return (
155+
<CarouselContext.Provider
156+
value={{
157+
activeItem: activeItem ? activeItem : 0,
158+
imagesCount: imagesCount,
159+
fade: fade ? true : false,
160+
prev: prevState,
161+
setPrev: setPrevState,
162+
}}
163+
>
164+
<Tag
165+
onTouchStart={startTouch}
166+
onTouchMove={!isChanging ? moveTouch : null}
167+
onTouchEnd={() => setIsChanging(false)}
168+
onMouseEnter={pause ? () => setStartInterval(false) : null}
169+
onMouseLeave={pause ? () => setStartInterval(true) : null}
170+
className={classes}
171+
ref={carouselReference}
172+
{...props}
173+
>
174+
{showIndicators && (
175+
<ol className='carousel-indicators'>
176+
{Array.from(Array(imagesCount + 1)).map((item, i) => (
177+
<MDBCarouselIndicatorItem key={i} active={activeItem === i} onClick={() => handleIndicatorClick(i)} />
178+
))}
179+
</ol>
180+
)}
181+
{children}
182+
{showControls && (
183+
<>
184+
<MDBCarouselControl direction='prev' onClick={() => handleControlClick(false)} />
185+
<MDBCarouselControl direction='next' onClick={() => handleControlClick(true)} />
186+
</>
187+
)}
188+
</Tag>
189+
</CarouselContext.Provider>
190+
);
191+
};
192+
MDBCarousel.defaultProps = { tag: 'div', interval: 5000, fade: false, pause: true, touch: true, keyboard: false };
193+
export default MDBCarousel;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import clsx from 'clsx';
2+
import React from 'react';
3+
import type { CarouselCaptionProps } from './types';
4+
5+
const MDBCarouselCaption: React.FC<CarouselCaptionProps> = React.forwardRef<HTMLAllCollection, CarouselCaptionProps>(
6+
({ className, tag: Tag, children, ...props }, ref) => {
7+
const classes = clsx('carousel-caption', 'd-none', 'd-md-block', className);
8+
9+
return (
10+
<Tag className={classes} ref={ref} {...props}>
11+
{children}
12+
</Tag>
13+
);
14+
}
15+
);
16+
17+
MDBCarouselCaption.defaultProps = { tag: 'div' };
18+
19+
export default MDBCarouselCaption;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
3+
declare const MDBCarouselCaption: React.FunctionComponent<{
4+
className?: string;
5+
tag?: React.ComponentProps<any>;
6+
[rest: string]: any;
7+
}>;
8+
9+
export default MDBCarouselCaption;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react';
2+
3+
type CarouselCaptionProps = {
4+
className?: string;
5+
tag?: React.ComponentProps<any>;
6+
[rest: string]: any;
7+
};
8+
9+
export { CarouselCaptionProps };
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
3+
interface CarouselProps {
4+
activeItem: number;
5+
imagesCount: number;
6+
fade: boolean;
7+
prev: number;
8+
setPrev: React.SetStateAction<any>;
9+
}
10+
11+
const CarouselContext = React.createContext<CarouselProps>({
12+
activeItem: 0,
13+
imagesCount: 0,
14+
fade: false,
15+
prev: 0,
16+
setPrev: null,
17+
});
18+
19+
export { CarouselContext };
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import clsx from 'clsx';
2+
import React from 'react';
3+
import type { CarouselControlProps } from './types';
4+
5+
const MDBCarouselControl: React.FC<CarouselControlProps> = React.forwardRef<HTMLAllCollection, CarouselControlProps>(
6+
({ className, direction, tag: Tag, ...props }, ref) => {
7+
const classes = clsx(`carousel-control-${direction}`, className);
8+
9+
return (
10+
<Tag role='button' className={classes} ref={ref} {...props}>
11+
<span className={`carousel-control-${direction}-icon`}></span>
12+
{direction === 'prev' ? (
13+
<span className='visually-hidden'>Previous</span>
14+
) : (
15+
<span className='visually-hidden'>Next</span>
16+
)}
17+
</Tag>
18+
);
19+
}
20+
);
21+
22+
MDBCarouselControl.defaultProps = { tag: 'a' };
23+
24+
export default MDBCarouselControl;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
3+
declare const MDBCarouselControl: React.FunctionComponent<{
4+
className?: string;
5+
tag?: React.ComponentProps<any>;
6+
[rest: string]: any;
7+
}>;
8+
9+
export default MDBCarouselControl;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react';
2+
3+
type CarouselControlProps = {
4+
className?: string;
5+
tag?: React.ComponentProps<any>;
6+
[rest: string]: any;
7+
};
8+
9+
export { CarouselControlProps };
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import clsx from 'clsx';
2+
import React from 'react';
3+
import type { CarouselElementProps } from './types';
4+
5+
const MDBCarouselElement: React.FC<CarouselElementProps> = React.forwardRef<HTMLAllCollection, CarouselElementProps>(
6+
({ className, tag: Tag, children, ...props }, ref) => {
7+
const classes = clsx('d-block', 'w-100', className);
8+
9+
return <Tag className={classes} ref={ref} {...props} />;
10+
}
11+
);
12+
13+
MDBCarouselElement.defaultProps = { tag: 'img' };
14+
15+
export default MDBCarouselElement;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
3+
declare const MDBCarouselElement: React.FunctionComponent<{
4+
className?: string;
5+
tag?: React.ComponentProps<any>;
6+
[rest: string]: any;
7+
}>;
8+
9+
export default MDBCarouselElement;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react';
2+
3+
type CarouselElementProps = {
4+
className?: string;
5+
tag?: React.ComponentProps<any>;
6+
[rest: string]: any;
7+
};
8+
9+
export { CarouselElementProps };
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import clsx from 'clsx';
2+
import React from 'react';
3+
import type { CarouselIndicatorItemProps } from './types';
4+
5+
const MDBCarouselIndicatorItem: React.FC<CarouselIndicatorItemProps> = React.forwardRef<
6+
HTMLAllCollection,
7+
CarouselIndicatorItemProps
8+
>(({ active, className, tag: Tag, ...props }, ref) => {
9+
const classes = clsx(active && 'active', className);
10+
11+
return <Tag className={classes} ref={ref} {...props} />;
12+
});
13+
14+
MDBCarouselIndicatorItem.defaultProps = { tag: 'li' };
15+
16+
export default MDBCarouselIndicatorItem;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from 'react';
2+
3+
declare const MDBCarouselIndicatorItem: React.FunctionComponent<{
4+
className?: string;
5+
tag?: React.ComponentProps<any>;
6+
[rest: string]: any;
7+
}>;
8+
9+
export default MDBCarouselIndicatorItem;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react';
2+
3+
type CarouselIndicatorItemProps = {
4+
className?: string;
5+
active?: boolean;
6+
tag?: React.ComponentProps<any>;
7+
[rest: string]: any;
8+
};
9+
10+
export { CarouselIndicatorItemProps };

0 commit comments

Comments
 (0)