2019-10-24 20:23:19 +03:00
|
|
|
module Examples.Accordion exposing
|
|
|
|
( example
|
2020-03-31 22:14:18 +03:00
|
|
|
, State, Msg
|
2019-10-24 20:23:19 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
{-|
|
|
|
|
|
2020-03-31 22:14:18 +03:00
|
|
|
@docs example
|
|
|
|
@docs State, Msg
|
2019-10-24 20:23:19 +03:00
|
|
|
|
|
|
|
-}
|
|
|
|
|
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
|
2020-03-24 03:33:42 +03:00
|
|
|
import Category exposing (Category(..))
|
2019-10-24 20:23:19 +03:00
|
|
|
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)
|
2020-03-31 21:31:14 +03:00
|
|
|
import Html.Styled as Html exposing (Html)
|
2019-10-24 20:23:19 +03:00
|
|
|
import Html.Styled.Attributes exposing (css)
|
2020-06-20 00:45:32 +03:00
|
|
|
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
|
2019-10-24 20:23:19 +03:00
|
|
|
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
|
2019-10-24 20:23:19 +03:00
|
|
|
|
|
|
|
|
|
|
|
{-| -}
|
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
|
2020-03-31 21:31:14 +03:00
|
|
|
, state = init
|
|
|
|
, update = update
|
2020-03-31 22:48:26 +03:00
|
|
|
, subscriptions = \_ -> Sub.none
|
2020-03-31 21:31:14 +03:00
|
|
|
, 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
|
|
|
]
|
2020-03-31 21:31:14 +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" ]
|
2020-03-31 21:31:14 +03:00
|
|
|
, 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-03-31 21:31:14 +03:00
|
|
|
]
|
2020-09-11 23:13:18 +03:00
|
|
|
, focus = Focus
|
2020-03-31 21:31:14 +03:00
|
|
|
}
|
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
|
|
|
|
]
|
2020-03-31 21:31:14 +03:00
|
|
|
]
|
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)
|
2020-03-31 21:31:14 +03:00
|
|
|
]
|
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 = []
|
2020-03-31 21:31:14 +03:00
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
|
2019-10-24 20:23:19 +03:00
|
|
|
type Msg
|
|
|
|
= Toggle Int Bool
|
2020-09-11 23:13:18 +03:00
|
|
|
| Focus String
|
|
|
|
| Focused (Result Dom.Error ())
|
2019-10-24 20:23:19 +03:00
|
|
|
|
|
|
|
|
|
|
|
{-| -}
|
|
|
|
init : State
|
|
|
|
init =
|
2021-05-06 02:03:57 +03:00
|
|
|
Set.empty
|
2019-10-24 20:23:19 +03:00
|
|
|
|
|
|
|
|
|
|
|
{-| -}
|
|
|
|
type alias State =
|
2021-05-06 02:03:57 +03:00
|
|
|
Set Int
|
2019-10-24 20:23:19 +03:00
|
|
|
|
|
|
|
|
|
|
|
{-| -}
|
2020-03-31 21:31:14 +03:00
|
|
|
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 )
|