react-smooth-carousel-dots
Version:
Custom Carousel Dots component to plug in to any your Carousels.
204 lines (184 loc) • 6.27 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
import { useState, useEffect } from "react";
import usePrevious from "./use-previous";
var range = (start, end) => {
if (start === 0 && end === 0) return [0];
return Array(end - start + 1).fill().map((_, idx) => start + idx);
};
var defaultHolderStyle = {
display: "flex",
alignItems: "center",
overflow: "hidden",
transition: "all 0.5s ease"
};
var defaultDotsStyle = {
flexShrink: 0,
transition: "all 0.5s ease"
};
var defaultDotStyle = {
width: "100%",
height: "100%",
borderRadius: "50%",
backgroundColor: "rgba(255, 255, 255, 0.5)",
flexShrink: 0,
transition: "transform 0.5s ease, background 0.3s ease-in-out, opacity 0.3s ease-in-out"
};
var defaultActiveDotStyle = {
backgroundColor: "white"
};
var defaultVisibleDotStyle = {
opacity: 1
};
var defaultSmallDotStyle = {
transform: "scale(0.6667)"
};
var defaultMediumDotStyle = {
transform: "scale(0.8333)"
};
var defaultBigDotStyle = {
transform: "scale(1)"
};
var useCarouselDots = props => {
var {
total,
current,
size = 12,
margin = 3,
padding = 16,
visible = 3
} = props;
if (total == null) {
throw new Error("'total' cannot be null/undefined");
}
if (total <= 0) {
throw new Error("'total' cannot be less than or equal to 0");
}
if (visible < 3) {
throw new Error("'visible' cannot be less than 3");
}
var _visible = visible;
if (total <= 3) {
_visible = total;
}
if (_visible > 3 && _visible !== total && visible % 2 === 0) {
throw new Error("'visible' cannot be an even number");
}
if (_visible > total) {
throw new Error("'visible' cannot be more than 'total'");
}
var prevCurrent = usePrevious(current);
var dotFullWidth = size + margin * 2;
var center = Math.round(_visible / 2);
var centerIndex = Math.floor(_visible / 2);
var [translate, setTranslate] = useState(0);
var [visibleDots, setVisibleDots] = useState(range(0, _visible - 1));
var [mediumDots, setMediumDots] = useState(range(0, centerIndex + centerIndex - 1));
var [bigDots, setBigDots] = useState(range(0, centerIndex));
var [isLooping, setIsLooping] = useState(false);
useEffect(() => {
if (current < centerIndex) {
setTranslate(0);
setVisibleDots(range(0, _visible - 1));
} else if (total - center < current) {
setTranslate((total - _visible) * dotFullWidth);
setVisibleDots(range(total - _visible, total - 1));
} else {
setTranslate((current - centerIndex) * dotFullWidth);
setVisibleDots(range(current - centerIndex, current + centerIndex));
}
}, [current, center, centerIndex, dotFullWidth, total, _visible]);
useEffect(() => {
if (current < center) {
if (_visible === 3) {
setMediumDots(range(0, _visible));
} else {
setMediumDots(range(0, centerIndex + centerIndex - 1));
}
setBigDots(range(0, centerIndex));
} else if (total - center - 1 < current) {
if (_visible === 3) {
setMediumDots(range(total - _visible, total - 1));
} else {
setMediumDots(range(total - centerIndex - centerIndex, total - 1));
}
setBigDots(range(total - center, total - 1));
} else {
if (_visible === 3) {
setMediumDots(range(current - 1, current + 1));
setBigDots([current]);
} else {
setMediumDots(range(current - 2, current + 2));
setBigDots(range(current - 1, current + 1));
}
}
}, [current, center, centerIndex, total, _visible]);
useEffect(() => {
if (prevCurrent === 0 && current === total - 1 || prevCurrent === total - 1 && current === 0) {
setIsLooping(true);
setTimeout(() => setIsLooping(false), 300);
}
}, [current, prevCurrent, total]);
var getHolderStyle = {
height: size,
paddingLeft: padding,
paddingRight: padding,
width: _visible * dotFullWidth + padding * 2
};
var getDotsStyle = {
height: size,
width: size,
marginRight: margin,
marginLeft: margin,
transform: "translateX(-" + translate + "px)"
};
var getDotStyle = _objectSpread({
opacity: 0
}, isLooping && {
opacity: 1,
transform: "scale(1)"
});
if (total === visible || total <= 3) {
return {
defaultHolderStyle,
getHolderStyle,
dots: range(0, total - 1),
defaultDotsStyle,
getDotsStyle,
defaultDotStyle,
getDotStyle,
defaultVisibleDotStyle,
defaultActiveDotStyle,
defaultSmallDotStyle,
defaultMediumDotStyle,
defaultBigDotStyle,
isSmall: () => false,
isMedium: () => false,
isBig: () => true,
isActive: dot => current === dot,
isVisible: dot => visibleDots.includes(dot)
};
}
return {
defaultHolderStyle,
getHolderStyle,
dots: range(0, total - 1),
defaultDotsStyle,
getDotsStyle,
defaultDotStyle,
getDotStyle,
defaultVisibleDotStyle,
defaultActiveDotStyle,
defaultSmallDotStyle,
defaultMediumDotStyle,
defaultBigDotStyle,
isSmall: dot => !mediumDots.includes(dot),
isMedium: dot => mediumDots.includes(dot),
isBig: dot => bigDots.includes(dot),
isActive: dot => current === dot,
isVisible: dot => visibleDots.includes(dot)
};
};
export default useCarouselDots;
//# sourceMappingURL=use-carousel-dots.js.map