{"version":3,"file":"use-pagination.mjs","names":[],"sources":["../../src/use-pagination/use-pagination.ts"],"sourcesContent":["import { useCallback, useMemo } from 'react';\nimport { useUncontrolled } from '../use-uncontrolled/use-uncontrolled';\n\nfunction range(start: number, end: number) {\n  const length = end - start + 1;\n  return Array.from({ length }, (_, index) => index + start);\n}\n\nexport const DOTS = 'dots';\n\nexport interface UsePaginationOptions {\n  /** Page selected on initial render, defaults to 1 or startValue if provided */\n  initialPage?: number;\n\n  /** Controlled active page number */\n  page?: number;\n\n  /** Total amount of pages */\n  total: number;\n\n  /** Siblings amount on left/right side of selected page, defaults to 1 */\n  siblings?: number;\n\n  /** Amount of elements visible on left/right edges, defaults to 1  */\n  boundaries?: number;\n\n  /** Callback fired after change of each page */\n  onChange?: (page: number) => void;\n\n  /** Starting page number, defaults to 1 */\n  startValue?: number;\n}\n\nexport interface UsePaginationReturnValue {\n  /** Array of page numbers and dots */\n  range: (number | 'dots')[];\n\n  /** Active page number */\n  active: number;\n\n  /** Function to set active page */\n  setPage: (page: number) => void;\n\n  /** Function to go to next page */\n  next: () => void;\n\n  /** Function to go to previous page */\n  previous: () => void;\n\n  /** Function to go to first page */\n  first: () => void;\n\n  /** Function to go to last page */\n  last: () => void;\n}\n\nexport function usePagination({\n  total,\n  siblings = 1,\n  boundaries = 1,\n  page,\n  initialPage,\n  onChange,\n  startValue = 1,\n}: UsePaginationOptions): UsePaginationReturnValue {\n  const _startValue = Math.max(Math.trunc(startValue), 1);\n  const _endValue = Math.max(Math.trunc(total), _startValue);\n  const _total = _endValue - _startValue + 1;\n  const _initialPage = initialPage ?? _startValue;\n\n  const [activePage, setActivePage] = useUncontrolled({\n    value: page,\n    onChange,\n    defaultValue: _initialPage,\n    finalValue: _initialPage,\n  });\n\n  const setPage = useCallback(\n    (pageNumber: number) => {\n      if (pageNumber < _startValue) {\n        setActivePage(_startValue);\n      } else if (pageNumber > _endValue) {\n        setActivePage(_endValue);\n      } else {\n        setActivePage(pageNumber);\n      }\n    },\n    [_startValue, _endValue, setActivePage]\n  );\n\n  const next = useCallback(() => setPage(activePage + 1), [activePage, setPage]);\n  const previous = useCallback(() => setPage(activePage - 1), [activePage, setPage]);\n  const first = useCallback(() => setPage(_startValue), [setPage, _startValue]);\n  const last = useCallback(() => setPage(_endValue), [_endValue, setPage]);\n\n  const paginationRange = useMemo((): (number | 'dots')[] => {\n    const totalPageNumbers = siblings * 2 + 3 + boundaries * 2;\n    if (totalPageNumbers >= _total) {\n      return range(_startValue, _endValue);\n    }\n\n    const leftSiblingIndex = Math.max(activePage - siblings, _startValue + boundaries - 1);\n    const rightSiblingIndex = Math.min(activePage + siblings, _endValue - boundaries);\n\n    const shouldShowLeftDots = leftSiblingIndex > _startValue + boundaries + 1;\n    const shouldShowRightDots = rightSiblingIndex < _endValue - boundaries;\n\n    if (!shouldShowLeftDots && shouldShowRightDots) {\n      const leftItemCount = siblings * 2 + boundaries + 2;\n      return [\n        ...range(_startValue, _startValue + leftItemCount - 1),\n        DOTS,\n        ...range(_endValue - (boundaries - 1), _endValue),\n      ];\n    }\n\n    if (shouldShowLeftDots && !shouldShowRightDots) {\n      const rightItemCount = boundaries + 1 + 2 * siblings;\n      return [\n        ...range(_startValue, _startValue + boundaries - 1),\n        DOTS,\n        ...range(_endValue - rightItemCount, _endValue),\n      ];\n    }\n\n    return [\n      ...range(_startValue, _startValue + boundaries - 1),\n      DOTS,\n      ...range(leftSiblingIndex, rightSiblingIndex),\n      DOTS,\n      ...range(_endValue - boundaries + 1, _endValue),\n    ];\n  }, [_total, siblings, activePage, _startValue, _endValue, boundaries]);\n\n  return {\n    range: paginationRange,\n    active: activePage,\n    setPage,\n    next,\n    previous,\n    first,\n    last,\n  };\n}\n\nexport namespace usePagination {\n  export type Options = UsePaginationOptions;\n  export type ReturnValue = UsePaginationReturnValue;\n}\n"],"mappings":";;;;AAGA,SAAS,MAAM,OAAe,KAAa;CACzC,MAAM,SAAS,MAAM,QAAQ;CAC7B,OAAO,MAAM,KAAK,EAAE,OAAO,IAAI,GAAG,UAAU,QAAQ,KAAK;AAC3D;AAEA,MAAa,OAAO;AAgDpB,SAAgB,cAAc,EAC5B,OACA,WAAW,GACX,aAAa,GACb,MACA,aACA,UACA,aAAa,KACoC;CACjD,MAAM,cAAc,KAAK,IAAI,KAAK,MAAM,UAAU,GAAG,CAAC;CACtD,MAAM,YAAY,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,WAAW;CACzD,MAAM,SAAS,YAAY,cAAc;CACzC,MAAM,eAAe,eAAe;CAEpC,MAAM,CAAC,YAAY,iBAAiB,gBAAgB;EAClD,OAAO;EACP;EACA,cAAc;EACd,YAAY;CACd,CAAC;CAED,MAAM,UAAU,aACb,eAAuB;EACtB,IAAI,aAAa,aACf,cAAc,WAAW;OACpB,IAAI,aAAa,WACtB,cAAc,SAAS;OAEvB,cAAc,UAAU;CAE5B,GACA;EAAC;EAAa;EAAW;CAAa,CACxC;CAEA,MAAM,OAAO,kBAAkB,QAAQ,aAAa,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC;CAC7E,MAAM,WAAW,kBAAkB,QAAQ,aAAa,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC;CACjF,MAAM,QAAQ,kBAAkB,QAAQ,WAAW,GAAG,CAAC,SAAS,WAAW,CAAC;CAC5E,MAAM,OAAO,kBAAkB,QAAQ,SAAS,GAAG,CAAC,WAAW,OAAO,CAAC;CAyCvE,OAAO;EACL,OAxCsB,cAAmC;GAEzD,IADyB,WAAW,IAAI,IAAI,aAAa,KACjC,QACtB,OAAO,MAAM,aAAa,SAAS;GAGrC,MAAM,mBAAmB,KAAK,IAAI,aAAa,UAAU,cAAc,aAAa,CAAC;GACrF,MAAM,oBAAoB,KAAK,IAAI,aAAa,UAAU,YAAY,UAAU;GAEhF,MAAM,qBAAqB,mBAAmB,cAAc,aAAa;GACzE,MAAM,sBAAsB,oBAAoB,YAAY;GAE5D,IAAI,CAAC,sBAAsB,qBAEzB,OAAO;IACL,GAAG,MAAM,aAAa,eAFF,WAAW,IAAI,aAAa,KAEI,CAAC;IACrD;IACA,GAAG,MAAM,aAAa,aAAa,IAAI,SAAS;GAClD;GAGF,IAAI,sBAAsB,CAAC,qBAAqB;IAC9C,MAAM,iBAAiB,aAAa,IAAI,IAAI;IAC5C,OAAO;KACL,GAAG,MAAM,aAAa,cAAc,aAAa,CAAC;KAClD;KACA,GAAG,MAAM,YAAY,gBAAgB,SAAS;IAChD;GACF;GAEA,OAAO;IACL,GAAG,MAAM,aAAa,cAAc,aAAa,CAAC;IAClD;IACA,GAAG,MAAM,kBAAkB,iBAAiB;IAC5C;IACA,GAAG,MAAM,YAAY,aAAa,GAAG,SAAS;GAChD;EACF,GAAG;GAAC;GAAQ;GAAU;GAAY;GAAa;GAAW;EAAU,CAG7C;EACrB,QAAQ;EACR;EACA;EACA;EACA;EACA;CACF;AACF"}