Skip to content

Commit

Permalink
1.0.0-beta3
Browse files Browse the repository at this point in the history
  • Loading branch information
unknown committed Aug 31, 2021
1 parent 1792e24 commit 56f084c
Show file tree
Hide file tree
Showing 34 changed files with 619 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MDB 5 React

Version: FREE 1.0.0-beta2
Version: FREE 1.0.0-beta3

Documentation:
https://mdbootstrap.com/docs/b5/react/
Expand Down
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mdb-react-ui-kit-demo",
"version": "1.0.0-beta2",
"version": "1.0.0-beta3",
"main": "index.js",
"repository": {
"type": "git",
Expand Down
1 change: 1 addition & 0 deletions app/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

<link rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />

<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Expand Down
193 changes: 193 additions & 0 deletions app/src/components/Carousel/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import clsx from 'clsx';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import type { CarouselProps } from './types';
import MDBCarouselControl from './CarouselControl/CarouselControl';
import MDBCarouselIndicatorItem from './CarouselIndicatorItem/CarouselIndicatorItem';
import { CarouselContext } from './CarouselContext';
const MDBCarousel: React.FC<CarouselProps> = ({
fade,
className,
dark,
children,
carouselRef,
interval,
keyboard,
pause,
touch,
tag: Tag,
showControls,
showIndicators,
...props
}) => {
const [isChanging, setIsChanging] = useState(false);
const [imagesCount, setImagesCount] = useState(0);
const [activeItem, setActiveItem] = useState(0);
const [prevState, setPrevState] = useState(0);
const [startInterval, setStartInterval] = useState(true);
const [clientTouch, setClientTouch] = useState({ initialX: 0, initialY: 0 });

const carouselInnerRef = useRef<HTMLElement>(null);
const carouselReference = carouselRef ? carouselRef : carouselInnerRef;

const classes = clsx('carousel', 'slide', fade && 'carousel-fade', dark && 'carousel-dark', className);

const setPrev = useCallback(() => {
const prevIndex = activeItem === 0 ? imagesCount : activeItem - 1;

setActiveItem(prevIndex);
}, [activeItem, imagesCount]);

const setNext = useCallback(() => {
const nextIndex = activeItem === imagesCount ? 0 : activeItem + 1;

setActiveItem(nextIndex);
}, [activeItem, imagesCount]);

const handleKeydown = useCallback(
(event: KeyboardEvent) => {
console.log(event.key);
switch (event.key) {
case 'ArrowLeft':
event.preventDefault();
setPrev();
break;

case 'ArrowRight':
event.preventDefault();
setNext();
break;

default:
}
},
[setPrev, setNext]
);

const handleControlClick = (isNext: boolean) => {
if (!isChanging && !isNext) {
setPrev();
setIsChanging(true);

setTimeout(() => {
setIsChanging(false);
}, 700);
} else if (!isChanging && isNext) {
setNext();
setIsChanging(true);

setTimeout(() => {
setIsChanging(false);
}, 700);
} else {
return;
}
};

const handleIndicatorClick = (i: number) => {
if (!isChanging) {
setActiveItem(i);
setIsChanging(true);

setTimeout(() => {
setIsChanging(false);
}, 700);
}
};

useEffect(() => {
if (keyboard) {
document.addEventListener('keydown', handleKeydown);

return () => {
document.removeEventListener('keydown', handleKeydown);
};
}
}, [handleKeydown, keyboard]);

useEffect(() => {
if (interval && startInterval) {
const cycleInterval = setInterval(setNext, interval);

return () => {
clearInterval(cycleInterval);
};
}
}, [interval, setNext, startInterval]);

useEffect(() => {
const carouselImgList = carouselReference.current.querySelectorAll('.carousel-item-react img');

setImagesCount(carouselImgList.length - 1);
}, [carouselReference, showIndicators]);

const startTouch = (e: TouchEvent) => {
touch && setClientTouch({ initialX: e.touches[0].clientX, initialY: e.touches[0].clientY });
};

const moveTouch = (e: TouchEvent) => {
setIsChanging(true);

const { initialX, initialY } = clientTouch;

if (!initialX || !initialY) {
return;
}

const currentX = e.touches[0].clientX;
const currentY = e.touches[0].clientY;

const diffX = initialX - currentX;
const diffY = initialY - currentY;

if (Math.abs(diffX) > Math.abs(diffY)) {
// sliding horizontally
if (diffX > 0) {
setNext();
} else {
setPrev();
}
}

setClientTouch({ initialX: 0, initialY: 0 });
};

return (
<CarouselContext.Provider
value={{
activeItem: activeItem ? activeItem : 0,
imagesCount: imagesCount,
fade: fade ? true : false,
prev: prevState,
setPrev: setPrevState,
}}
>
<Tag
onTouchStart={startTouch}
onTouchMove={!isChanging ? moveTouch : null}
onTouchEnd={() => setIsChanging(false)}
onMouseEnter={pause ? () => setStartInterval(false) : null}
onMouseLeave={pause ? () => setStartInterval(true) : null}
className={classes}
ref={carouselReference}
{...props}
>
{showIndicators && (
<ol className='carousel-indicators'>
{Array.from(Array(imagesCount + 1)).map((item, i) => (
<MDBCarouselIndicatorItem key={i} active={activeItem === i} onClick={() => handleIndicatorClick(i)} />
))}
</ol>
)}
{children}
{showControls && (
<>
<MDBCarouselControl direction='prev' onClick={() => handleControlClick(false)} />
<MDBCarouselControl direction='next' onClick={() => handleControlClick(true)} />
</>
)}
</Tag>
</CarouselContext.Provider>
);
};
MDBCarousel.defaultProps = { tag: 'div', interval: 5000, fade: false, pause: true, touch: true, keyboard: false };
export default MDBCarousel;
19 changes: 19 additions & 0 deletions app/src/components/Carousel/CarouselCaption/CarouselCaption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import clsx from 'clsx';
import React from 'react';
import type { CarouselCaptionProps } from './types';

const MDBCarouselCaption: React.FC<CarouselCaptionProps> = React.forwardRef<HTMLAllCollection, CarouselCaptionProps>(
({ className, tag: Tag, children, ...props }, ref) => {
const classes = clsx('carousel-caption', 'd-none', 'd-md-block', className);

return (
<Tag className={classes} ref={ref} {...props}>
{children}
</Tag>
);
}
);

MDBCarouselCaption.defaultProps = { tag: 'div' };

export default MDBCarouselCaption;
9 changes: 9 additions & 0 deletions app/src/components/Carousel/CarouselCaption/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react';

declare const MDBCarouselCaption: React.FunctionComponent<{
className?: string;
tag?: React.ComponentProps<any>;
[rest: string]: any;
}>;

export default MDBCarouselCaption;
9 changes: 9 additions & 0 deletions app/src/components/Carousel/CarouselCaption/types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';

type CarouselCaptionProps = {
className?: string;
tag?: React.ComponentProps<any>;
[rest: string]: any;
};

export { CarouselCaptionProps };
19 changes: 19 additions & 0 deletions app/src/components/Carousel/CarouselContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';

interface CarouselProps {
activeItem: number;
imagesCount: number;
fade: boolean;
prev: number;
setPrev: React.SetStateAction<any>;
}

const CarouselContext = React.createContext<CarouselProps>({
activeItem: 0,
imagesCount: 0,
fade: false,
prev: 0,
setPrev: null,
});

export { CarouselContext };
24 changes: 24 additions & 0 deletions app/src/components/Carousel/CarouselControl/CarouselControl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import clsx from 'clsx';
import React from 'react';
import type { CarouselControlProps } from './types';

const MDBCarouselControl: React.FC<CarouselControlProps> = React.forwardRef<HTMLAllCollection, CarouselControlProps>(
({ className, direction, tag: Tag, ...props }, ref) => {
const classes = clsx(`carousel-control-${direction}`, className);

return (
<Tag role='button' className={classes} ref={ref} {...props}>
<span className={`carousel-control-${direction}-icon`}></span>
{direction === 'prev' ? (
<span className='visually-hidden'>Previous</span>
) : (
<span className='visually-hidden'>Next</span>
)}
</Tag>
);
}
);

MDBCarouselControl.defaultProps = { tag: 'a' };

export default MDBCarouselControl;
9 changes: 9 additions & 0 deletions app/src/components/Carousel/CarouselControl/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react';

declare const MDBCarouselControl: React.FunctionComponent<{
className?: string;
tag?: React.ComponentProps<any>;
[rest: string]: any;
}>;

export default MDBCarouselControl;
9 changes: 9 additions & 0 deletions app/src/components/Carousel/CarouselControl/types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';

type CarouselControlProps = {
className?: string;
tag?: React.ComponentProps<any>;
[rest: string]: any;
};

export { CarouselControlProps };
15 changes: 15 additions & 0 deletions app/src/components/Carousel/CarouselElement/CarouselElement.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import clsx from 'clsx';
import React from 'react';
import type { CarouselElementProps } from './types';

const MDBCarouselElement: React.FC<CarouselElementProps> = React.forwardRef<HTMLAllCollection, CarouselElementProps>(
({ className, tag: Tag, children, ...props }, ref) => {
const classes = clsx('d-block', 'w-100', className);

return <Tag className={classes} ref={ref} {...props} />;
}
);

MDBCarouselElement.defaultProps = { tag: 'img' };

export default MDBCarouselElement;
9 changes: 9 additions & 0 deletions app/src/components/Carousel/CarouselElement/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react';

declare const MDBCarouselElement: React.FunctionComponent<{
className?: string;
tag?: React.ComponentProps<any>;
[rest: string]: any;
}>;

export default MDBCarouselElement;
9 changes: 9 additions & 0 deletions app/src/components/Carousel/CarouselElement/types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';

type CarouselElementProps = {
className?: string;
tag?: React.ComponentProps<any>;
[rest: string]: any;
};

export { CarouselElementProps };
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import clsx from 'clsx';
import React from 'react';
import type { CarouselIndicatorItemProps } from './types';

const MDBCarouselIndicatorItem: React.FC<CarouselIndicatorItemProps> = React.forwardRef<
HTMLAllCollection,
CarouselIndicatorItemProps
>(({ active, className, tag: Tag, ...props }, ref) => {
const classes = clsx(active && 'active', className);

return <Tag className={classes} ref={ref} {...props} />;
});

MDBCarouselIndicatorItem.defaultProps = { tag: 'li' };

export default MDBCarouselIndicatorItem;
9 changes: 9 additions & 0 deletions app/src/components/Carousel/CarouselIndicatorItem/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react';

declare const MDBCarouselIndicatorItem: React.FunctionComponent<{
className?: string;
tag?: React.ComponentProps<any>;
[rest: string]: any;
}>;

export default MDBCarouselIndicatorItem;
10 changes: 10 additions & 0 deletions app/src/components/Carousel/CarouselIndicatorItem/types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';

type CarouselIndicatorItemProps = {
className?: string;
active?: boolean;
tag?: React.ComponentProps<any>;
[rest: string]: any;
};

export { CarouselIndicatorItemProps };
Loading

0 comments on commit 56f084c

Please sign in to comment.