Implemented upwards accordions

This commit is contained in:
Mandla Moyo 2023-12-06 10:14:52 -08:00
parent fd52bddb2f
commit 74bdddc1e6
3 changed files with 71 additions and 25 deletions

View File

@ -23,7 +23,7 @@ import EllieLink
import Example exposing (Example)
import Html.Styled.Attributes as Attributes exposing (css, src)
import KeyboardSupport exposing (Key(..))
import Nri.Ui.Accordion.V3 as Accordion exposing (AccordionEntry(..))
import Nri.Ui.Accordion.V4 as Accordion exposing (AccordionEntry(..))
import Nri.Ui.Colors.Extra as ColorsExtra
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.FocusRing.V1 as FocusRing
@ -163,6 +163,7 @@ view ellieLinkConfig model =
{ caret = Tuple.second settings_.icon
, content = \() -> Tuple.second settings_.content
, entryClass = "customizable-example"
, expansionDirection = Accordion.Downwards
, headerContent = Tuple.second settings_.headerContent
, headerId = "customizable-example-header"
, headerLevel = Accordion.H3
@ -174,6 +175,7 @@ view ellieLinkConfig model =
{ caret = Accordion.defaultCaret
, content = \_ -> Html.text "🍎 There are many kinds of apples! Apples are more genetically diverse than humans. The genetic diversity of apples means that to preserve delicious apple varieties, growers must use grafting rather than seeds. In the apple market, clones have already taken over! 🍏"
, entryClass = "accordion-example"
, expansionDirection = Accordion.Downwards
, headerContent = Html.text "Apples (has children)"
, headerId = "accordion-entry__1"
, headerLevel = Accordion.H3
@ -193,6 +195,7 @@ view ellieLinkConfig model =
[ Html.text "Wikipedia article on Gala Apples" ]
]
, entryClass = "accordion-example-child"
, expansionDirection = Accordion.Downwards
, headerContent = Html.text "Gala"
, headerId = "accordion-entry__11"
, headerLevel = Accordion.H4
@ -213,6 +216,7 @@ view ellieLinkConfig model =
[ Html.text "Wikipedia article on Granny Smith Apples" ]
]
, entryClass = "accordion-example-child"
, expansionDirection = Accordion.Downwards
, headerContent = Html.text "Granny Smith"
, headerId = "accordion-entry__12"
, headerLevel = Accordion.H4
@ -233,6 +237,7 @@ view ellieLinkConfig model =
[ Html.text "Wikipedia article on Fuji Apples" ]
]
, entryClass = "accordion-example-child"
, expansionDirection = Accordion.Downwards
, headerContent = Html.text "Fuji"
, headerId = "accordion-entry__13"
, headerLevel = Accordion.H4
@ -242,10 +247,11 @@ view ellieLinkConfig model =
[]
]
, AccordionEntry
{ caret = Accordion.defaultCaret
{ caret = Accordion.upwardCaret
, content = \_ -> Html.text "🍊 I don't know anything about oranges! Except: YUM! 🍊"
, entryClass = "accordion-example"
, headerContent = Html.text "Oranges"
, expansionDirection = Accordion.Upwards
, headerContent = Html.text "Oranges (Upward accordion!)"
, headerId = "accordion-entry__2"
, headerLevel = Accordion.H3
, isExpanded = Set.member 2 model.expanded
@ -277,6 +283,7 @@ view ellieLinkConfig model =
[ Html.img "Wild Apple" [ src "https://upload.wikimedia.org/wikipedia/commons/9/92/95apple.jpeg" ] ]
]
, entryClass = "fixed-positioning-accordion-example"
, expansionDirection = Accordion.Downwards
, headerContent = Html.text "Advanced Example: Expand & Scroll!"
, headerId = "accordion-entry__6"
, headerLevel = Accordion.H3

View File

@ -3,6 +3,7 @@ module Nri.Ui.Accordion.V4 exposing
, AccordionEntry(..), Entry
, StyleOptions, styleAccordion
, defaultCaret
, ExpansionDirection(..), upwardCaret
)
{-|
@ -11,6 +12,7 @@ module Nri.Ui.Accordion.V4 exposing
## Changes from V3
- Enables accordion expansion either upwards or downwards
- Added animated caret for upward accordions
## Example
@ -21,7 +23,7 @@ module Nri.Ui.Accordion.V4 exposing
[ Accordion.view
{ entries =
[ AccordionEntry
{ caret = Accordion.defaultCaret
{ caret = Accordion.updwardCaret
, content = \() -> text "Accordion Content"
, entryClass = "a-class-distinguishing-this-accordion-from-others-on-the-page"
, expansionDirection = Accordion.Upwards
@ -67,6 +69,7 @@ import Nri.Ui.FocusLoop.V1 as FocusLoop
import Nri.Ui.FocusRing.V1 as FocusRing
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Html.Attributes.V2 as AttributesExtra
import Nri.Ui.Html.V3 exposing (viewIf)
import Nri.Ui.Svg.V1 as Svg
@ -81,6 +84,17 @@ defaultCaret isOpen =
|> Svg.toHtml
{-| -}
upwardCaret : Bool -> Html msg
upwardCaret isOpen =
AnimatedIcon.arrowRightUp isOpen
|> Svg.withColor Colors.azure
|> Svg.withWidth (Css.px 17)
|> Svg.withHeight (Css.px 17)
|> Svg.withCss [ Css.marginRight (Css.px 8) ]
|> Svg.toHtml
{-| -}
type alias StyleOptions =
{ entryStyles : List Style
@ -184,6 +198,11 @@ accordionEntryPanelClass =
"accordion-v3-entry-panel"
type ExpansionDirection
= Upwards
| Downwards
{-| Corresponds to h1, h2, h3 etc.
Choose the correct header level given your page context.
-}
@ -228,6 +247,7 @@ type alias Entry msg =
{ caret : Bool -> Html msg
, content : () -> Html msg
, entryClass : String
, expansionDirection : ExpansionDirection
, headerContent : Html msg
, headerId : String
, headerLevel : HeaderLevel
@ -299,10 +319,29 @@ viewEntry :
-> Entry msg
-> List (AccordionEntry msg)
-> Html msg
viewEntry focus arrows ({ headerId, headerLevel, caret, headerContent, entryClass, content, isExpanded } as config) children =
viewEntry focus arrows ({ headerId, headerLevel, caret, headerContent, entryClass, expansionDirection, content, isExpanded } as config) children =
let
panelId =
"accordion-panel__" ++ headerId
contents =
section
[ Attributes.id panelId
, Aria.labelledBy headerId
, Attributes.classList
[ ( accordionEntryPanelClass, True )
, ( entryClass, True )
]
, Attributes.hidden (not isExpanded)
]
(if isExpanded then
[ content ()
, view_ { focus = focus, entries = children, leftId = Just headerId }
]
else
[]
)
in
div
[ Attributes.classList
@ -312,7 +351,8 @@ viewEntry focus arrows ({ headerId, headerLevel, caret, headerContent, entryClas
, ( accordionEntryCollapsedClass, not isExpanded )
]
]
[ header headerLevel <|
[ viewIf (\_ -> contents) (expansionDirection == Upwards)
, header headerLevel <|
button
[ Attributes.id headerId
, Attributes.classList
@ -339,21 +379,5 @@ viewEntry focus arrows ({ headerId, headerLevel, caret, headerContent, entryClas
[ caret isExpanded
, headerContent
]
, section
[ Attributes.id panelId
, Aria.labelledBy headerId
, Attributes.classList
[ ( accordionEntryPanelClass, True )
, ( entryClass, True )
]
, Attributes.hidden (not isExpanded)
]
(if isExpanded then
[ content ()
, view_ { focus = focus, entries = children, leftId = Just headerId }
]
else
[]
)
, viewIf (\_ -> contents) (expansionDirection == Downwards)
]

View File

@ -1,8 +1,8 @@
module Nri.Ui.AnimatedIcon.V1 exposing (mobileOpenClose, arrowRightDown, arrowDownUp)
module Nri.Ui.AnimatedIcon.V1 exposing (mobileOpenClose, arrowRightDown, arrowRightUp, arrowDownUp)
{-|
@docs mobileOpenClose, arrowRightDown, arrowDownUp
@docs mobileOpenClose, arrowRightDown, arrowRightUp, arrowDownUp
-}
@ -74,6 +74,21 @@ arrowRightDown isOpen =
squareArrowLeft
{-| An arrow that animates between pointing right and pointing up. Typically used for disclosures and accordions.
-}
arrowRightUp : Bool -> Nri.Ui.Svg.V1.Svg
arrowRightUp isOpen =
Nri.Ui.Svg.V1.withCss
[ Css.property "transition" "transform 0.1s"
, if isOpen then
Css.transform (Css.rotate (Css.deg 90))
else
Css.transform (Css.rotate (Css.deg 180))
]
squareArrowLeft
{-| An arrow that animates between pointing down and pointing up. Typically used as a fly-out menu indicator.
-}
arrowDownUp : Bool -> Nri.Ui.Svg.V1.Svg