Blog cards first design. Organisms that take a PostProp ADT for their
content. TODO: tweak the desing (font sizes, lineHeights), decide how to make the summary from a blog post (description metadata or first N chars?)
This commit is contained in:
parent
aec350eaf9
commit
5549461f4c
11 changed files with 210 additions and 12 deletions
|
@ -33,15 +33,21 @@ library
|
|||
Kit.Atoms.Fonts
|
||||
Kit.Atoms.Header
|
||||
Kit.Atoms.Image
|
||||
Kit.Atoms.Link
|
||||
Kit.Atoms.Section
|
||||
Kit.Atoms.Stylesheet
|
||||
Kit.Atoms.Typography
|
||||
Kit.Constants.Breakpoints
|
||||
Kit.Constants.Colors
|
||||
Kit.Constants.Spacing
|
||||
Kit.Molecules.CardBody
|
||||
Kit.Molecules.CardFooter
|
||||
Kit.Molecules.CardHeader
|
||||
Kit.Molecules.DefaultCss
|
||||
Kit.Molecules.ProfileBio
|
||||
Kit.Molecules.ProfileContent
|
||||
Kit.Molecules.ProfilePic
|
||||
Kit.Organisms.Card
|
||||
Kit.Organisms.Head
|
||||
Kit.Organisms.ProfileHeader
|
||||
Kit.Templates.Index
|
||||
|
|
24
src/Kit/Atoms/Link.hs
Normal file
24
src/Kit/Atoms/Link.hs
Normal file
|
@ -0,0 +1,24 @@
|
|||
module Kit.Atoms.Link
|
||||
( a'
|
||||
) where
|
||||
|
||||
import Clay as C
|
||||
import Components
|
||||
import Kit.Constants.Colors
|
||||
import Routes
|
||||
import Text.Blaze.Html5 as H
|
||||
import Text.Blaze.Html5.Attributes as A
|
||||
|
||||
css :: Css
|
||||
css = C.a ? do
|
||||
color $ secondary @ 50
|
||||
textDecoration none
|
||||
transition "all" (sec 0.4) easeInOut (sec 0)
|
||||
hover & do
|
||||
textDecoration underline
|
||||
color $ secondary @ 40
|
||||
|
||||
a' :: Route -> Component (Html -> Html)
|
||||
a' ref = do
|
||||
addCss "link" css
|
||||
return $ H.a H.! A.href (stringValue . path $ ref)
|
28
src/Kit/Atoms/Section.hs
Normal file
28
src/Kit/Atoms/Section.hs
Normal file
|
@ -0,0 +1,28 @@
|
|||
module Kit.Atoms.Section
|
||||
( section'
|
||||
) where
|
||||
|
||||
import Clay as C
|
||||
import Components
|
||||
import Kit.Atoms.Container
|
||||
import Kit.Constants.Colors
|
||||
import Kit.Constants.Spacing
|
||||
import Text.Blaze.Html5 as H
|
||||
import Text.Blaze.Html5.Attributes as A
|
||||
import Utils.Clay
|
||||
|
||||
css :: Css
|
||||
css = do
|
||||
C.section ? do
|
||||
paddingTop <> paddingBottom $ giant
|
||||
element ".section-inner" ? do
|
||||
uniform padding huge
|
||||
backgroundColor $ grays @ 100
|
||||
|
||||
section' :: Component (Html -> Html)
|
||||
section' =
|
||||
do
|
||||
addCss "section" css
|
||||
return $ H.section
|
||||
<.> container
|
||||
<.> pure (H.div H.! class_ "section-inner")
|
|
@ -10,6 +10,7 @@ module Kit.Constants.Spacing
|
|||
, regular
|
||||
, large
|
||||
, huge
|
||||
, giant
|
||||
) where
|
||||
|
||||
import Clay.Size
|
||||
|
@ -39,3 +40,4 @@ small = ex 0.5
|
|||
regular = ex 1
|
||||
large = ex 2
|
||||
huge = ex 4
|
||||
giant = ex 8
|
||||
|
|
14
src/Kit/Molecules/CardBody.hs
Normal file
14
src/Kit/Molecules/CardBody.hs
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Kit.Molecules.CardBody
|
||||
( cardBody
|
||||
) where
|
||||
|
||||
import Clay as C
|
||||
import Components
|
||||
import Routes
|
||||
import Text.Blaze.Html5 as H
|
||||
import Text.Blaze.Html5.Attributes as A
|
||||
|
||||
cardBody :: Component (Html -> Html)
|
||||
cardBody = do
|
||||
addCss "CardBody" (element ".card-body" ? C.width (pct 100))
|
||||
return $ H.div H.! class_ "card-body"
|
23
src/Kit/Molecules/CardFooter.hs
Normal file
23
src/Kit/Molecules/CardFooter.hs
Normal file
|
@ -0,0 +1,23 @@
|
|||
module Kit.Molecules.CardFooter
|
||||
( cardFooter
|
||||
) where
|
||||
|
||||
import Clay as C
|
||||
import Components
|
||||
import Kit.Constants.Colors
|
||||
import Kit.Constants.Spacing as S
|
||||
import Text.Blaze.Html5 as H
|
||||
import Text.Blaze.Html5.Attributes as A
|
||||
|
||||
css :: Css
|
||||
css = element ".card-footer" ? do
|
||||
backgroundColor $ grays @ 75
|
||||
C.width (pct 100)
|
||||
marginTop auto
|
||||
fontSize fontXS
|
||||
color $ grays @ 50
|
||||
|
||||
cardFooter :: Component (Html -> Html)
|
||||
cardFooter = do
|
||||
addCss "CardFooter" css
|
||||
return $ (H.div H.! class_ "card-footer") . H.p
|
27
src/Kit/Molecules/CardHeader.hs
Normal file
27
src/Kit/Molecules/CardHeader.hs
Normal file
|
@ -0,0 +1,27 @@
|
|||
module Kit.Molecules.CardHeader
|
||||
( cardHeader
|
||||
) where
|
||||
|
||||
import Clay as C
|
||||
import Components
|
||||
import Kit.Atoms.Link
|
||||
import Kit.Constants.Spacing as S
|
||||
import Routes
|
||||
import Text.Blaze.Html5 as H
|
||||
import Text.Blaze.Html5.Attributes as A
|
||||
|
||||
css :: Css
|
||||
css = element ".card-header" ? do
|
||||
C.width (pct 100)
|
||||
textAlign center
|
||||
C.a ? do
|
||||
fontWeight bold
|
||||
fontSize S.fontM
|
||||
marginTop <> marginBottom $ S.large
|
||||
|
||||
cardHeader :: Route -> Component (Html -> Html)
|
||||
cardHeader route =
|
||||
do
|
||||
addCss "CardHeader" css
|
||||
return $ H.div H.! class_ "card-header"
|
||||
<.> a' route
|
|
@ -9,7 +9,8 @@ import Kit.Atoms.Stylesheet
|
|||
import Kit.Atoms.Typography
|
||||
import Kit.Constants.Colors
|
||||
import Routes
|
||||
import Text.Blaze.Html5 ( Html )
|
||||
import Text.Blaze.Html
|
||||
import Utils.Clay
|
||||
|
||||
css :: Css
|
||||
css = do
|
||||
|
@ -17,7 +18,8 @@ css = do
|
|||
defaultFontStyle
|
||||
color (primary @ 10)
|
||||
backgroundColor (primary @ 45)
|
||||
C.body ? margin nil nil nil nil
|
||||
C.body ? do
|
||||
uniform margin nil
|
||||
headings
|
||||
|
||||
defaultCss :: Component Html
|
||||
|
|
55
src/Kit/Organisms/Card.hs
Normal file
55
src/Kit/Organisms/Card.hs
Normal file
|
@ -0,0 +1,55 @@
|
|||
module Kit.Organisms.Card
|
||||
( PostProp(..)
|
||||
, blogCard
|
||||
) where
|
||||
|
||||
import Clay as C
|
||||
import Components
|
||||
import Kit.Atoms.ButtonLink
|
||||
import Kit.Constants.Colors
|
||||
import Kit.Constants.Spacing as S
|
||||
import Kit.Molecules.CardBody
|
||||
import Kit.Molecules.CardFooter
|
||||
import Kit.Molecules.CardHeader
|
||||
import Routes
|
||||
import Text.Blaze.Html5 as H
|
||||
import Text.Blaze.Html5.Attributes as A
|
||||
import Utils.Clay
|
||||
|
||||
data PostProp = PostProp
|
||||
{ postRoute :: Route
|
||||
, postTitle :: Html
|
||||
, postSummary :: Html
|
||||
, postDate :: Html
|
||||
}
|
||||
|
||||
css :: Css
|
||||
css = C.article # byClass "card" ? do
|
||||
C.width (pct 100)
|
||||
display flex
|
||||
flexDirection column
|
||||
alignItems flexStart
|
||||
overflow scroll
|
||||
uniform margin regular
|
||||
boxShadow . pure $ bsColor (grays @ 80) $ shadowWithSpread nil nil (px 3) nil
|
||||
hover & do
|
||||
boxShadow . pure $ bsColor (grays @ 80) $ shadowWithSpread nil
|
||||
nil
|
||||
(px 30)
|
||||
nil
|
||||
|
||||
blogCard :: PostProp -> Component Html
|
||||
blogCard prop =
|
||||
do
|
||||
addCss "blogCard" css
|
||||
return $ H.article H.! class_ "card"
|
||||
<*> mconcat
|
||||
[ cardHeader (postRoute prop) <*> pure (postTitle prop)
|
||||
, cardBody
|
||||
<*> ( pure (postSummary prop)
|
||||
<> ( pure (H.div H.! A.style "text-align: center")
|
||||
<*> (buttonLink (postRoute prop) <*> pure "More")
|
||||
)
|
||||
)
|
||||
, cardFooter <*> pure (postDate prop)
|
||||
]
|
|
@ -7,6 +7,8 @@ import Components
|
|||
import Core.Render
|
||||
import Kit.Atoms.Button
|
||||
import Kit.Atoms.ButtonLink
|
||||
import Kit.Atoms.Section
|
||||
import Kit.Organisms.Card
|
||||
import Kit.Organisms.Head
|
||||
import Kit.Organisms.ProfileHeader
|
||||
import Routes
|
||||
|
@ -14,12 +16,22 @@ import Text.Blaze.Html5 as H
|
|||
hiding ( main )
|
||||
import Text.Blaze.Html5.Attributes as A
|
||||
|
||||
dummy :: PostProp
|
||||
dummy = PostProp { postRoute = Blog
|
||||
, postTitle = "Go see all the posts now!"
|
||||
, postSummary = H.p "Aaaaaaall the poooooooosts"
|
||||
, postDate = "2023-06-20"
|
||||
}
|
||||
|
||||
indexBody :: Component Html
|
||||
indexBody = mconcat
|
||||
[ profileHeader
|
||||
, buttonWithText <*> pure "Click!"
|
||||
, buttonLink Blog <*> pure "All posts"
|
||||
]
|
||||
indexBody =
|
||||
profileHeader
|
||||
<> (section' <*> mconcat
|
||||
[ buttonWithText <*> pure "Click!"
|
||||
, buttonLink Blog <*> pure "All posts"
|
||||
, blogCard dummy
|
||||
]
|
||||
)
|
||||
|
||||
indexTemplate :: Component Html
|
||||
indexTemplate =
|
||||
|
|
|
@ -5,16 +5,21 @@ module Kit.Templates.Post
|
|||
|
||||
import Components
|
||||
import Core.Render
|
||||
import Kit.Atoms.Section
|
||||
import Kit.Organisms.Head
|
||||
import Text.Blaze.Html5 as H
|
||||
hiding ( main )
|
||||
|
||||
postTemplate :: Component Html
|
||||
postTemplate = docTypeHtml <$> defaultHead "$title$" <> pure
|
||||
(body $ do
|
||||
h1 "$title$"
|
||||
"$body$"
|
||||
)
|
||||
postTemplate =
|
||||
docTypeHtml
|
||||
<$> defaultHead "$title$"
|
||||
<> (section' <*> pure
|
||||
(body $ do
|
||||
h1 "$title$"
|
||||
"$body$"
|
||||
)
|
||||
)
|
||||
|
||||
main :: IO ()
|
||||
main = print $ getHtml postTemplate
|
||||
|
|
Loading…
Reference in a new issue