Skip to content

Instantly share code, notes, and snippets.

@mdgriffith
Last active June 30, 2017 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdgriffith/9576c74f85ec779d064de79ebf5973c1 to your computer and use it in GitHub Desktop.
Save mdgriffith/9576c74f85ec779d064de79ebf5973c1 to your computer and use it in GitHub Desktop.
{- It might be nice to have a few "premade" layouts.
These would be semantic elements that have an implied, but specific layout.
-}
footer -- <footer>, always rendered as a `row layout`
sidebar -- <aside> ?, always renderd as a column
navbar -- <nav>, always rendered as a row layout with `justify`?
{-
Form elements could use some love as far as standardizing how they work.
Every form element have the following in common:
- a value (except button)
- placeholder?
- a change event
- a label
- style
- label content
Building in a label for every element would be nice, but also challenging to create an API for.
Lets keep it in mind but not start there.
The standard pattern for form elements could be the following
formElement ChangeMsg style [] value
Which would look like the following:
-}
checkbox Change style [] True
textarea Change style [] "My Text Area!"
inputText Change style [] "Some text"
password Change style [] "superpass"
button Change style [] (text "Button text!")
-- Button's child can be any `el`
-- We can disable the form submit on the button as the default
-- Radio Buttons
type Lunch = Burrito | Taco
radio ChangeRadio RadioStyle []
[ option Burrito (text "A Burrito!")
, option Taco (text "A Taco!")
]
currentlySelected -- : Lunch
-- Do we even need the equivalent of `<select>`. It seems like a weird subclass of a dropdown menu.
type Animal = Manatee | Pangolin | Bee
optionList ChangeSelection SelectStyle []
[ option Manatee (text "Manatees are pretty cool")
, option Pangolin (text "But so are pangolins")
, option Bee (text "Bees")
]
currentlySelected -- : Animal
-- Compared to a standard dropdown
type Animal = Manatee | Pangolin | Bee
el DropDown [] (text "My Animal Menu")
|> below
[ when menu.open <|
radio ChangeSelection Style []
[ option Manatee (text "Manatees are pretty cool")
, option Pangolin (text "But so are pangolins")
, option Bee (text "Bees")
]
currentlySelected -- : Animal
]
{- Labels!
If we have elements like the above, we can use the labeler that's currently in the lib.
-}
label style [] (text "First Name") <|
inputText change style [] "LazerCat"
{- It would be nice to make labels required. I'm not sure what that would look like without making the API nuts though.
-}
{-
As sketched out briefly in this gist: https://gist.github.com/rtfeldman/5b680c64be829c6dbd78c073c269d313
We could have style-elements focus on organizing styles inline as opposed to having a stylesheet.
Technically this is very likely achievable by bubbling up styles and rendering into a stylesheet.
Some points about the inline organization approach:
* Eliminates the situation where a style isn't found because it hasn't been written
* Currently a warning is issued, which is soft protection.
* No longer required to maintain a style type
* An avenue for dynamic styles
* Eliminates `style` and `variation` type variables
* Variations can be done using standard elm machinery
* Resolves weird tensions that occur in some cases (like if you want to set border radius relative to height)
* The "Stylesheet" turns into a set of functions related to creating nice styles (color palettes, scaling fns)
, rather than explicit styles.
The questions I've been thinking about are:
* how does this affect higher level organization?
* how does this affect workflow?
* how does it scale?
Here are some more specific thoughts:
* No higher level organization structure, though is that a problem?
* Is it common to go to a stylesheet and do a bunch of work that _doesn't_ involve the view? Probably not.
* The default is for styles to be fragmented/organized in their own separate functions.
* You then have to work to make sure they're using the same design language.
* Meaning if colors are all defined inline, you may decide later that
"oh, I should have one place to define my color palette"
Then you have to track down all the colors and organize them in a palette after the fact.
Same with fonts, borders, and spacings.
Would you ever not want one place for these? It's much easier to start in an organized fashion.
* This could potentially be addressed by having a strong "best practices" example
and have the elm-style cli generate a "starter kit" via `elm-style new`
* It may be tempting to break out styles into separate functions _even when they're not reusable_.
* Is that a problem?
* My main metric here is "how many levels of indirection are there?"
* In the current library, you start in the view
where all layout info is right in front of you,
and if you need to look up a style you go to
the one place in the stylesheet where that style exists.
* So, what's the workflow for the sketch below?
-}
-- Basic example
logoLink : String -> Elem msg -> Elem msg
logoLink =
link <|
style
[ Color.text (Color.rgb 92 184 92)
, Font.typeface [ "Titillium Web", "sans-serif" ]
, Font.size 16
]
attributionParagraph : List (Elem msg) -> Elem msg
attributionParagraph =
paragraph (style [ Color.text (Color.rgb 187 187 187) ]) []
footerRow : List (Elem msg) -> Elem msg
footerRow =
let
footerStyle =
Style.style
[ Color.background (Color.rgb 243 243 243)
, Font.typeface [ "Source Sans Pro", "sans-serif" ]
, Font.size 12
]
in
Element.footer footerStyle [ verticalCenter, spacing 10, paddingXY 77.5 21 ]
footerLink : String -> Elem msg -> Elem msg
footerLink =
link <|
style
[ Color.text (Color.rgb 92 184 92)
, Font.typeface [ "Titillium Web", "sans-serif" ]
]
plainLink : String -> Elem msg -> Elem msg
plainLink =
link unstyled
viewFooter : Elem msg
viewFooter =
footerRow <|
[ text "conduit" |> logoLink "/"
, attributionParagraph
[ text "An interactive learning project from "
, text "Thinkster" |> footerLink "https://thinkster.io"
, text ". Code & design licensed under MIT."
]
]
-- Compared to the current library
viewFooter2 =
row Footer
[ verticalCenter, spacing 10, paddingXY 77.5 21 ]
[ el Logo [] (text "conduit") |> link "/"
, paragraph Attribution
[]
[ text "An interactive learning project from "
, el Link [] (text "Thinkster") |> link "https://thinkster.io"
, text ". Code & design licensed under MIT."
]
]
{- Currently elements take the following form.
-}
el Style [ --attributes ++ layout ] child
{-
If we move to inline definitions, we might want to move things around.
The first attempt would be to replace the Style identifier with an inline style type.
-}
el (style [Color.text blue]) [--attributes ++ layout] child
{- Or we could add style to the attributes
This keeps things visually separated, simplifies construction, and solves the "unstyled" problem.
The only issue is can we optimize it using the toplevel value trick.
If the style is defined separately, as a top level value, then yes.
-}
el
[ style
[ Color.text blue
, Color.background grey
]
, attributes
, layout
]
child
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment