@won-ui/hooks
Version:
hooks for @won-ui/core
135 lines (132 loc) • 4.34 kB
JavaScript
// src/useClickOutside/useClickOutside.ts
import { useEffect } from "react";
var EVENT_KEYS = ["touchstart", "mousedown"];
function useClickOutside(ref, eventHandler, eventKeys = EVENT_KEYS) {
useEffect(() => {
const eventListner = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
eventHandler(event);
}
};
eventKeys.forEach((key) => document.addEventListener(key, eventListner));
return () => {
eventKeys.forEach((key) => document.removeEventListener(key, eventListner));
};
}, [ref, eventHandler]);
}
// src/usePagination/usePagination.ts
import { useCallback, useMemo, useState } from "react";
function usePagination({
defaultPage = 1,
currentPage: propsCurrentPage,
onChange,
pageSizeOptions = [10, 20, 30, 50, 100],
defaultPageSize = pageSizeOptions[0],
pagesGap = 2,
total,
hasMoreButton = false
}) {
const [current, setCurrent] = useState(defaultPage);
const [pageSize, setPageSize] = useState(defaultPageSize);
const maxPageNum = useMemo(() => Math.ceil(total / pageSize), [total, pageSize]);
const additionalPages = useMemo(() => hasMoreButton ? 2 : 0, [hasMoreButton]);
const page = useMemo(
() => propsCurrentPage === void 0 ? current : propsCurrentPage,
[propsCurrentPage, current]
);
const currentPages = useMemo(() => {
const isLimitedPages = maxPageNum <= pagesGap * 2 + 1;
let pagesLength = isLimitedPages ? maxPageNum : pagesGap * 2 + 1;
let startNum = page - pagesGap - additionalPages;
if (pagesLength !== maxPageNum && hasMoreButton) {
pagesLength = pagesLength + additionalPages * 2;
}
const minStartNum = pagesGap + additionalPages + 1;
const maxCenterNum = maxPageNum - pagesGap - additionalPages;
if (!isLimitedPages && page > maxCenterNum) {
startNum = maxCenterNum - pagesGap - additionalPages;
}
if (isLimitedPages || page <= minStartNum) {
startNum = 1;
}
const pages = Array.from({ length: pagesLength }, (_, i) => {
let updatePage = i + startNum;
if (hasMoreButton && i <= 1 && startNum > 1) {
updatePage = i === 0 ? 1 : "left";
}
if (hasMoreButton && i >= pagesLength - 2 && maxPageNum >= pagesLength + startNum) {
updatePage = i === pagesLength - 1 ? maxPageNum : "right";
}
return {
selected: page === updatePage,
page: updatePage
};
});
return pages;
}, [current, total, pageSize, pagesGap, propsCurrentPage, page]);
const handleCurrent = useCallback(
(updatePage, updatePageSize = pageSize) => {
let changePage = updatePage;
if (updatePageSize !== pageSize) {
const changeMaxPageNum = Math.ceil(total / updatePageSize);
if (updatePage > changeMaxPageNum)
changePage = changeMaxPageNum;
setPageSize(updatePageSize);
}
if (changePage !== page)
setCurrent(changePage);
if (onChange) {
onChange(updatePage, updatePageSize);
}
},
[onChange, pageSize, page]
);
const handleChangePage = (clickedPage) => (e) => {
handleCurrent(clickedPage);
};
const handleChangePageSize = (e) => {
const changePageSize = Number(e.target.value);
handleCurrent(page, changePageSize);
};
const handleClickPrev = (e) => {
if (page <= 1)
return;
handleCurrent(page - 1);
};
const handleClickNext = (e) => {
if (page === maxPageNum)
return;
handleCurrent(page + 1);
};
const handleClickMoreButton = (position) => (e) => {
let updatePage = page + pagesGap * 2 + 1 >= Math.ceil(total / pageSize) ? Math.ceil(total / pageSize) : page + pagesGap * 2 + 1;
if (position === "left") {
updatePage = page - (pagesGap * 2 + 1) <= 1 ? 1 : page - (pagesGap * 2 + 1);
}
handleCurrent(updatePage);
};
return {
page,
maxPageNum,
additionalPages,
currentPages,
pageSize,
pageSizeOptions,
handleChangePage,
handleChangePageSize,
handleClickNext,
handleClickPrev,
handleClickMoreButton
};
}
// src/useUniqueId/useUniqueId.ts
import { useRef } from "react";
var useUniqueId = (id) => {
const uniqueId = useRef(`won-ui-${Math.random().toString(36).slice(2)}`);
return id || uniqueId.current;
};
export {
useClickOutside,
usePagination,
useUniqueId
};