A comprehensive collection of 75+ React hooks for state and UI management including storage, events, browser APIs, and performance optimizations
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Navigation helpers and scroll management including pagination logic, smooth scrolling, scroll spy functionality, and headroom patterns.
Pagination logic with range calculation and navigation controls.
/**
* Pagination logic with range calculation
* @param options - Pagination configuration
* @returns Object with pagination state and controls
*/
function usePagination(options: UsePaginationOptions): UsePaginationReturnValue;
const DOTS = 'dots';
interface UsePaginationOptions {
initialPage?: number;
page?: number;
total: number;
siblings?: number;
boundaries?: number;
onChange?: (page: number) => void;
}
interface UsePaginationReturnValue {
range: (number | 'dots')[];
active: number;
setPage: (page: number) => void;
next: () => void;
previous: () => void;
first: () => void;
last: () => void;
}Usage Examples:
import { usePagination } from "@mantine/hooks";
function DataTable({ totalItems }: { totalItems: number }) {
const [currentPage, setCurrentPage] = useState(1);
const itemsPerPage = 10;
const totalPages = Math.ceil(totalItems / itemsPerPage);
const pagination = usePagination({
total: totalPages,
page: currentPage,
onChange: setCurrentPage,
siblings: 1,
boundaries: 1,
});
return (
<div>
<div>{/* Table content */}</div>
<div>
<button onClick={pagination.first} disabled={pagination.active === 1}>
First
</button>
<button onClick={pagination.previous} disabled={pagination.active === 1}>
Previous
</button>
{pagination.range.map((page, index) => (
<button
key={index}
onClick={() => typeof page === 'number' && pagination.setPage(page)}
disabled={page === 'dots'}
className={page === pagination.active ? 'active' : ''}
>
{page === 'dots' ? '...' : page}
</button>
))}
<button onClick={pagination.next} disabled={pagination.active === totalPages}>
Next
</button>
<button onClick={pagination.last} disabled={pagination.active === totalPages}>
Last
</button>
</div>
</div>
);
}Smooth scroll into view with animation and cancellation support.
/**
* Smooth scroll into view with animation
* @param options - Scroll configuration
* @returns Object with refs and scroll controls
*/
function useScrollIntoView<T extends HTMLElement = any>(
options?: UseScrollIntoViewOptions
): UseScrollIntoViewReturnValue<T>;
interface UseScrollIntoViewOptions {
duration?: number;
axis?: 'x' | 'y';
easing?: (t: number) => number;
offset?: number;
cancelable?: boolean;
isList?: boolean;
onScrollFinish?: () => void;
}
interface UseScrollIntoViewReturnValue<T extends HTMLElement = any> {
scrollableRef: React.RefCallback<T | null>;
targetRef: React.RefCallback<HTMLElement | null>;
scrollIntoView: (alignment?: ScrollLogicalPosition) => void;
cancel: () => void;
}Usage Examples:
import { useScrollIntoView } from "@mantine/hooks";
function ScrollableList({ items, activeId }: Props) {
const { scrollableRef, targetRef, scrollIntoView } = useScrollIntoView<HTMLDivElement>({
duration: 500,
offset: 60,
onScrollFinish: () => console.log('Scrolled to target'),
});
useEffect(() => {
if (activeId) {
scrollIntoView({ block: 'center' });
}
}, [activeId, scrollIntoView]);
return (
<div ref={scrollableRef} style={{ height: '400px', overflow: 'auto' }}>
{items.map(item => (
<div
key={item.id}
ref={item.id === activeId ? targetRef : undefined}
className={item.id === activeId ? 'active' : ''}
>
{item.title}
</div>
))}
</div>
);
}Track active section during scroll for table of contents navigation.
/**
* Track active section during scroll
* @param selectors - Array of CSS selectors to track
* @param options - Scroll spy configuration
* @returns Tuple with root ref, active index, and heading data
*/
function useScrollSpy<T extends HTMLElement = any>(
selectors: string[],
options?: UseScrollSpyOptions<T>
): UseScrollSpyReturnType;
interface UseScrollSpyOptions<T extends HTMLElement = any> {
root?: T;
rootMargin?: string;
threshold?: number | number[];
}
interface UseScrollSpyHeadingData {
id: string;
level: number;
element: HTMLElement;
}
type UseScrollSpyReturnType = [
React.RefCallback<HTMLElement | null>, // rootRef
number, // activeIndex
UseScrollSpyHeadingData[] // headings
];Hide/show header based on scroll direction for better UX.
/**
* Hide/show header based on scroll direction
* @param options - Headroom configuration
* @returns Boolean indicating if header should be pinned
*/
function useHeadroom(options?: UseHeadroomOptions): boolean;
interface UseHeadroomOptions {
fixedAt?: number;
onPin?: () => void;
onRelease?: () => void;
}Usage Examples:
import { useHeadroom } from "@mantine/hooks";
function Header() {
const pinned = useHeadroom({ fixedAt: 120 });
return (
<header
style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
transform: pinned ? 'translateY(0)' : 'translateY(-100%)',
transition: 'transform 0.3s ease',
zIndex: 1000,
}}
>
<nav>Navigation content</nav>
</header>
);
}