Move css sidenav customization to a list of attributes

This commit is contained in:
Tessa Kelly 2022-03-29 12:38:39 -07:00
parent b1a218c63d
commit e20d53d853
2 changed files with 101 additions and 34 deletions

View File

@ -1,5 +1,6 @@
module Nri.Ui.SideNav.V3 exposing module Nri.Ui.SideNav.V3 exposing
( view, Config ( view, Config, NavAttribute
, navCss, navNotMobileCss, navMobileCss, navQuizEngineMobileCss
, entry, entryWithChildren, html, Entry, Attribute , entry, entryWithChildren, html, Entry, Attribute
, icon, custom, css, nriDescription, testId, id , icon, custom, css, nriDescription, testId, id
, onClick , onClick
@ -10,7 +11,17 @@ module Nri.Ui.SideNav.V3 exposing
{-| {-|
@docs view, Config
# Changes from V1
- change to `NavAttribute` list-based API
@docs view, Config, NavAttribute
@docs navCss, navNotMobileCss, navMobileCss, navQuizEngineMobileCss
## Entries
@docs entry, entryWithChildren, html, Entry, Attribute @docs entry, entryWithChildren, html, Entry, Attribute
@docs icon, custom, css, nriDescription, testId, id @docs icon, custom, css, nriDescription, testId, id
@ -36,6 +47,7 @@ import Accessibility.Styled exposing (..)
import Accessibility.Styled.Style as Style import Accessibility.Styled.Style as Style
import ClickableAttributes exposing (ClickableAttributes) import ClickableAttributes exposing (ClickableAttributes)
import Css exposing (..) import Css exposing (..)
import Css.Media exposing (MediaQuery)
import Html.Styled import Html.Styled
import Html.Styled.Attributes as Attributes import Html.Styled.Attributes as Attributes
import Html.Styled.Events as Events import Html.Styled.Events as Events
@ -46,6 +58,7 @@ import Nri.Ui.Data.PremiumDisplay as PremiumDisplay exposing (PremiumDisplay)
import Nri.Ui.Fonts.V1 as Fonts import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Html.Attributes.V2 as ExtraAttributes import Nri.Ui.Html.Attributes.V2 as ExtraAttributes
import Nri.Ui.Html.V3 exposing (viewJust) import Nri.Ui.Html.V3 exposing (viewJust)
import Nri.Ui.MediaQuery.V1 as MediaQuery
import Nri.Ui.Svg.V1 as Svg exposing (Svg) import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Nri.Ui.UiIcon.V1 as UiIcon import Nri.Ui.UiIcon.V1 as UiIcon
@ -84,22 +97,75 @@ type alias Config route msg =
{ isCurrentRoute : route -> Bool { isCurrentRoute : route -> Bool
, routeToString : route -> String , routeToString : route -> String
, onSkipNav : msg , onSkipNav : msg
, css : List Style
} }
{-| -} {-| -}
view : Config route msg -> List (Entry route msg) -> Html msg type NavAttribute
view config entries = = NavAttribute (NavAttributeConfig -> NavAttributeConfig)
styled nav
type alias NavAttributeConfig =
{ css : List Style
}
defaultNavAttributeConfig : NavAttributeConfig
defaultNavAttributeConfig =
{ css =
[ flexBasis (px 250) [ flexBasis (px 250)
, flexShrink (num 0) , flexShrink (num 0)
, borderRadius (px 8) , borderRadius (px 8)
, backgroundColor Colors.gray96 , backgroundColor Colors.gray96
, padding (px 20) , padding (px 20)
, marginRight (px 20) , marginRight (px 20)
, batch config.css
] ]
}
{-| These styles are included automatically in the nav container:
[ flexBasis (px 250)
, flexShrink (num 0)
, borderRadius (px 8)
, backgroundColor Colors.gray96
, padding (px 20)
, marginRight (px 20)
]
-}
navCss : List Style -> NavAttribute
navCss styles =
NavAttribute (\config -> { config | css = List.append config.css styles })
{-| -}
navNotMobileCss : List Style -> NavAttribute
navNotMobileCss styles =
navCss [ Css.Media.withMedia [ MediaQuery.notMobile ] styles ]
{-| -}
navMobileCss : List Style -> NavAttribute
navMobileCss styles =
navCss [ Css.Media.withMedia [ MediaQuery.mobile ] styles ]
{-| -}
navQuizEngineMobileCss : List Style -> NavAttribute
navQuizEngineMobileCss styles =
navCss [ Css.Media.withMedia [ MediaQuery.quizEngineMobile ] styles ]
{-| -}
view : Config route msg -> List NavAttribute -> List (Entry route msg) -> Html msg
view config navAttributes entries =
let
appliedNavAttributes =
List.foldl (\(NavAttribute f) b -> f b) defaultNavAttributeConfig navAttributes
in
styled nav
appliedNavAttributes.css
[] []
(viewSkipLink config.onSkipNav (viewSkipLink config.onSkipNav
:: List.map (viewSidebarEntry config []) entries :: List.map (viewSidebarEntry config []) entries

View File

@ -12,7 +12,7 @@ import CommonControls
import Css import Css
import Debug.Control as Control exposing (Control) import Debug.Control as Control exposing (Control)
import Debug.Control.Extra as ControlExtra import Debug.Control.Extra as ControlExtra
import Debug.Control.View as ControlView import Debug.Control.View as ControlView exposing (codeFromList)
import EllieLink import EllieLink
import Example exposing (Example) import Example exposing (Example)
import Html.Styled.Attributes exposing (css) import Html.Styled.Attributes exposing (css)
@ -89,7 +89,7 @@ view ellieLinkConfig state =
, update = SetControls , update = SetControls
, settings = state.settings , settings = state.settings
, toExampleCode = , toExampleCode =
\{ entries } -> \{ navAttributes, entries } ->
[ { sectionName = "View" [ { sectionName = "View"
, code = , code =
String.join "" String.join ""
@ -97,11 +97,9 @@ view ellieLinkConfig state =
, "\n\t{ isCurrentRoute = (==) \"" ++ settings.currentRoute ++ "\"" , "\n\t{ isCurrentRoute = (==) \"" ++ settings.currentRoute ++ "\""
, "\n\t, routeToString = identity" , "\n\t, routeToString = identity"
, "\n\t, onSkipNav = SkipToContent" , "\n\t, onSkipNav = SkipToContent"
, "\n\t, css = " ++ Tuple.first settings.css
, "\n\t}" , "\n\t}"
, "\n\t[ " , codeFromList navAttributes
, String.join "\n\t" (List.map Tuple.first entries) , codeFromList entries
, "\n\t]"
] ]
} }
] ]
@ -110,8 +108,8 @@ view ellieLinkConfig state =
{ isCurrentRoute = (==) settings.currentRoute { isCurrentRoute = (==) settings.currentRoute
, routeToString = identity , routeToString = identity
, onSkipNav = SkipToContent , onSkipNav = SkipToContent
, css = Tuple.second settings.css
} }
(List.map Tuple.second settings.navAttributes)
(List.map Tuple.second settings.entries) (List.map Tuple.second settings.entries)
] ]
@ -124,7 +122,7 @@ type alias State =
type alias Settings = type alias Settings =
{ currentRoute : String { currentRoute : String
, css : ( String, List Css.Style ) , navAttributes : List ( String, SideNav.NavAttribute )
, entries : List ( String, SideNav.Entry String Msg ) , entries : List ( String, SideNav.Entry String Msg )
} }
@ -135,27 +133,30 @@ init =
{ settings = { settings =
Control.record Settings Control.record Settings
|> Control.field "currentRoute" (Control.string "#some-route") |> Control.field "currentRoute" (Control.string "#some-route")
|> Control.field "css" |> Control.field "navAttributes" controlNavAttributes
(Control.maybe True |> Control.field "entries" (Control.map List.singleton (controlEntryType "#some-route"))
}
controlNavAttributes : Control (List ( String, SideNav.NavAttribute ))
controlNavAttributes =
ControlExtra.list
|> ControlExtra.optionalListItem "navCss"
(Control.choice (Control.choice
[ ( "maxWidth" [ ( "maxWidth"
, Control.value , Control.value
( "[ Css.maxWidth (Css.px 300) ]" ( "SideNav.navCss [ Css.maxWidth (Css.px 300) ]"
, [ Css.maxWidth (Css.px 300) ] , SideNav.navCss [ Css.maxWidth (Css.px 300) ]
) )
) )
, ( "purple border" , ( "purple border"
, Control.value , Control.value
( "[ Css.border3 (Css.px 3) Css.dotted Colors.purple ]" ( "SideNav.navCss [ Css.border3 (Css.px 3) Css.dotted Colors.purple ]"
, [ Css.border3 (Css.px 3) Css.dotted Colors.purple ] , SideNav.navCss [ Css.border3 (Css.px 3) Css.dotted Colors.purple ]
) )
) )
] ]
) )
|> Control.map (Maybe.withDefault ( "[]", [] ))
)
|> Control.field "entries" (Control.map List.singleton (controlEntryType "#some-route"))
}
controlEntryType : String -> Control ( String, SideNav.Entry String Msg ) controlEntryType : String -> Control ( String, SideNav.Entry String Msg )