Assets declared throughout Components are gathered in a FileTree structure. At compile time, the assets tree is flattened to give all assets paths and each asset is matched and copied. This prevents unused assets that are in the source to be deployed.
66 lines
2 KiB
Haskell
66 lines
2 KiB
Haskell
module Components
|
|
( Prop(..)
|
|
, prop
|
|
, Component(..)
|
|
, new
|
|
, (<.>)
|
|
, addCss
|
|
, addAsset
|
|
, addAsset'
|
|
, getHtml
|
|
, getCss
|
|
, getAssets
|
|
) where
|
|
|
|
import Clay ( Css
|
|
, compact
|
|
, renderWith
|
|
)
|
|
import Core.Writer
|
|
import qualified Data.Map as Map
|
|
import Data.Text.Lazy ( unpack )
|
|
import Routes
|
|
import Text.Blaze.Html
|
|
import Text.Blaze.Html.Renderer.String
|
|
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.)
|
|
data Prop = Prop
|
|
{ cssMap :: Map.Map String Css
|
|
, assetsTree :: FileTree
|
|
}
|
|
|
|
instance Semigroup Prop where
|
|
p1 <> p2 = Prop { cssMap = Map.union (cssMap p1) (cssMap p2)
|
|
, assetsTree = assetsTree p1 <> assetsTree p2
|
|
}
|
|
|
|
instance Monoid Prop where
|
|
mempty = Prop Map.empty mempty
|
|
|
|
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
|
|
|
|
-- |Get a Component's Css
|
|
getCss :: Component a -> Css
|
|
getCss = mconcat . map snd . Map.toList . cssMap . snd . runWriter
|
|
|
|
-- |Get a Component's assets tree
|
|
getAssets :: Component a -> FileTree
|
|
getAssets = assetsTree . snd . runWriter
|