Skip to content

Commit

Permalink
Merge pull request #1217 from NoRedInk/tessa/pagination
Browse files Browse the repository at this point in the history
Tessa/pagination
  • Loading branch information
tesk9 authored Jan 5, 2023
2 parents 2bbf7bd + 4946042 commit 9a58bba
Show file tree
Hide file tree
Showing 11 changed files with 503 additions and 29 deletions.
1 change: 1 addition & 0 deletions elm.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"Nri.Ui.Message.V3",
"Nri.Ui.Modal.V11",
"Nri.Ui.Page.V3",
"Nri.Ui.Pagination.V1",
"Nri.Ui.Palette.V1",
"Nri.Ui.Panel.V1",
"Nri.Ui.Pennant.V2",
Expand Down
5 changes: 3 additions & 2 deletions src/ClickableAttributes.elm
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ linkExternalWithTracking { track, url } clickableAttributes =


{-| -}
toButtonAttributes : ClickableAttributes route msg -> List (Attribute msg)
toButtonAttributes clickableAttributes =
toButtonAttributes : ClickableAttributes route msg -> { disabled : Bool } -> List (Attribute msg)
toButtonAttributes clickableAttributes { disabled } =
[ AttributesExtra.maybe Events.onClick clickableAttributes.onClick
, Attributes.type_ clickableAttributes.buttonType
, -- why "aria-haspopup=true" instead of "aria-haspopup=dialog"?
Expand All @@ -143,6 +143,7 @@ toButtonAttributes clickableAttributes =
-- If time has passed, feel free to revisit and see if dialog support has improved!
AttributesExtra.includeIf clickableAttributes.opensModal
(Attributes.attribute "aria-haspopup" "true")
, Attributes.disabled disabled
]


Expand Down
4 changes: 2 additions & 2 deletions src/Nri/Ui/Button/V10.elm
Original file line number Diff line number Diff line change
Expand Up @@ -635,8 +635,8 @@ renderButton ((ButtonOrLink config) as button_) =
]
]
(ClickableAttributes.toButtonAttributes config.clickableAttributes
++ Attributes.disabled (isDisabled config.state)
:: Attributes.class FocusRing.customClass
{ disabled = isDisabled config.state }
++ Attributes.class FocusRing.customClass
:: config.customAttributes
)
[ viewLabel config ]
Expand Down
2 changes: 1 addition & 1 deletion src/Nri/Ui/ClickableSvg/V2.elm
Original file line number Diff line number Diff line change
Expand Up @@ -584,10 +584,10 @@ renderButton ((ButtonOrLink config) as button_) =
([ Attributes.class "Nri-Ui-Clickable-Svg-V1__button"
, Attributes.class FocusRing.customClass
, Attributes.css (buttonOrLinkStyles config theme ++ config.customStyles)
, Attributes.disabled config.disabled
, Aria.label config.label
]
++ ClickableAttributes.toButtonAttributes config.clickableAttributes
{ disabled = config.disabled }
++ config.customAttributes
)
(renderIcons config theme.includeBorder)
Expand Down
83 changes: 59 additions & 24 deletions src/Nri/Ui/ClickableText/V3.elm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Nri.Ui.ClickableText.V3 exposing
, small, medium, large, modal
, onClick, submit, opensModal
, href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
, disabled
, icon, rightIcon
, hideIconForMobile, hideIconFor
, custom, nriDescription, testId, id
Expand All @@ -30,6 +31,7 @@ module Nri.Ui.ClickableText.V3 exposing
- adds `hideIconForMobile` and `hideIconAt`
- adds `hideTextForMobile` and `hideTextAt`
- adds `submit` and `opensModal`
- adds `disabled`
# Changes from V2
Expand Down Expand Up @@ -72,6 +74,7 @@ HTML `<a>` elements and are created here with `*Link` functions.
@docs onClick, submit, opensModal
@docs href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
@docs disabled
## Icons
Expand Down Expand Up @@ -364,6 +367,25 @@ linkExternalWithTracking config =
setClickableAttributes (ClickableAttributes.linkExternalWithTracking config)


