Last active
April 27, 2020 18:54
-
-
Save cmditch/9b4352cb194928ba45af149ca4684624 to your computer and use it in GitHub Desktop.
elm-ui hacks and utils
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Example of a top level view, with flexbox bug fix, modal support, etc. | |
view : Model -> Browser.Document Msg | |
view model = | |
{ title = pageTitle model | |
, body = | |
[ Element.layoutWith options | |
[ inFront (Dialog.view model.dialog) ] | |
(appView model) | |
-- TODO Remove this fix if elm-ui 1.1.6 fixes the flexbox bug | |
-- see here for why we added this css override | |
-- https://github.com/mdgriffith/elm-ui/issues/147 | |
-- https://github.com/mdgriffith/elm-ui/issues/152 | |
, Html.node "style" [] [ Html.text ".s.c > .s { flex-basis: auto; flex-shrink: 0; }" ] | |
] | |
} | |
options : { options : List Option } | |
options = | |
{ options = [ noFocusStyling ] } | |
{-| Override focus styling across the whole app | |
-} | |
noFocusStyling : Option | |
noFocusStyling = | |
focusStyle | |
{ borderColor = Nothing | |
, backgroundColor = Nothing | |
, shadow = Nothing | |
} | |
-- Fix scrollbar issue on some elements. | |
scrollbarYEl : List (Attribute msg) -> Element msg -> Element msg | |
scrollbarYEl attrs body = | |
el [ height fill, width fill ] <| | |
el | |
([ style "position" "absolute" | |
, style "top" "0" | |
, style "right" "0" | |
, style "bottom" "0" | |
, style "left" "0" | |
, Element.scrollbarY | |
] | |
++ attrs | |
) | |
body | |
-- Really nice helpers | |
class : String -> Attribute msg | |
class = | |
htmlAttribute << Html.Attributes.class | |
id : String -> Attribute msg | |
id = | |
htmlAttribute << Html.Attributes.id | |
attribute : String -> String -> Attribute msg | |
attribute k v = | |
htmlAttribute <| Html.Attributes.attribute k v | |
style : String -> String -> Attribute msg | |
style k v = | |
htmlAttribute <| Html.Attributes.style k v | |
stopPropagationOn : String -> msg -> Attribute msg | |
stopPropagationOn eventName noOpMsg = | |
htmlAttribute <| | |
Html.Events.stopPropagationOn eventName | |
(Decode.succeed ( noOpMsg, True )) | |
preventDefaultOn : String -> msg -> Attribute msg | |
preventDefaultOn eventName noOpMSg = | |
htmlAttribute <| | |
Html.Events.preventDefaultOn eventName | |
(Decode.succeed ( noOpMsg, True )) | |
-- In some views I need to control keyboard interactions very granularly. | |
-- For instance our top level app behavior is to navigate back when `esc` is pressed. | |
-- (btw 'Escape' is only recognized on keydown or keyup events, not keypress) | |
-- But if you're focused in a textfield like our searchbar, esc needs to be handled differently. | |
type alias Event = | |
{ key : String | |
, ctrl : Bool | |
, meta : Bool | |
, shift : Bool | |
} | |
decodeEvent : Decoder Event | |
decodeEvent = | |
Decode.succeed Event | |
|> required "key" string | |
|> required "ctrlKey" bool | |
|> required "metaKey" bool | |
|> required "shiftKey" bool | |
onKeydown : Attribute Msg | |
onKeydown = | |
decodeEvent | |
|> Decode.andThen | |
(\event -> | |
case event.key of | |
"ArrowUp" -> | |
Decode.succeed ItemUp | |
"ArrowDown" -> | |
Decode.succeed ItemDown | |
"Escape" -> | |
Decode.succeed EscPressed | |
"Enter" -> | |
Decode.succeed EnterPressed | |
"Tab" -> | |
Decode.succeed TabPressed | |
"ArrowRight" -> | |
Decode.succeed ArrowRightPressed | |
_ -> | |
Decode.fail "matching keyup not found" | |
) | |
|> Decode.map | |
(\msg -> | |
{ message = msg | |
, stopPropagation = True | |
, preventDefault = True | |
} | |
) | |
|> Html.custom "keyup" | |
|> htmlAttribute |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment