UNPKG

@won-ui/hooks

Version:
135 lines (132 loc) 4.34 kB
// 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 };