noredink-ui/styleguide-app/Examples/Accordion.elm

254 lines
8.5 KiB
Elm
Raw Normal View History

module Examples.Accordion exposing
( example
2020-03-31 22:14:18 +03:00
, State, Msg
)
{-|
2020-03-31 22:14:18 +03:00
@docs example
@docs State, Msg
-}
2020-06-19 23:41:28 +03:00
import AtomicDesignType exposing (AtomicDesignType(..))
2020-09-11 23:13:18 +03:00
import Browser.Dom as Dom
import Category exposing (Category(..))
import Css exposing (..)
2021-05-06 02:03:57 +03:00
import Css.Global
2020-03-31 23:20:03 +03:00
import Example exposing (Example)
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes exposing (css)
import KeyboardSupport exposing (Direction(..), Key(..))
2021-05-06 02:03:57 +03:00
import Nri.Ui.Accordion.V3 as Accordion exposing (AccordionEntry(..))
import Nri.Ui.Colors.Extra as ColorsExtra
import Nri.Ui.Colors.V1 as Colors
2021-05-06 02:03:57 +03:00
import Nri.Ui.DisclosureIndicator.V2 as DisclosureIndicator
2019-10-24 20:32:26 +03:00
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading
2021-05-06 02:03:57 +03:00
import Nri.Ui.Svg.V1 as Svg
2019-10-24 20:32:26 +03:00
import Nri.Ui.Text.V4 as Text
2021-05-06 02:03:57 +03:00
import Nri.Ui.UiIcon.V1 as UiIcon
import Set exposing (Set)
2020-09-11 23:13:18 +03:00
import Task
{-| -}
2020-03-31 23:20:03 +03:00
example : Example State Msg
2020-03-31 22:14:18 +03:00
example =
2020-09-09 21:43:10 +03:00
{ name = "Accordion"
2021-05-06 02:03:57 +03:00
, version = 3
, state = init
, update = update
2020-03-31 22:48:26 +03:00
, subscriptions = \_ -> Sub.none
, view = view
, categories = [ Layout ]
2020-06-20 00:16:10 +03:00
, atomicDesignType = Molecule
2020-09-11 23:13:18 +03:00
, keyboardSupport =
[ { keys = [ Arrow KeyboardSupport.Up ]
, result = "Moves the focus to the previous accordion header button (wraps focus to the last header button)"
}
, { keys = [ Arrow KeyboardSupport.Down ]
, result = "Moves the focus to the next accordion header button (wraps focus to the first header button)"
}
2021-05-06 02:03:57 +03:00
, { keys = [ Arrow KeyboardSupport.Right ]
, result = "Moves the focus to the first accordion header button in a nested list of accordions"
}
, { keys = [ Arrow KeyboardSupport.Left ]
, result = "Moves the focus to the parent accordion header button from a a nested accordion"
}
2020-09-11 23:13:18 +03:00
]
}
{-| -}
view : State -> List (Html Msg)
view model =
2021-05-06 02:03:57 +03:00
let
defaultCaret =
DisclosureIndicator.large [ Css.marginRight (Css.px 8) ]
defaultClass =
"first-accordion-example"
in
[ Heading.h3 [] [ Html.text "Accordion.view" ]
, Accordion.view
{ entries =
2021-05-06 02:03:57 +03:00
[ AccordionEntry
{ caret = defaultCaret
, content = \_ -> Html.text "Content for the first accordion"
, entryClass = defaultClass
, headerContent = Html.text "Default Look"
, headerId = "accordion-entry__1"
, headerLevel = Accordion.H4
, isExpanded = Set.member 1 model
, toggle = Just (Toggle 1)
}
[ AccordionEntry
{ caret = defaultCaret
, content = \_ -> Html.text "Content for the Accordion Child"
, entryClass = defaultClass
, headerContent = Html.text "Accordion Child"
, headerId = "accordion-entry__2"
, headerLevel = Accordion.H5
, isExpanded = Set.member 2 model
, toggle = Just (Toggle 2)
}
[]
]
, AccordionEntry
{ caret =
\isOpen ->
UiIcon.seeMore
|> Svg.withWidth (Css.px 17)
|> Svg.withHeight (Css.px 17)
|> Svg.withCss [ Css.marginRight (Css.px 8) ]
|> Svg.withColor
(if isOpen then
Colors.azureDark
else
Colors.azure
)
|> Svg.toHtml
, content = \_ -> Html.text "Content for the third accordion"
, entryClass = defaultClass
, headerContent = Html.text "Custom Carets!"
, headerId = "accordion-entry__3"
, headerLevel = Accordion.H4
, isExpanded = Set.member 3 model
, toggle = Just (Toggle 3)
}
[]
, AccordionEntry
{ caret =
\_ ->
UiIcon.null
|> Svg.withWidth (Css.px 17)
|> Svg.withHeight (Css.px 17)
|> Svg.withCss [ Css.marginRight (Css.px 8) ]
|> Svg.withColor Colors.gray85
|> Svg.toHtml
, content = \_ -> Html.text "Content for the fourth accordion"
, entryClass = defaultClass
, headerContent = Html.text "This accordion can't be opened."
, headerId = "accordion-entry__4"
, headerLevel = Accordion.H5
, isExpanded = Set.member 4 model
, toggle = Nothing
}
[]
, AccordionEntry
{ caret =
\_ ->
UiIcon.null
|> Svg.withWidth (Css.px 17)
|> Svg.withHeight (Css.px 17)
|> Svg.withCss [ Css.marginRight (Css.px 8) ]
|> Svg.withColor Colors.gray85
|> Svg.toHtml
, content = \_ -> Html.text "Content for the fifth accordion"
, entryClass = defaultClass
, headerContent = Html.text "This accordion can't be closed."
, headerId = "accordion-entry__5"
, headerLevel = Accordion.H5
, isExpanded = True
, toggle = Nothing
}
[]
, AccordionEntry
{ caret = defaultCaret
, content =
\_ ->
Html.div
[ css
[ Css.backgroundColor Colors.gray92
, Css.minHeight (Css.vh 100)
, Css.padding (Css.px 20)
]
]
[ Html.text "Content for the accordion"
]
, entryClass = "fixed-positioning-accordion-example"
, headerContent = Html.text "Fixed Position Example: Expand & Scroll!"
, headerId = "accordion-entry__6"
, headerLevel = Accordion.H4
, isExpanded = Set.member 6 model
, toggle = Just (Toggle 6)
}
[]
]
2020-09-11 23:13:18 +03:00
, focus = Focus
}
2021-05-06 02:03:57 +03:00
, Accordion.styleAccordion
{ entryStyles =
[ Css.marginLeft (Css.px 16)
, Css.Global.withClass "fixed-positioning-accordion-example"
[ Css.position Css.relative
]
]
2021-05-06 02:03:57 +03:00
, entryExpandedStyles =
[ Css.Global.withClass "fixed-positioning-accordion-example"
[ Css.Global.children
[ Css.Global.h4
[ Css.position Css.sticky
, Css.property "position" "-webkit-sticky"
, Css.top (Css.px -8)
]
2021-05-06 02:03:57 +03:00
]
]
]
, entryClosedStyles = []
, headerStyles =
[ Css.Global.withClass "fixed-positioning-accordion-example"
[ Css.padding (Css.px 20)
]
]
, headerExpandedStyles =
[ Css.Global.withClass "fixed-positioning-accordion-example"
[ Css.backgroundColor Colors.gray96
, Css.borderRadius (Css.px 8)
, Css.boxShadow5 Css.zero Css.zero (px 10) zero (ColorsExtra.withAlpha 0.2 Colors.gray20)
]
]
, headerClosedStyles = []
, contentStyles = []
}
]
type Msg
= Toggle Int Bool
2020-09-11 23:13:18 +03:00
| Focus String
| Focused (Result Dom.Error ())
{-| -}
init : State
init =
2021-05-06 02:03:57 +03:00
Set.empty
{-| -}
type alias State =
2021-05-06 02:03:57 +03:00
Set Int
{-| -}
update : Msg -> State -> ( State, Cmd Msg )
2020-09-11 23:13:18 +03:00
update msg model =
case msg of
2021-05-06 02:03:57 +03:00
Toggle id expand ->
( if expand then
Set.insert id model
else
Set.remove id model
, Cmd.none
)
2020-09-11 23:13:18 +03:00
Focus id ->
( model, Task.attempt Focused (Dom.focus id) )
Focused _ ->
( model, Cmd.none )