{-| Shows inactive styling.
If a button, this attribute will disable it as you'd expect.
If a link, this attribute will follow the pattern laid out in [Scott O'Hara's disabled links](https://www.scottohara.me/blog/2021/05/28/disabled-links.html) article,
and essentially make the anchor a disabled placeholder.
_Caveat!_
The styleguide example will NOT work correctly because of <https://github.com/elm/browser/issues/34>, which describes a problem where "a tags without href generate a navigation event".
In most cases, if you're not using Browser.application, disabled links should work just fine.
-}
disabled : Bool -> Attribute msg
disabled value =
set (\attributes -> { attributes | disabled = value })


{-| Creates a `<button>` element
-}
button :
Expand All @@ -378,8 +400,9 @@ button label_ attributes =
in
Nri.Ui.styled Html.button
(dataDescriptor "button")
(clickableTextStyles ++ config.customStyles)
(clickableTextStyles config.disabled ++ config.customStyles)
(ClickableAttributes.toButtonAttributes config.clickableAttributes
{ disabled = config.disabled }
++ config.customAttributes
)
[ viewContent config ]
Expand All @@ -400,13 +423,13 @@ link label_ attributes =
( name, clickableAttributes ) =
ClickableAttributes.toLinkAttributes
{ routeToString = identity
, isDisabled = False
, isDisabled = config.disabled
}
config.clickableAttributes
in
Nri.Ui.styled Html.a
(dataDescriptor name)
(clickableTextStyles ++ config.customStyles)
(clickableTextStyles config.disabled ++ config.customStyles)
(clickableAttributes ++ config.customAttributes)
[ viewContent config ]

Expand Down Expand Up @@ -460,27 +483,37 @@ viewContent config =
)


clickableTextStyles : List Css.Style
clickableTextStyles =
[ Css.cursor Css.pointer
, Nri.Ui.Fonts.V1.baseFont
, Css.backgroundImage Css.none
, Css.textShadow Css.none
, Css.boxShadow Css.none
, Css.border Css.zero
, Css.disabled [ Css.cursor Css.notAllowed ]
, Css.color Colors.azure
, Css.hover [ Css.color Colors.azureDark ]
, Css.backgroundColor Css.transparent
, Css.fontWeight (Css.int 600)
, Css.textAlign Css.left
, Css.borderStyle Css.none
, Css.textDecoration Css.none
, Css.padding Css.zero
, Css.display Css.inlineBlock
, Css.verticalAlign Css.textBottom
, Css.margin Css.zero -- Get rid of default margin Webkit adds to buttons
]
clickableTextStyles : Bool -> List Css.Style
clickableTextStyles isDisabled =
let
baseStyles =
[ Nri.Ui.Fonts.V1.baseFont
, Css.backgroundImage Css.none
, Css.textShadow Css.none
, Css.boxShadow Css.none
, Css.border Css.zero
, Css.backgroundColor Css.transparent
, Css.fontWeight (Css.int 600)
, Css.textAlign Css.left
, Css.borderStyle Css.none |> Css.important
, Css.textDecoration Css.none
, Css.padding Css.zero
, Css.display Css.inlineBlock
, Css.verticalAlign Css.textBottom
, Css.margin Css.zero -- Get rid of default margin Webkit adds to buttons
]
in
if isDisabled then
Css.cursor Css.notAllowed
:: Css.color Colors.gray45
:: Css.visited [ Css.important (Css.color Colors.gray45) ]
:: baseStyles

else
Css.cursor Css.pointer
:: Css.color Colors.azure
:: Css.hover [ Css.color Colors.azureDark ]
:: baseStyles


sizeToPx : Size -> Css.Px
Expand Down Expand Up @@ -514,6 +547,7 @@ type alias ClickableTextAttributes msg =
, rightIcon : Maybe Svg
, customAttributes : List (Html.Attribute msg)
, customStyles : List Style
, disabled : Bool
}


Expand All @@ -527,6 +561,7 @@ defaults =
, rightIcon = Nothing
, customAttributes = [ Attributes.class FocusRing.customClass ]
, customStyles = [ Css.pseudoClass "focus-visible" (Css.borderRadius (Css.px 4) :: FocusRing.tightStyles) ]
, disabled = False
}


Expand Down
140 changes: 140 additions & 0 deletions src/Nri/Ui/Pagination/V1.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
module Nri.Ui.Pagination.V1 exposing (view)

{-| Display a nav element aiding in navigating between pages of content.
[ Previous ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ Next ]
@docs view
-}

import Accessibility.Styled as Html exposing (Html)
import Accessibility.Styled.Aria as Aria
import Css
import Css.Transitions as Transitions
import Html.Styled.Attributes exposing (css)
import List.Extra
import Nri.Ui.ClickableText.V3 as ClickableText
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Html.V3 exposing (viewIf)


{-| Pass in a list of page URLs/on-click handlers and the currently-selected page's index.
view
[ { onClick = GoToPage 0, href = "#page-1" }
, { onClick = GoToPage 1, href = "#page-2" }
, { onClick = GoToPage 2, href = "#page-3" }
]
2
Note: the navigation will only show if there's 2 or more pages of content.
-}
view : List { onClick : msg, href : String } -> Int -> Html msg
view pages currentPageIndex =
viewIf (\_ -> view_ pages currentPageIndex)
(List.length pages > 1)


view_ : List { onClick : msg, href : String } -> Int -> Html msg
view_ pages currentPageIndex =
Html.nav
[ css
[ Css.width (Css.pct 100)
, Css.displayFlex
, Css.justifyContent Css.center
, Css.alignItems Css.center
]
, Aria.label "pagination"
]
[ previousPageLink (List.Extra.getAt (currentPageIndex - 1) pages)
, pages
|> List.indexedMap
(\index page ->
Html.li [] [ directPageLink currentPageIndex index page ]
)
|> Html.ol
[ css
[ Css.displayFlex
, Css.flexWrap Css.wrap
, Css.justifyContent Css.center
, Css.listStyleType Css.none
, Css.margin Css.zero
, Css.padding Css.zero
]
]
, nextPageLink (List.Extra.getAt (currentPageIndex + 1) pages)
]


previousPageLink : Maybe { onClick : msg, href : String } -> Html msg
previousPageLink maybePreviousPage =
ClickableText.link "Previous\u{00A0}page" <|
[ ClickableText.small
, ClickableText.css [ Css.marginRight (Css.px 10) ]
]
++ linkAttributes maybePreviousPage


nextPageLink : Maybe { onClick : msg, href : String } -> Html msg
nextPageLink maybeNextPage =
ClickableText.link "Next\u{00A0}page" <|
[ ClickableText.small
, ClickableText.css [ Css.marginLeft (Css.px 10) ]
]
++ linkAttributes maybeNextPage


directPageLink : Int -> Int -> { onClick : msg, href : String } -> Html msg
directPageLink currentPageIndex pageIndex page =
let
humanPage =
String.fromInt (pageIndex + 1)
in
ClickableText.link humanPage <|
[ ClickableText.small
, List.filterMap identity
[ Just (Aria.label ("Page " ++ humanPage))
, if pageIndex == currentPageIndex then
Just Aria.currentPage

else
Nothing
]
|> ClickableText.custom
, ClickableText.css
[ Css.padding2 (Css.px 7) (Css.px 13.5)
, Css.minWidth (Css.px 36)
, Css.minHeight (Css.px 33)
, Css.textAlign Css.center
, Css.margin (Css.px 7)
, Css.borderRadius (Css.px 8)
, Transitions.transition
[ Transitions.backgroundColor 300
, Transitions.color 300
]
, if pageIndex == currentPageIndex then
Css.batch
[ Css.backgroundColor Colors.glacier
, Css.border3 (Css.px 1) Css.solid Colors.glacier |> Css.important
, Css.color Colors.navy
]

else
Css.batch []
]
]
++ linkAttributes (Just page)


linkAttributes : Maybe { onClick : msg, href : String } -> List (ClickableText.Attribute msg)
linkAttributes maybePage =
case maybePage of
Just { onClick, href } ->
[ ClickableText.onClick onClick
, ClickableText.linkSpa href
]

Nothing ->
[ ClickableText.disabled True ]
22 changes: 22 additions & 0 deletions styleguide-app/Examples.elm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import Examples.Menu as Menu
import Examples.Message as Message
import Examples.Modal as Modal
import Examples.Page as Page
import Examples.Pagination as Pagination
import Examples.Panel as Panel
import Examples.Pennant as Pennant
import Examples.PremiumCheckbox as PremiumCheckbox
Expand Down Expand Up @@ -583,6 +584,25 @@ all =
PageState childState ->
Just childState

_ ->
Nothing
)
, Pagination.example
|> Example.wrapMsg PaginationMsg
(\msg ->
case msg of
PaginationMsg childMsg ->
Just childMsg

_ ->
Nothing
)
|> Example.wrapState PaginationState
(\msg ->
case msg of
PaginationState childState ->
Just childState

_ ->
Nothing
)
Expand Down Expand Up @@ -1017,6 +1037,7 @@ type State
| MessageState Message.State
| ModalState Modal.State
| PageState Page.State
| PaginationState Pagination.State
| PanelState Panel.State
| PennantState Pennant.State
| PremiumCheckboxState PremiumCheckbox.State
Expand Down Expand Up @@ -1069,6 +1090,7 @@ type Msg
| MessageMsg Message.Msg
| ModalMsg Modal.Msg
| PageMsg Page.Msg
| PaginationMsg Pagination.Msg
| PanelMsg Panel.Msg
| PennantMsg Pennant.Msg
| PremiumCheckboxMsg PremiumCheckbox.Msg
Expand Down
Loading

0 comments on commit 9a58bba

Please sign in to comment.