Modified Components declaration of Props.
Props are now added using add(...) functions in a Monad block, and the Html is "return"ed.
This commit is contained in:
parent
454b7f48f0
commit
4a900ab57c
12 changed files with 79 additions and 66 deletions
|
@ -4,6 +4,9 @@ module Components
|
|||
, Component(..)
|
||||
, new
|
||||
, (<.>)
|
||||
, addCss
|
||||
, addAsset
|
||||
, addAsset'
|
||||
, getHtml
|
||||
, getCss
|
||||
) where
|
||||
|
@ -14,10 +17,10 @@ import Clay ( Css
|
|||
)
|
||||
import Core.Writer
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Set as Set
|
||||
import Data.Text.Lazy ( unpack )
|
||||
import Routes
|
||||
import Text.Blaze.Html
|
||||
import Text.Blaze.Html.Renderer.String
|
||||
import Text.Blaze.Html5 ( Html )
|
||||
import Utils.FileTree
|
||||
|
||||
-- |Props are data on top of a component's html. They are aggregated when components are combined. The choice of structures for Prop ensures that there is no duplicate at compile time (e.g. the css of a button used 5 times is only rendered once.)
|
||||
|
@ -27,33 +30,36 @@ data Prop = Prop
|
|||
}
|
||||
|
||||
instance Semigroup Prop where
|
||||
p1 <> p2 =
|
||||
Prop (Map.union (cssMap p1) (cssMap p2)) (assetsTree p1 <> assetsTree p2)
|
||||
p1 <> p2 = Prop { cssMap = Map.union (cssMap p1) (cssMap p2)
|
||||
, assetsTree = assetsTree p1 <> assetsTree p2
|
||||
}
|
||||
|
||||
instance Monoid Prop where
|
||||
mempty = Prop Map.empty mempty
|
||||
|
||||
-- |Construct a Prop with a name, css.
|
||||
prop :: String -> Css -> Prop
|
||||
prop name css = Prop (Map.singleton name css)
|
||||
|
||||
type Component = Writer Prop
|
||||
|
||||
prop :: String -> Css -> Prop
|
||||
prop name css = Prop (Map.singleton name css) mempty
|
||||
-- |Add a name and css to a Prop.
|
||||
addCss :: String -> Css -> Component ()
|
||||
addCss name css = tell $ Prop (Map.singleton name css) mempty
|
||||
|
||||
-- |Add an asset to the Prop's tree.
|
||||
addAsset :: FilePath -> Component ()
|
||||
addAsset fp = tell $ Prop Map.empty (build fp)
|
||||
|
||||
addAsset' :: Route -> Component ()
|
||||
addAsset' r = tell $ Prop Map.empty (build' r)
|
||||
|
||||
-- |Get a Component's Html
|
||||
getHtml :: Component Html -> Html
|
||||
getHtml = fst . runWriter
|
||||
---- |Return a Component's Css as a String
|
||||
--toCss :: Component a -> String
|
||||
--toCss =
|
||||
-- unpack
|
||||
-- . renderWith compact []
|
||||
-- . mconcat
|
||||
-- . map snd
|
||||
-- . Map.toList
|
||||
-- . cssMap
|
||||
-- . snd
|
||||
-- . runWriter
|
||||
|
||||
-- |Get a Component's Css
|
||||
getCss :: Component a -> Css
|
||||
getCss = mconcat . map snd . Map.toList . cssMap . snd . runWriter
|
||||
|
||||
-- |Get a Component's assets tree
|
||||
getFileTree :: Component a -> FileTree
|
||||
getFileTree = assetsTree . snd . runWriter
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
module Core.Writer
|
||||
( Writer
|
||||
, tell
|
||||
, runWriter
|
||||
, new
|
||||
, (<.>)
|
||||
|
|
|
@ -13,5 +13,7 @@ css = C.button ? do
|
|||
color white
|
||||
fontWeight bold
|
||||
|
||||
buttonWithText :: Html -> Component Html
|
||||
buttonWithText = new (prop "buttonWithText" css) . H.button
|
||||
buttonWithText :: Component (Html -> Html)
|
||||
buttonWithText = do
|
||||
addCss "buttonWithText" css
|
||||
return H.button
|
||||
|
|
|
@ -31,5 +31,7 @@ css = C.a # byClass "button" ? do
|
|||
color (grays @ 100)
|
||||
backgroundColor (grays @ 70)
|
||||
|
||||
buttonLink :: Route -> Html -> Component Html
|
||||
buttonLink ref = new (prop "buttonLink" css) . buttonLinkHtml ref
|
||||
buttonLink :: Route -> Component (Html -> Html)
|
||||
buttonLink ref = do
|
||||
addCss "buttonLink" css
|
||||
return $ buttonLinkHtml ref
|
||||
|
|
|
@ -13,4 +13,6 @@ css = element ".container" ? do
|
|||
marginLeft <> marginRight $ auto
|
||||
|
||||
container :: Component (Html -> Html)
|
||||
container = new (prop "container" css) $ H.div H.! class_ "container"
|
||||
container = do
|
||||
addCss "container" css
|
||||
return $ H.div H.! class_ "container"
|
||||
|
|
|
@ -20,4 +20,6 @@ css = C.header ? do
|
|||
|
||||
|
||||
header' :: Component (Html -> Html)
|
||||
header' = new (prop "header" css) H.header
|
||||
header' = do
|
||||
addCss "header" css
|
||||
return H.header
|
||||
|
|
|
@ -19,38 +19,32 @@ baseCss = C.img ? do
|
|||
maxWidth (pct 100)
|
||||
|
||||
img' :: FilePath -> String -> Component Html
|
||||
img' file description =
|
||||
new (prop "img" baseCss)
|
||||
$ H.img
|
||||
H.! A.src (stringValue . path . Img $ file)
|
||||
H.! A.alt (stringValue description)
|
||||
img' file description = do
|
||||
addCss "img" baseCss
|
||||
addAsset' $ Img file
|
||||
return $ H.img H.! A.src (stringValue . path . Img $ file) H.! A.alt
|
||||
(stringValue description)
|
||||
|
||||
|
||||
imgWithShape :: Shape -> FilePath -> String -> Component Html
|
||||
imgWithShape Square file description = img' file description
|
||||
imgWithShape Circle file description =
|
||||
new
|
||||
(prop "img circle"
|
||||
(C.img # byClass "circle" ? uniform borderRadius (pct 50))
|
||||
)
|
||||
(H.! class_ "circle")
|
||||
<*> img' file description
|
||||
do
|
||||
addCss "img circle"
|
||||
(C.img # byClass "circle" ? uniform borderRadius (pct 50))
|
||||
return (H.! class_ "circle")
|
||||
<*> img' file description
|
||||
imgWithShape Rounded file description =
|
||||
new
|
||||
(prop "img rounded"
|
||||
(C.img # byClass "rounded" ? uniform borderRadius (pct 10))
|
||||
)
|
||||
(H.! class_ "rounded")
|
||||
<*> img' file description
|
||||
do
|
||||
addCss "img rounded"
|
||||
(C.img # byClass "rounded" ? uniform borderRadius (pct 10))
|
||||
return (H.! class_ "rounded")
|
||||
<*> img' file description
|
||||
imgWithShape Drop file description =
|
||||
new
|
||||
(prop
|
||||
"img drop"
|
||||
(C.img # byClass "drop" ? borderRadius (pct 50)
|
||||
(pct 50)
|
||||
(pct 50)
|
||||
(pct 10)
|
||||
)
|
||||
do
|
||||
addCss
|
||||
"img drop"
|
||||
(C.img # byClass "drop" ? borderRadius (pct 50) (pct 50) (pct 50) (pct 10)
|
||||
)
|
||||
(H.! class_ "drop")
|
||||
<*> img' file description
|
||||
return (H.! class_ "drop")
|
||||
<*> img' file description
|
||||
|
|
|
@ -9,8 +9,6 @@ import Text.Blaze.Html5
|
|||
import Text.Blaze.Html5.Attributes
|
||||
|
||||
stylesheet :: Route -> Css -> Component Html
|
||||
stylesheet route css =
|
||||
new (prop (path route) css)
|
||||
$ link
|
||||
! rel "stylesheet"
|
||||
! (href . stringValue . path $ route)
|
||||
stylesheet route css = do
|
||||
addCss (path route) css
|
||||
return $ link ! rel "stylesheet" ! (href . stringValue . path $ route)
|
||||
|
|
|
@ -20,6 +20,6 @@ css = byClass "profile-bio" & do
|
|||
C.width (C.em 20)
|
||||
|
||||
profileBio :: String -> Component Html
|
||||
profileBio bio =
|
||||
new (prop "profileBio" css) $ H.div H.! class_ "profile-bio" $ H.p
|
||||
(toHtml bio)
|
||||
profileBio bio = do
|
||||
addCss "profileBio" css
|
||||
return $ H.div H.! class_ "profile-bio" $ H.p (toHtml bio)
|
||||
|
|
|
@ -16,8 +16,9 @@ css = byClass "profile-content" & do
|
|||
borderLeft (px 10) solid $ secondary @ 50
|
||||
|
||||
profileContent :: String -> String -> Component Html
|
||||
profileContent auth desc =
|
||||
new (prop "profileContent" css)
|
||||
profileContent auth desc = do
|
||||
addCss "profileContent" css
|
||||
return
|
||||
$ H.div
|
||||
H.! class_ "profile-content"
|
||||
$ H.hgroup
|
||||
|
|
|
@ -21,5 +21,7 @@ css = byClass "profile-pic" & do
|
|||
|
||||
profilePic :: FilePath -> String -> Component Html
|
||||
profilePic file altText =
|
||||
new (prop "profilePic" css) (H.div H.! class_ "profile-pic")
|
||||
<*> imgWithShape Rounded file altText
|
||||
do
|
||||
addCss "profilePic" css
|
||||
return $ H.div H.! class_ "profile-pic"
|
||||
<*> imgWithShape Rounded file altText
|
||||
|
|
|
@ -15,8 +15,11 @@ import Text.Blaze.Html5 as H
|
|||
import Text.Blaze.Html5.Attributes as A
|
||||
|
||||
indexBody :: Component Html
|
||||
indexBody =
|
||||
mconcat [profileHeader, buttonWithText "Click!", buttonLink Blog "All posts"]
|
||||
indexBody = mconcat
|
||||
[ profileHeader
|
||||
, buttonWithText <*> pure "Click!"
|
||||
, buttonLink Blog <*> pure "All posts"
|
||||
]
|
||||
|
||||
indexTemplate :: Component Html
|
||||
indexTemplate =
|
||||
|
|
Loading…
Reference in a new issue