clay-0.0.1: src/Clay/Size.hs
{-# LANGUAGE
EmptyDataDecls
, OverloadedStrings
, GeneralizedNewtypeDeriving
, FlexibleInstances
#-}
module Clay.Size
(
-- * Size type.
Size
, Abs
, Rel
-- * Size constructors.
, px
, pt
, em
, ex
, pct
-- * Shorthands for mutli size-valued properties.
, sym
, sym2
, sym3
-- * Angle type.
, Angle
, Deg
, Rad
-- * Constructing angles.
, deg
, rad
)
where
import Data.Monoid
import Data.Text (pack)
import Clay.Common
import Clay.Property
import Clay.Stylesheet
-------------------------------------------------------------------------------
-- | Sizes can be relative like percentages.
data Rel
-- | Sizes can be absolute like pixels, points, etc.
data Abs
newtype Size a = Size Value
deriving (Val, Auto, Normal, Inherit, None, Other)
-- | Size in pixels.
px :: Integer -> Size Abs
px i = Size (value (pack (show i) <> "px"))
-- | Size in points.
pt :: Double -> Size Abs
pt i = Size (value (pack (show i) <> "pt"))
-- | Size in em's.
em :: Double -> Size Abs
em i = Size (value (pack (show i) <> "em"))
-- | Size in ex'es.
ex :: Double -> Size Abs
ex i = Size (value (pack (show i) <> "ex"))
-- | Size in percentages.
pct :: Double -> Size Rel
pct i = Size (value (pack (show i) <> "%"))
instance Num (Size Abs) where
fromInteger = px
(+) = error "plus not implemented for Size"
(*) = error "times not implemented for Size"
abs = error "abs not implemented for Size"
signum = error "signum not implemented for Size"
instance Fractional (Size Abs) where
fromRational = em . fromRational
instance Num (Size Rel) where
fromInteger = pct . fromInteger
(+) = error "plus not implemented for Size"
(*) = error "times not implemented for Size"
abs = error "abs not implemented for Size"
signum = error "signum not implemented for Size"
instance Fractional (Size Rel) where
fromRational = pct . fromRational
-------------------------------------------------------------------------------
sym :: (Size a -> Size a -> Size a -> Size a -> Css) -> Size a -> Css
sym k a = k a a a a
sym3 :: (Size a -> Size a -> Size a -> Size a -> Css) -> Size a -> Size a -> Size a -> Css
sym3 k tb l r = k tb l tb r
sym2 :: (Size a -> Size a -> Size a -> Size a -> Css) -> Size a -> Size a -> Css
sym2 k tb lr = k tb lr tb lr
-------------------------------------------------------------------------------
data Deg
data Rad
newtype Angle a = Angle Value
deriving (Val, Auto, Inherit, Other)
-- | Angle in degrees.
deg :: Double -> Angle Deg
deg i = Angle (value (pack (show i) <> "deg"))
-- | Angle in radians.
rad :: Double -> Angle Rad
rad i = Angle (value (pack (show i) <> "rad"))
instance Num (Angle Deg) where
fromInteger = deg . fromInteger
(+) = error "plus not implemented for Angle"
(*) = error "times not implemented for Angle"
abs = error "abs not implemented for Angle"
signum = error "signum not implemented for Angle"
instance Fractional (Angle Deg) where
fromRational = deg . fromRational
instance Num (Angle Rad) where
fromInteger = rad . fromInteger
(+) = error "plus not implemented for Angle"
(*) = error "times not implemented for Angle"
abs = error "abs not implemented for Angle"
signum = error "signum not implemented for Angle"
instance Fractional (Angle Rad) where
fromRational = rad . fromRational