Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions __tests__/__snapshots__/index.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ exports[`Accordion should render properly with default props 1`] = `
>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -42,6 +43,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -69,6 +71,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -96,6 +99,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -123,6 +127,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -150,6 +155,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -177,6 +183,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -204,6 +211,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -231,6 +239,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -258,6 +267,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -285,6 +295,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -312,6 +323,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -339,6 +351,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -366,6 +379,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -393,6 +407,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -420,6 +435,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -447,6 +463,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -474,6 +491,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -501,6 +519,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down Expand Up @@ -528,6 +547,7 @@ exports[`Accordion should render properly with default props 1`] = `
</div>
<div
className="carousel__slide"
onClick={[Function]}
style={
{
"opacity": 1,
Expand Down
34 changes: 19 additions & 15 deletions demo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,28 @@ import { createRoot } from 'react-dom/client';

import 'scriptex-socials';

import { Carousel, CarouselRef } from '../dist/index';
import { items } from './mocks';
import { Carousel } from '../dist/index';

const App = () => (
<>
<a
href="https://github.com/scriptex/react-round-carousel"
title="See code on Github"
className="github-fork-ribbon"
data-ribbon="See code on Github"
>
See code on Github
</a>
const App = () => {
const ref = React.createRef<CarouselRef>();

<Carousel items={items} />
return (
<>
<a
href="https://github.com/scriptex/react-round-carousel"
title="See code on Github"
className="github-fork-ribbon"
data-ribbon="See code on Github"
>
See code on Github
</a>

<social-links></social-links>
</>
);
<Carousel items={items} ref={ref} />

<social-links></social-links>
</>
);
};

createRoot(document.getElementById('root')!).render(<App />);
41 changes: 36 additions & 5 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type CarouselItem = {
readonly alt?: string;
readonly content: React.ReactNode;
readonly image: string;
readonly click?: () => void;
Comment thread
scriptex marked this conversation as resolved.
Outdated
};

export type CarouselProps = {
Expand All @@ -14,9 +15,19 @@ export type CarouselProps = {
readonly nextButtonContent?: string | React.ReactNode;
readonly prevButtonContent?: string | React.ReactNode;
readonly showControls?: boolean;
readonly slideOnClick?: boolean;
readonly ref?: React.ForwardedRef<CarouselRef>;
};

export const Carousel: React.FC<CarouselProps> = (props: CarouselProps) => {
export type CarouselRef = {
readonly next: () => void;
readonly prev: () => void;
getItems: () => CarouselItem[];
Comment thread
scriptex marked this conversation as resolved.
getSelectedIndex: () => number;
setSelectedIndex: (index: number) => void;
};

export const Carousel: React.FC<CarouselProps> = React.forwardRef((props: CarouselProps, CarouselRef) => {
const itemWidth = props.itemWidth;
const len = props.items.length;
const radius = Math.round((itemWidth || 210) / 2 / Math.tan(Math.PI / len));
Expand All @@ -28,7 +39,7 @@ export const Carousel: React.FC<CarouselProps> = (props: CarouselProps) => {
const getSlideStyle = (index: number): React.CSSProperties => {
const style: React.CSSProperties = {};

if (index < len) {
if (index <= len) {
Comment thread
scriptex marked this conversation as resolved.
Outdated
const cellAngle = theta * index;

style.opacity = 1;
Expand Down Expand Up @@ -72,12 +83,31 @@ export const Carousel: React.FC<CarouselProps> = (props: CarouselProps) => {
};
});

React.useImperativeHandle(CarouselRef, (): CarouselRef => {
return {
next,
prev,
getItems: () => props.items,
getSelectedIndex: () => selectedIndex,
setSelectedIndex: (index: number) => setSelectedIndex(index)
};
});

return (
<>
<div className={getClassName('')} ref={ref}>
<div className={getClassName('__container')} style={getItemStyle()}>
{props.items.map((item: CarouselItem, index: number) => (
<div className={getClassName('__slide')} key={index} style={getSlideStyle(index)}>
<div
onClick={() => {
if (item.click) item.click();

if (props.slideOnClick) setSelectedIndex(index);
}}
className={getClassName('__slide')}
key={index}
style={getSlideStyle(index)}
>
<img src={item.image} alt={item.alt} />

<div className={getClassName('__slide-overlay')}>{item.content}</div>
Expand All @@ -99,14 +129,15 @@ export const Carousel: React.FC<CarouselProps> = (props: CarouselProps) => {
)}
</>
);
};
});

Carousel.defaultProps = {
itemWidth: 210,
showControls: true,
classNamePrefix: 'carousel',
prevButtonContent: 'Previous',
nextButtonContent: 'Next'
nextButtonContent: 'Next',
slideOnClick: false
};

export default Carousel;