This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.

CarwowTheme.Pagination

Filters

Exports

type alias PaginationProperties = { totalCount : Int , totalPages : Int , perPage : Int , currentPage : Int }

Properties for the pagination component

view : PaginationProperties -> (Int -> msg) -> Html msg

Helper to render the component

module CarwowTheme.Pagination exposing (PaginationProperties, view)

{-| Filters


# Exports

@docs PaginationProperties, view

-}

import Html exposing (Html, a, div, text)
import Html.Attributes exposing (class, classList, href)
import Html.Events exposing (onClick)
import CarwowTheme.Icons exposing (icon)
import List.Extra exposing (group)


{-| Properties for the pagination component
-}
type alias PaginationProperties =
    { totalCount : Int
    , totalPages : Int
    , perPage : Int
    , currentPage : Int
    }


type Page
    = Maybe Int


linkView : Int -> Html msg -> (Int -> msg) -> PaginationProperties -> Html msg
linkView page content clickMsg pagination =
    div
        [ classList
            [ ( "pagination__page ", True )
            , ( "pagination__page--active", pagination.currentPage == page )
            ]
        ]
        [ a
            [ href "javascript:;"
            , onClick (clickMsg page)
            ]
            [ content ]
        ]


emptyLinkView : Html msg
emptyLinkView =
    div [ class "pagination__page" ]
        [ text "…"
        ]


prevLink : PaginationProperties -> (Int -> msg) -> Html msg
prevLink pagination clickMsg =
    if pagination.currentPage > 1 then
        linkView
            (pagination.currentPage - 1)
            (icon "caret_left" { size = "x-small", colour = "dark-grey", colouring = "outline" })
            clickMsg
            pagination
    else
        text ""


pageLinks : PaginationProperties -> (Int -> msg) -> List (Html msg)
pageLinks pagination clickMsg =
    let
        allPages =
            List.range 1 pagination.totalPages

        middlePages =
            List.map
                (\page ->
                    if abs (page - pagination.currentPage) < 2 then
                        Just page
                    else
                        Nothing
                )
                allPages

        middleAndLimitPages =
            List.concat [ [ Just 1 ], middlePages, [ Just pagination.totalPages ] ]

        pages =
            middleAndLimitPages |> List.Extra.group |> List.map (List.take 1) |> List.concat
    in
        List.map
            (\page ->
                case page of
                    Nothing ->
                        emptyLinkView

                    Just pageNum ->
                        linkView pageNum (text (toString pageNum)) clickMsg pagination
            )
            pages


nextLink : PaginationProperties -> (Int -> msg) -> Html msg
nextLink pagination clickMsg =
    if pagination.currentPage < pagination.totalPages then
        linkView
            (pagination.currentPage + 1)
            (icon "caret_right" { size = "x-small", colour = "dark-grey", colouring = "outline" })
            clickMsg
            pagination
    else
        text ""


{-| Helper to render the component
-}
view : PaginationProperties -> (Int -> msg) -> Html msg
view pagination clickMsg =
    let
        links =
            List.concat
                [ [ prevLink pagination clickMsg ]
                , pageLinks pagination clickMsg
                , [ nextLink pagination clickMsg ]
                ]
    in
        div [ class "pagination" ] links