-- | This module defines most of the functions that are core to the DSL. Most of them are re-exported by "Stitch", so you usually shouldn't need to import this module directly (unless you want to use CSS imports). module Stitch.Combinators ( (.=) , (?) , (-:) , comment , cssImport ) where import Control.Monad.Trans.Stitch import Stitch.Types import Control.Monad.Trans.Writer.Strict import Data.Monoid (Monoid(..)) import Data.Semigroup ((<>)) import Data.Text (Text) import qualified Data.Map as Map import qualified Data.Text as Text -- | Add a key-value property pair. For example, @"color" .= "red"@ will add @color: red@ to the CSS output. (.=) :: Monad m => Text -> Text -> StitchT m () k .= v = StitchT $ tell $ Block [] [Property k v] mempty infix 8 .= -- | Nest a selector under the current selector. For example, this: -- -- > "h1" ? do -- > "color" .= "red" -- > "a" ? -- > "text-decoration" .= "underline" -- -- | results in the following being added to the CSS output: -- -- > h1 { -- > color: red -- > } -- > h1 a { -- > text-decoration: underline -- > } (?) :: Monad m => Selector -> StitchT m a -> StitchT m a sel ? (StitchT x) = StitchT $ censor (\(Block is ps cs) -> Block is [] (Children $ Map.singleton sel (InnerBlock ps cs))) x infixr 6 ? -- | @"pref" -: assignments@ prefixes all the keys of @assignments@ with @pref-@. This can be useful for putting a bunch of grouped "font" or "border" properties together – for example, the following two actions function the same: -- -- > "font" -: do -- > "size" .= "1.5rem" -- > "family" .= "Helvetica" -- > "weight" .= "bold" -- -- > "font-size" .= "1.5rem" -- > "font-family" .= "Helvetica" -- > "font-weight" .= "bold" (-:) :: Monad m => Text -> StitchT m a -> StitchT m a prefix -: (StitchT x) = StitchT $ censor (\(Block _ ps cs) -> Block [] (map (prefixProperty prefix) ps) (prefixChildren prefix cs)) x infixr 6 -: prefixProperty :: Text -> Property -> Property prefixProperty pref (Property k v) = Property (if Text.null k then pref else pref <> "-" <> k) v prefixProperty _ x = x prefixChildren :: Text -> Children -> Children prefixChildren pref (Children x) = Children (fmap (prefixInnerBlock pref) x) prefixInnerBlock :: Text -> InnerBlock -> InnerBlock prefixInnerBlock pref (InnerBlock ps cs) = InnerBlock (fmap (prefixProperty pref) ps) (prefixChildren pref cs) -- | Add a comment to the CSS output. The 'Stitch.Render.compressed' printer won't add comments to the final CSS output. comment :: Monad m => Text -> StitchT m () comment c = StitchT $ tell $ Block [] [Comment c] mempty -- | Add an @\@import@ statement to the top-level of the CSS output. cssImport :: Monad m => Text -> StitchT m () cssImport u = StitchT $ tell $ Block [Import u] [] mempty