mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-09-21 04:07:54 +03:00
Merge pull request #1578 from NoRedInk/growth/upward-accordion
Upward opening accordions
This commit is contained in:
commit
36001ad618
@ -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
|
||||
@ -43,7 +43,7 @@ moduleName =
|
||||
|
||||
version : Int
|
||||
version =
|
||||
3
|
||||
4
|
||||
|
||||
|
||||
{-| -}
|
||||
@ -120,6 +120,7 @@ view ellieLinkConfig model =
|
||||
[ ( "caret", Tuple.first settings.icon )
|
||||
, ( "content", Code.anonymousFunction "()" (Tuple.first settings.content) )
|
||||
, ( "entryClass", Code.string "customizable-example" )
|
||||
, ( "expansionDirection", Tuple.first settings.expansionDirection )
|
||||
, ( "headerContent", Tuple.first settings.headerContent )
|
||||
, ( "headerId", Code.string "customizable-example-header" )
|
||||
, ( "headerLevel", Code.fromModule moduleName "H3" )
|
||||
@ -163,6 +164,7 @@ view ellieLinkConfig model =
|
||||
{ caret = Tuple.second settings_.icon
|
||||
, content = \() -> Tuple.second settings_.content
|
||||
, entryClass = "customizable-example"
|
||||
, expansionDirection = Tuple.second settings_.expansionDirection
|
||||
, headerContent = Tuple.second settings_.headerContent
|
||||
, headerId = "customizable-example-header"
|
||||
, headerLevel = Accordion.H3
|
||||
@ -174,6 +176,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 +196,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 +217,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 +238,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 +248,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 +284,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
|
||||
@ -348,6 +356,7 @@ type alias State =
|
||||
|
||||
type alias Settings =
|
||||
{ icon : ( String, Bool -> Html Msg )
|
||||
, expansionDirection : ( String, Accordion.ExpansionDirection )
|
||||
, headerContent : ( String, Html Msg )
|
||||
, content : ( String, Html Msg )
|
||||
}
|
||||
@ -357,6 +366,7 @@ initSettings : Control Settings
|
||||
initSettings =
|
||||
Control.record Settings
|
||||
|> Control.field "icon" controlIcon
|
||||
|> Control.field "expansionDirection" controlExpansionDirection
|
||||
|> Control.field "headerContent" controlHeaderContent
|
||||
|> Control.field "content" controlContent
|
||||
|
||||
@ -367,6 +377,9 @@ controlIcon =
|
||||
[ ( "defaultCaret"
|
||||
, Control.value ( "Accordion.defaultCaret", Accordion.defaultCaret )
|
||||
)
|
||||
, ( "upwardCaret"
|
||||
, Control.value ( "Accordion.upwardCaret", Accordion.upwardCaret )
|
||||
)
|
||||
, ( "none", Control.value ( "\\_ -> text \"\"", \_ -> Html.text "" ) )
|
||||
, ( "UiIcon"
|
||||
, Control.map
|
||||
@ -403,6 +416,18 @@ controlHeaderContent =
|
||||
(Control.string "Berries")
|
||||
|
||||
|
||||
controlExpansionDirection : Control ( String, Accordion.ExpansionDirection )
|
||||
controlExpansionDirection =
|
||||
Control.choice
|
||||
[ ( "Downwards"
|
||||
, Control.value ( "Accordion.Downwards", Accordion.Downwards )
|
||||
)
|
||||
, ( "Upwards"
|
||||
, Control.value ( "Accordion.Upwards", Accordion.Upwards )
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
controlContent : Control ( String, Html Msg )
|
||||
controlContent =
|
||||
Control.map
|
||||
|
@ -13,7 +13,7 @@ import Example exposing (Example)
|
||||
import Html.Styled as Html exposing (..)
|
||||
import Html.Styled.Attributes exposing (css, href)
|
||||
import Markdown
|
||||
import Nri.Ui.Accordion.V3 as Accordion exposing (AccordionEntry(..))
|
||||
import Nri.Ui.Accordion.V4 as Accordion exposing (AccordionEntry(..))
|
||||
import Nri.Ui.Button.V10 as Button
|
||||
import Nri.Ui.Checkbox.V7 as Checkbox
|
||||
import Nri.Ui.ClickableSvg.V2 as ClickableSvg
|
||||
@ -248,6 +248,7 @@ NOTE: use `boxShadows` instead if your focusable element:
|
||||
{ caret = Accordion.defaultCaret
|
||||
, content = \() -> text "Content"
|
||||
, entryClass = "accordion-focus-ring"
|
||||
, expansionDirection = Accordion.Downwards
|
||||
, headerContent = text "Accordion"
|
||||
, headerId = "accordion-focus-ring-example-header"
|
||||
, headerLevel = Accordion.H3
|
||||
|
@ -1,3 +1,4 @@
|
||||
Nri.Ui.Accordion.V3,upgrade to V4
|
||||
Nri.Ui.Block.V4,upgrade to V6
|
||||
Nri.Ui.Block.V5,upgrade to V6
|
||||
Nri.Ui.Carousel.V1,upgrade to V2
|
||||
|
|
1
elm.json
1
elm.json
@ -10,6 +10,7 @@
|
||||
"Nri.Test.MouseHelpers.V1",
|
||||
"Nri.Ui",
|
||||
"Nri.Ui.Accordion.V3",
|
||||
"Nri.Ui.Accordion.V4",
|
||||
"Nri.Ui.AnimatedIcon.V1",
|
||||
"Nri.Ui.AssignmentIcon.V2",
|
||||
"Nri.Ui.Balloon.V2",
|
||||
|
@ -38,6 +38,9 @@ usages = ['component-catalog-app/../src/Nri/Ui/Button/V8.elm']
|
||||
[forbidden."Nri.Ui.Accordion.V1"]
|
||||
hint = 'upgrade to V3'
|
||||
|
||||
[forbidden."Nri.Ui.Accordion.V3"]
|
||||
hint = 'upgrade to V4'
|
||||
|
||||
[forbidden."Nri.Ui.Balloon.V1"]
|
||||
hint = 'upgrade to V2'
|
||||
|
||||
|
393
src/Nri/Ui/Accordion/V4.elm
Normal file
393
src/Nri/Ui/Accordion/V4.elm
Normal file
@ -0,0 +1,393 @@
|
||||
module Nri.Ui.Accordion.V4 exposing
|
||||
( view, HeaderLevel(..)
|
||||
, AccordionEntry(..), Entry
|
||||
, StyleOptions, styleAccordion
|
||||
, defaultCaret
|
||||
, ExpansionDirection(..), upwardCaret
|
||||
)
|
||||
|
||||
{-|
|
||||
|
||||
|
||||
## Changes from V3
|
||||
|
||||
- Enables accordion expansion either upwards or downwards
|
||||
- Added animated caret for upward accordions
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
div []
|
||||
[ Accordion.view
|
||||
{ entries =
|
||||
[ AccordionEntry
|
||||
{ caret = Accordion.updwardCaret
|
||||
, content = \() -> text "Accordion Content"
|
||||
, entryClass = "a-class-distinguishing-this-accordion-from-others-on-the-page"
|
||||
, expansionDirection = Accordion.Upwards
|
||||
, headerContent = text "Accordion Header"
|
||||
, headerId = "a-unique-id-for-this-accordion-header-button"
|
||||
, headerLevel = Accordion.H1
|
||||
, isExpanded = model.isAccordionOpen
|
||||
, toggle = Just ToggleAccordion
|
||||
}
|
||||
[]
|
||||
]
|
||||
, focus = Focus
|
||||
}
|
||||
, Accordion.styleAccordion
|
||||
{ entryStyles = []
|
||||
, entryExpandedStyles = []
|
||||
, entryClosedStyles = []
|
||||
, headerStyles = []
|
||||
, headerExpandedStyles = []
|
||||
, headerClosedStyles = []
|
||||
, contentStyles = []
|
||||
}
|
||||
]
|
||||
|
||||
@docs view, HeaderLevel
|
||||
@docs AccordionEntry, Entry
|
||||
@docs StyleOptions, styleAccordion
|
||||
@docs defaultCaret
|
||||
@docs ExpansionDirection, upwardCaret
|
||||
|
||||
-}
|
||||
|
||||
import Accessibility.Styled exposing (Html, button, div, section)
|
||||
import Accessibility.Styled.Aria as Aria
|
||||
import Accessibility.Styled.Key as Key
|
||||
import Css exposing (..)
|
||||
import Css.Global
|
||||
import Html.Styled.Attributes as Attributes
|
||||
import Html.Styled.Events exposing (onClick)
|
||||
import Html.Styled.Keyed
|
||||
import Nri.Ui.AnimatedIcon.V1 as AnimatedIcon
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
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.Svg.V1 as Svg
|
||||
|
||||
|
||||
{-| -}
|
||||
defaultCaret : Bool -> Html msg
|
||||
defaultCaret isOpen =
|
||||
AnimatedIcon.arrowRightDown isOpen
|
||||
|> Svg.withColor Colors.azure
|
||||
|> Svg.withWidth (Css.px 17)
|
||||
|> Svg.withHeight (Css.px 17)
|
||||
|> Svg.withCss [ Css.marginRight (Css.px 8) ]
|
||||
|> Svg.toHtml
|
||||
|
||||
|
||||
{-| Animated caret used for accordions that expand upwards.
|
||||
-}
|
||||
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
|
||||
, entryExpandedStyles : List Style
|
||||
, entryClosedStyles : List Style
|
||||
, headerStyles : List Style
|
||||
, headerExpandedStyles : List Style
|
||||
, headerClosedStyles : List Style
|
||||
, contentStyles : List Style
|
||||
}
|
||||
|
||||
|
||||
{-| -}
|
||||
styleAccordion : StyleOptions -> Html msg
|
||||
styleAccordion styleOptions =
|
||||
Css.Global.global
|
||||
[ Css.Global.class accordionHeaderClass
|
||||
[ margin zero, padding zero ]
|
||||
, Css.Global.class accordionEntryHeaderClass
|
||||
([ displayFlex
|
||||
, alignItems center
|
||||
, boxSizing borderBox
|
||||
, minWidth (pct 100)
|
||||
|
||||
-- button resets
|
||||
, Css.Global.withAttribute "aria-disabled=false" [ cursor pointer ]
|
||||
, Css.backgroundColor Css.unset
|
||||
, borderWidth Css.zero
|
||||
, margin zero
|
||||
, Css.pseudoClass "focus-visible" [ FocusRing.insetBoxShadows [] ]
|
||||
|
||||
-- fonts & text
|
||||
, textAlign left
|
||||
, Fonts.baseFont
|
||||
, fontSize (px 16)
|
||||
, fontWeight (int 600)
|
||||
, lineHeight (num 1.2)
|
||||
, Css.Global.withClass accordionEntryHeaderExpandedClass
|
||||
styleOptions.headerExpandedStyles
|
||||
, Css.Global.withClass accordionEntryHeaderCollapsedClass
|
||||
styleOptions.headerClosedStyles
|
||||
]
|
||||
++ styleOptions.headerStyles
|
||||
)
|
||||
, Css.Global.class accordionEntryClass
|
||||
([ marginBottom (px 10)
|
||||
, Css.Global.withClass accordionEntryExpandedClass
|
||||
styleOptions.entryExpandedStyles
|
||||
, Css.Global.withClass accordionEntryCollapsedClass
|
||||
styleOptions.entryClosedStyles
|
||||
]
|
||||
++ styleOptions.entryStyles
|
||||
)
|
||||
, Css.Global.class accordionEntryPanelClass
|
||||
styleOptions.contentStyles
|
||||
, Css.Global.class accordionExpandsUpwardsClass
|
||||
[ Css.displayFlex, Css.flexDirection Css.columnReverse ]
|
||||
]
|
||||
|
||||
|
||||
accordionClass : String
|
||||
accordionClass =
|
||||
"accordion-v4"
|
||||
|
||||
|
||||
accordionHeaderClass : String
|
||||
accordionHeaderClass =
|
||||
"accordion-v4-header"
|
||||
|
||||
|
||||
accordionEntryHeaderClass : String
|
||||
accordionEntryHeaderClass =
|
||||
"accordion-v4-entry-header"
|
||||
|
||||
|
||||
accordionEntryHeaderExpandedClass : String
|
||||
accordionEntryHeaderExpandedClass =
|
||||
"accordion-v4-entry-header-expanded"
|
||||
|
||||
|
||||
accordionEntryHeaderCollapsedClass : String
|
||||
accordionEntryHeaderCollapsedClass =
|
||||
"accordion-v4-entry-header-collapsed"
|
||||
|
||||
|
||||
accordionEntryClass : String
|
||||
accordionEntryClass =
|
||||
"accordion-v4-entry"
|
||||
|
||||
|
||||
accordionEntryExpandedClass : String
|
||||
accordionEntryExpandedClass =
|
||||
"accordion-v4-entry-state-expanded"
|
||||
|
||||
|
||||
accordionEntryCollapsedClass : String
|
||||
accordionEntryCollapsedClass =
|
||||
"accordion-v4-entry-state-collapsed"
|
||||
|
||||
|
||||
accordionEntryPanelClass : String
|
||||
accordionEntryPanelClass =
|
||||
"accordion-v4-entry-panel"
|
||||
|
||||
|
||||
accordionExpandsUpwardsClass : String
|
||||
accordionExpandsUpwardsClass =
|
||||
"accordion-v4-expands-upwards"
|
||||
|
||||
|
||||
{-| Determines in which direction the accordion expands.
|
||||
-}
|
||||
type ExpansionDirection
|
||||
= Upwards
|
||||
| Downwards
|
||||
|
||||
|
||||
{-| Corresponds to h1, h2, h3 etc.
|
||||
Choose the correct header level given your page context.
|
||||
-}
|
||||
type HeaderLevel
|
||||
= H1
|
||||
| H2
|
||||
| H3
|
||||
| H4
|
||||
| H5
|
||||
| H6
|
||||
|
||||
|
||||
header : HeaderLevel -> Html msg -> Html msg
|
||||
header headerLevel content =
|
||||
case headerLevel of
|
||||
H1 ->
|
||||
Accessibility.Styled.h1 [ Attributes.class accordionHeaderClass ] [ content ]
|
||||
|
||||
H2 ->
|
||||
Accessibility.Styled.h2 [ Attributes.class accordionHeaderClass ] [ content ]
|
||||
|
||||
H3 ->
|
||||
Accessibility.Styled.h3 [ Attributes.class accordionHeaderClass ] [ content ]
|
||||
|
||||
H4 ->
|
||||
Accessibility.Styled.h4 [ Attributes.class accordionHeaderClass ] [ content ]
|
||||
|
||||
H5 ->
|
||||
Accessibility.Styled.h5 [ Attributes.class accordionHeaderClass ] [ content ]
|
||||
|
||||
H6 ->
|
||||
Accessibility.Styled.h6 [ Attributes.class accordionHeaderClass ] [ content ]
|
||||
|
||||
|
||||
{-| -}
|
||||
type AccordionEntry msg
|
||||
= AccordionEntry (Entry msg) (List (AccordionEntry msg))
|
||||
|
||||
|
||||
{-| -}
|
||||
type alias Entry msg =
|
||||
{ caret : Bool -> Html msg
|
||||
, content : () -> Html msg
|
||||
, entryClass : String
|
||||
, expansionDirection : ExpansionDirection
|
||||
, headerContent : Html msg
|
||||
, headerId : String
|
||||
, headerLevel : HeaderLevel
|
||||
, isExpanded : Bool
|
||||
, toggle : Maybe (Bool -> msg)
|
||||
}
|
||||
|
||||
|
||||
getHeaderId : AccordionEntry msg -> String
|
||||
getHeaderId entry =
|
||||
case entry of
|
||||
AccordionEntry { headerId } _ ->
|
||||
headerId
|
||||
|
||||
|
||||
{-| -}
|
||||
view :
|
||||
{ entries : List (AccordionEntry msg)
|
||||
, focus : String -> msg
|
||||
}
|
||||
-> Html msg
|
||||
view { entries, focus } =
|
||||
view_
|
||||
{ entries = entries
|
||||
, focus = focus
|
||||
, leftId = Nothing
|
||||
}
|
||||
|
||||
|
||||
view_ :
|
||||
{ entries : List (AccordionEntry msg)
|
||||
, focus : String -> msg
|
||||
, leftId : Maybe String
|
||||
}
|
||||
-> Html msg
|
||||
view_ { entries, focus, leftId } =
|
||||
div [ Attributes.class accordionClass ]
|
||||
[ Html.Styled.Keyed.node "div"
|
||||
[]
|
||||
(FocusLoop.addEvents
|
||||
{ focus = \(AccordionEntry { headerId } _) -> focus headerId
|
||||
, leftRight = False
|
||||
, upDown = True
|
||||
}
|
||||
entries
|
||||
|> List.map
|
||||
(\( AccordionEntry entry_ children, upDownEvents ) ->
|
||||
( "keyed-section__" ++ entry_.headerId
|
||||
, viewEntry focus
|
||||
{ upDownEvents = upDownEvents
|
||||
, right = Maybe.map getHeaderId (List.head children)
|
||||
, left = leftId
|
||||
}
|
||||
entry_
|
||||
children
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
viewEntry :
|
||||
(String -> msg)
|
||||
->
|
||||
{ upDownEvents : List (Key.Event msg)
|
||||
, right : Maybe String
|
||||
, left : Maybe String
|
||||
}
|
||||
-> Entry msg
|
||||
-> List (AccordionEntry msg)
|
||||
-> Html msg
|
||||
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
|
||||
[ ( accordionEntryClass, True )
|
||||
, ( entryClass, True )
|
||||
, ( accordionEntryExpandedClass, isExpanded )
|
||||
, ( accordionEntryCollapsedClass, not isExpanded )
|
||||
, ( accordionExpandsUpwardsClass, expansionDirection == Upwards )
|
||||
]
|
||||
]
|
||||
[ header headerLevel <|
|
||||
button
|
||||
[ Attributes.id headerId
|
||||
, Attributes.classList
|
||||
[ ( accordionEntryHeaderClass, True )
|
||||
, ( entryClass, True )
|
||||
, ( accordionEntryHeaderExpandedClass, isExpanded )
|
||||
, ( accordionEntryHeaderCollapsedClass, not isExpanded )
|
||||
, ( FocusRing.customClass, True )
|
||||
]
|
||||
, Aria.disabled (config.toggle == Nothing)
|
||||
, Aria.expanded isExpanded
|
||||
, Aria.controls [ panelId ]
|
||||
, config.toggle
|
||||
|> Maybe.map (\toggle -> onClick (toggle (not isExpanded)))
|
||||
|> Maybe.withDefault AttributesExtra.none
|
||||
, Key.onKeyDownPreventDefault
|
||||
(arrows.upDownEvents
|
||||
++ List.filterMap identity
|
||||
[ Maybe.map (\id -> Key.right (focus id)) arrows.right
|
||||
, Maybe.map (\id -> Key.left (focus id)) arrows.left
|
||||
]
|
||||
)
|
||||
]
|
||||
[ caret isExpanded
|
||||
, headerContent
|
||||
]
|
||||
, contents
|
||||
]
|
@ -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
|
||||
|
@ -3,7 +3,7 @@ module Spec.Nri.Ui.Accordion exposing (spec)
|
||||
import Accessibility.Aria as Aria
|
||||
import Browser.Dom as Dom
|
||||
import Html.Styled as Html exposing (..)
|
||||
import Nri.Ui.Accordion.V3 as Accordion
|
||||
import Nri.Ui.Accordion.V4 as Accordion
|
||||
import ProgramTest exposing (..)
|
||||
import Set exposing (Set)
|
||||
import Task
|
||||
@ -14,7 +14,7 @@ import Test.Html.Selector as Selector
|
||||
|
||||
spec : Test
|
||||
spec =
|
||||
describe "Nri.Ui.Accordion.V3"
|
||||
describe "Nri.Ui.Accordion.V4"
|
||||
[ describe "panel rendering" panelRenderingTests
|
||||
, describe "aria attributes" ariaAttributesTests
|
||||
]
|
||||
@ -157,6 +157,7 @@ view model =
|
||||
{ caret = Accordion.defaultCaret
|
||||
, content = \() -> text "Content 1"
|
||||
, entryClass = ""
|
||||
, expansionDirection = Accordion.Downwards
|
||||
, headerContent = text "Header 1"
|
||||
, headerId = "header-1"
|
||||
, headerLevel = Accordion.H4
|
||||
@ -165,9 +166,10 @@ view model =
|
||||
}
|
||||
[]
|
||||
, Accordion.AccordionEntry
|
||||
{ caret = Accordion.defaultCaret
|
||||
{ caret = Accordion.upwardCaret
|
||||
, content = \() -> text "Content 2"
|
||||
, entryClass = ""
|
||||
, expansionDirection = Accordion.Upwards
|
||||
, headerContent = text "Header 2"
|
||||
, headerId = "header-2"
|
||||
, headerLevel = Accordion.H4
|
||||
|
@ -6,6 +6,7 @@
|
||||
"Nri.Test.MouseHelpers.V1",
|
||||
"Nri.Ui",
|
||||
"Nri.Ui.Accordion.V3",
|
||||
"Nri.Ui.Accordion.V4",
|
||||
"Nri.Ui.AnimatedIcon.V1",
|
||||
"Nri.Ui.AssignmentIcon.V2",
|
||||
"Nri.Ui.Balloon.V2",
|
||||
|
Loading…
Reference in New Issue
Block a user