use-carousel-hook
Advanced tools
Comparing version 0.0.4 to 0.0.5
# Changelog | ||
## [0.0.5] | ||
- Fix issue width lastScrollableChild not being calculated correctly for vertical carousels | ||
- Return current from the hook | ||
- Return an array of indexes for the children shown within the slider view | ||
## [0.0.4] | ||
@@ -4,0 +10,0 @@ |
@@ -11,3 +11,3 @@ import React from 'react'; | ||
interface CarouselHook { | ||
ref: React.MutableRefObject<HTMLUListElement | HTMLDivElement | HTMLElement>; | ||
ref: React.MutableRefObject<HTMLElement>; | ||
previous: () => void; | ||
@@ -18,4 +18,6 @@ next: () => void; | ||
position: CarouselPosition; | ||
current: number; | ||
inView: number[]; | ||
} | ||
declare const useCarousel: (options?: Options | undefined) => CarouselHook; | ||
export default useCarousel; |
@@ -9,14 +9,50 @@ import { useState, useRef, useEffect, useReducer, useCallback } from 'react'; | ||
const [position, setPosition] = useState({ isAtStart: true, isAtEnd: false }); | ||
const [inView, setInView] = useState([0]); | ||
const updateMaxIndex = useCallback(() => { | ||
const el = ref.current; | ||
const children = [...el.children]; | ||
const lastScrollableChild = children.findIndex(child => child.offsetLeft >= el.scrollWidth - el.offsetWidth); | ||
const lastScrollableChild = children.findIndex(child => (options === null || options === void 0 ? void 0 : options.direction) === 'vertical' | ||
? child.offsetTop >= el.scrollHeight - el.offsetHeight | ||
: child.offsetLeft >= el.scrollWidth - el.offsetWidth); | ||
setMaxIndex(lastScrollableChild >= 0 ? lastScrollableChild : children.length - 1); | ||
}, [ref.current]); | ||
const updateInView = useCallback(() => { | ||
const carouselEl = ref.current; | ||
const childEls = [...carouselEl.children]; | ||
const currentChildEl = childEls[current]; | ||
const inView = [current]; | ||
const carouselBottom = currentChildEl.offsetTop + carouselEl.offsetHeight; | ||
const carouselRight = currentChildEl.offsetLeft + carouselEl.offsetWidth; | ||
// Find which elements are in view | ||
for (let index = current + 1; index < childEls.length; index++) { | ||
if ((options === null || options === void 0 ? void 0 : options.direction) === 'vertical') { | ||
if (childEls[index].offsetTop + childEls[index].offsetHeight <= carouselBottom) { | ||
inView.push(index); | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
else { | ||
if (childEls[index].offsetLeft + childEls[index].offsetWidth <= carouselRight) { | ||
inView.push(index); | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
} | ||
setInView(inView); | ||
}, [ref.current]); | ||
useEffect(() => { | ||
window.addEventListener('resize', updateMaxIndex); | ||
return () => window.removeEventListener('resize', updateMaxIndex); | ||
window.addEventListener('resize', updateInView); | ||
return () => { | ||
window.removeEventListener('resize', updateMaxIndex); | ||
window.removeEventListener('resize', updateInView); | ||
}; | ||
}, []); | ||
useEffect(() => { | ||
updateMaxIndex(); | ||
updateInView(); | ||
}, [ref.current]); | ||
@@ -26,2 +62,3 @@ useDidUpdateEffect(() => { | ||
const currentChildEl = carouselEl.children[current]; | ||
// Scroll to the element | ||
if ((options === null || options === void 0 ? void 0 : options.direction) === 'vertical') { | ||
@@ -39,2 +76,4 @@ carouselEl.scrollTo({ | ||
} | ||
updateInView(); | ||
// Update the carousel position | ||
setPosition({ | ||
@@ -57,4 +96,13 @@ isAtStart: current === 0, | ||
}; | ||
return { ref, previous, next, setCurrent, reset, position }; | ||
return { | ||
ref, | ||
previous, | ||
next, | ||
setCurrent, | ||
reset, | ||
position, | ||
current, | ||
inView | ||
}; | ||
}; | ||
export default useCarousel; |
{ | ||
"name": "use-carousel-hook", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "Adds functionality for carousels using React hooks", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -16,10 +16,12 @@ # useCarousel | ||
| Property | Type | Description | | ||
| ---------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | | ||
| ref | React.MutableRefObject\<HTMLUListElement \| HTMLDivElement \| HTMLElement> | Attach this ref to your carousel element that contains your cards/elements. | | ||
| previous | (amount: number = 1) => void; | Go to the previous element in the carousel. Can set amount to decrease by, default is 1. | | ||
| next | (amount: number = 1) => void; | Go to the next element in the carousel. Can set amount to increase by, default is 1. | | ||
| setCurrent | (current: number) => void; | Go to a specific element index in the carousel. | | ||
| reset | () => void; | Go to the beginning of the carousel. | | ||
| position | { isAtStart: boolean; isAtEnd: boolean } | Position of the carousel. Can be used to disable next/previous buttons if needed. | | ||
| Property | Type | Description | | ||
| ---------- | ---------------------------------------- | ---------------------------------------------------------------------------------------- | | ||
| ref | React.MutableRefObject\<HTMLElement> | Attach this ref to your carousel element that contains your cards/elements. | | ||
| previous | (amount: number = 1) => void; | Go to the previous element in the carousel. Can set amount to decrease by, default is 1. | | ||
| next | (amount: number = 1) => void; | Go to the next element in the carousel. Can set amount to increase by, default is 1. | | ||
| setCurrent | (current: number) => void; | Go to a specific element index in the carousel. | | ||
| reset | () => void; | Go to the beginning of the carousel. | | ||
| position | { isAtStart: boolean; isAtEnd: boolean } | Position of the carousel. Can be used to disable next/previous buttons if needed. | | ||
| current | number; | The index of the current item. | | ||
| inView | number[]; | The indexes of the items in view. | | ||
@@ -43,4 +45,4 @@ ### Code example | ||
<button onClick={() => setCurrent(2)}>Set index to 2</button> | ||
/* ref accepts HTMLUListElement (recommended), HTMLDivElement and generic HTMLElement types (you will need to cast to the correct type) */ | ||
<ul ref={ref}> | ||
/* ref will need to be cast to the correct type if using TypeScript */ | ||
<ul ref={ref as React.RefObject<HTMLUListElement>}> | ||
<li>Item 1</li> | ||
@@ -51,3 +53,3 @@ <li>Item 2</li> | ||
</ul> | ||
<div ref={ref}> | ||
<div ref={ref as React.RefObject<HTMLDivElement>}> | ||
<div>Item 1</div> | ||
@@ -58,3 +60,3 @@ <div>Item 2</div> | ||
</div> | ||
<span ref={ref as React.MutableRefObject<HTMLSpanElement>}> | ||
<span ref={ref as React.RefObject<HTMLSpanElement>}> | ||
<div>Item 1</div> | ||
@@ -61,0 +63,0 @@ <div>Item 2</div> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
12760
165
82