import { map } from "@thi.ng/transducers/map" ; import { range } from "@thi.ng/transducers/range" ; /**
 * Configuration options for pager components.
 */ export interface PagerOpts { /**
     * Function producing a single page nav or counter element. MUST be
     * provided by user.
     *
     * The function is called with:
     *
     * - target page ID
     * - current page ID
     * - max pageID
     * - page label (page number or sourced from these options here)
     * - disabled flag as determined by the pager
     *
     * If `disabled` is true, the function should return a version of
     * the button component reflecting this state to the user. E.g. the
     * "prev page" buttons should be disabled if the first page is
     * currently active. Likewise, the currently selected page button
     * will be set to disabled as well.
     *
     * Page IDs are zero-based indices, whereas page number labels are
     * one-based. The currently active page ID is only provided for
     * special highlighting cases (optional).
     */ button ( page , curr , max , label , disabled ) : any ; /**
     * Pager root component function. Receives all 3 button groups as
     * arguments. Optional. Default: `["div.pager", ...body]`
     */ root ( ctx , ... body ) : any ; /**
     * Component function to provide wrapper for the first / prev nav
     * button group. The `first` / `prev` args are button components.
     * Optional. Default: `["div.pager-prev", first, prev]`
     */ groupPrev ( ctx , first , prev ) : any ; /**
     * Component function to provide wrapper for the page buttons group.
     * The `buttons` argument is an array of button components.
     * Optional. Default: `["div.pager-pages", ...buttons]`
     */ groupPages ( ctx , buttons ) : any ; /**
     * Component function to provide wrapper for the next / last nav
     * button group. The `next` /  `last` args are button components.
     * Optional. Default: `["div.pager-next", next, last]`
     */ groupNext ( ctx , next , last ) : any ; /**
     * Page increment for prev / next page buttons. Default: 1
     */ navStep ? : number ; /**
     * Label for "first page" button. Default: `"<<""`
     */ labelFirst ? : any ; /**
     * Label for "last page" button. Default: `">>"`
     */ labelLast ? : any ; /**
     * Label for "prev page" button. Default: `"<"`
     */ labelPrev ? : any ; /**
     * Label for "next page" button. Default: `">"`
     */ labelNext ? : any ; } param opts export const pager = ( _opts ) => { const opts = < PagerOpts > { navStep : 1 , labelFirst : "<<" , labelPrev : "<" , labelNext : ">" , labelLast : ">>" , ... _opts , } ; return ( _ , id , num , pageLen = 10 , maxBts = 5 ) => { const bt = opts . button ; const step = opts . navStep ; const maxID = Math . floor ( Math . max ( 0 , num - 1 ) / pageLen ) ; id = Math . max ( Math . min ( id , maxID ) , 0 ) ; return [ opts . root , [ opts . groupPrev , bt ( 0 , id , maxID , opts . labelFirst , ! id ) , bt ( Math . max ( id - step ! , 0 ) , id , maxID , opts . labelPrev , ! id ) , ] , [ opts . groupPages , map ( ( i ) => bt ( i , id , maxID , i + 1 , i === id ) , pageRange ( id , maxID , maxBts ) ) , ] , [ opts . groupNext , bt ( Math . min ( id + step ! , maxID ) , id , maxID , opts . labelNext , id >= maxID ) , bt ( maxID , id , maxID , opts . labelLast , id >= maxID ) , ] , ] ; } ; } ; const pageRange = ( id , maxID , maxBt ) => { if ( maxID > maxBt - 1 ) { const from = Math . max ( Math . min ( id - ( maxBt >> 1 ) , maxID - maxBt + 1 ) , 0 ) ; return range ( from , from + maxBt ) ; } return range ( 0 , maxID + 1 ) ; } ;