Skip to content

Instantly share code, notes, and snippets.

@escherlies
Last active December 13, 2022 21:57
Show Gist options
  • Save escherlies/b03ae740b6eb2048c108f20fbe2c2b26 to your computer and use it in GitHub Desktop.
Save escherlies/b03ae740b6eb2048c108f20fbe2c2b26 to your computer and use it in GitHub Desktop.
module Context exposing (..)
import Element exposing (Color, Element, el, rgba, text)
import Element.Background
import Element.Font
import UI.Theme exposing (Appereance(..))
{-| Lang Module
-}
type Lang
= De
| En
getTranslation : LangContext ctx -> { a | en : String, de : String } -> String
getTranslation { lang } { en, de } =
case lang of
En ->
en
De ->
de
type alias LangContext a =
{ a | lang : Lang }
{-| Ui Module
-}
type alias UI =
{ colors :
{ foreground : Color
, background : Color
}
}
type alias UiContext a =
{ a | ui : UI }
{-| Another arbitrary context
-}
type alias VersionContext ctx =
{ ctx
| version : Int
}
{-| App context composed of all contexts
-}
type alias Context a =
UiContext (LangContext (VersionContext a))
{-| Get the context from some values of you state
-}
getContext : model -> Context {}
getContext _ =
{ ui =
{ colors =
{ foreground = rgba 0.2 0.2 0.2 1
, background = rgba 0.9 0.9 0.9 1
}
}
, lang = De
, version = 1
}
{-| Now we can precisely describe which context some function needs by composing them
Of course we could just supply Context a but this is not ideal when you thrive for modularity
-}
exampleView : LangContext (UiContext ctx) -> Element msg
exampleView ctx =
el
[ Element.Background.color ctx.ui.colors.background
, Element.Font.color ctx.ui.colors.foreground
]
(text <|
getTranslation ctx
{ en = "Hello, World!"
, de = "Hallo, Welt!"
}
)
{-| Old way with infered type annotations. Hard to extend and refactor
-}
exampleView_old : { a | ui : UI, lang : Lang } -> Element msg
exampleView_old ctx =
el
[ Element.Background.color ctx.ui.colors.background
, Element.Font.color ctx.ui.colors.foreground
]
(text <|
getTranslation ctx
{ en = "Hello, World!"
, de = "Hallo, Welt!"
}
)
-- | You can even interop with the old type
applyContext : Context a -> (Context a -> Element msg) -> Element msg
applyContext ctx fn =
fn ctx
test : Context a -> Element msg
test ctx =
applyContext ctx exampleView_old
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment