{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE RecordWildCards #-}
{-# OPTIONS_GHC -Wno-name-shadowing #-}

module Web.View.Style where

import Data.Function ((&))
import Data.Map qualified as M
import Data.Text (Text)
import Web.View.Types


{- HLINT "HLint: shadows the existing binding" -}

-- * Styles


-- | Set to a specific width
width :: Length -> Mod c
width :: forall c. Length -> Mod c
width Length
n =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"w" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"width" Length
n
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Int Name
"flex-shrink" Int
0


-- | Set to a specific height
height :: Length -> Mod c
height :: forall c. Length -> Mod c
height Length
n =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"h" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"height" Length
n
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Int Name
"flex-shrink" Int
0


-- | Allow width to grow to contents but not shrink any smaller than value
minWidth :: Length -> Mod c
minWidth :: forall c. Length -> Mod c
minWidth Length
n =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"mw" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"min-width" Length
n


-- | Allow height to grow to contents but not shrink any smaller than value
minHeight :: Length -> Mod c
minHeight :: forall c. Length -> Mod c
minHeight Length
n =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"mh" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"min-height" Length
n


{- | Space surrounding the children of the element

To create even spacing around and between all elements:

> col (pad 10 . gap 10) $ do
>   el_ "one"
>   el_ "two"
>   el_ "three"
-}
pad :: Sides Length -> Mod c
pad :: forall c. Sides Length -> Mod c
pad (All Length
n) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"pad" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding" Length
n
pad (Y Length
n) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"pady" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-top" Length
n
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-bottom" Length
n
pad (X Length
n) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"padx" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-left" Length
n
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-right" Length
n
pad (XY Length
x Length
y) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"pad" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
x ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
y)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-left" Length
x
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-right" Length
x
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-top" Length
y
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-bottom" Length
y
pad (TRBL Length
t Length
r Length
b Length
l) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"pad" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
t ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
r ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
b ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
l)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-top" Length
t
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-right" Length
r
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-bottom" Length
b
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"padding-left" Length
l


-- | The space between child elements. See 'pad'
gap :: Length -> Mod c
gap :: forall c. Length -> Mod c
gap Length
n = Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$ ClassName -> Class
cls (ClassName
"gap" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n) Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"gap" Length
n


fontSize :: Length -> Mod c
fontSize :: forall c. Length -> Mod c
fontSize Length
n = Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$ ClassName -> Class
cls (ClassName
"fs" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n) Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"font-size" Length
n


-- fontFamily :: Text -> Mod c
-- fontFamily t = cls1 $ Class ("font" -. n) [("font-family", pxRem n)]

-- | Set container to be a row. Favor 'Web.View.Layout.row' when possible
flexRow :: Mod c
flexRow :: forall c. Mod c
flexRow =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls ClassName
"row"
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"display" Name
"flex"
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"flex-direction" Name
"row"


-- | Set container to be a column. Favor 'Web.View.Layout.col' when possible
flexCol :: Mod c
flexCol :: forall c. Mod c
flexCol =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls ClassName
"col"
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"display" Name
"flex"
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"flex-direction" Name
"column"


-- | Adds a basic drop shadow to an element
shadow :: Mod c
shadow :: forall c. Mod c
shadow =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls ClassName
"shadow"
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"box-shadow" Name
"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"


-- | Round the corners of the element
rounded :: Length -> Mod c
rounded :: forall c. Length -> Mod c
rounded Length
n = Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$ ClassName -> Class
cls (ClassName
"rnd" ClassName -> Length -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Length
n) Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Length -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-radius" Length
n


-- | Set the background color. See 'Web.View.Types.ToColor'
bg :: (ToColor clr) => clr -> Mod ctx
bg :: forall clr ctx. ToColor clr => clr -> Mod ctx
bg clr
c =
  Class -> Mod ctx
forall c. Class -> Mod c
addClass (Class -> Mod ctx) -> Class -> Mod ctx
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"bg" ClassName -> Name -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. clr -> Name
forall a. ToColor a => a -> Name
colorName clr
c)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> HexColor -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"background-color" (clr -> HexColor
forall a. ToColor a => a -> HexColor
colorValue clr
c)


-- | Set the text color. See 'Web.View.Types.ToColor'
color :: (ToColor clr) => clr -> Mod ctx
color :: forall clr ctx. ToColor clr => clr -> Mod ctx
color clr
c = Class -> Mod ctx
forall c. Class -> Mod c
addClass (Class -> Mod ctx) -> Class -> Mod ctx
forall a b. (a -> b) -> a -> b
$ ClassName -> Class
cls (ClassName
"clr" ClassName -> Name -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. clr -> Name
forall a. ToColor a => a -> Name
colorName clr
c) Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> HexColor -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"color" (clr -> HexColor
forall a. ToColor a => a -> HexColor
colorValue clr
c)


bold :: Mod c
bold :: forall c. Mod c
bold = Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$ ClassName -> Class
cls ClassName
"bold" Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"font-weight" Name
"bold"


-- | Hide an element. See 'parent' and 'media'
hide :: Mod c
hide :: forall c. Mod c
hide =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls ClassName
"hide"
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"display" Name
"none"


opacity :: Float -> Mod c
opacity :: forall c. Float -> Mod c
opacity Float
n =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"opacity" ClassName -> Float -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Float
n)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Float -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"opacity" Float
n


{- | Set a border around the element

> el (border 1) "all sides"
> el (border (X 1)) "only left and right"
-}
border :: Sides PxRem -> Mod c
border :: forall c. Sides PxRem -> Mod c
border (All PxRem
p) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"brd" ClassName -> PxRem -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. PxRem
p)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-width" PxRem
p
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"border-style" Name
"solid"
border (Y PxRem
p) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"brdy" ClassName -> PxRem -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. PxRem
p)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-top-width" PxRem
p
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-bottom-width" PxRem
p
border (X PxRem
p) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"brdx" ClassName -> PxRem -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. PxRem
p)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-left-width" PxRem
p
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-right-width" PxRem
p
border (XY PxRem
x PxRem
y) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"brd" ClassName -> PxRem -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. PxRem
x ClassName -> PxRem -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. PxRem
y)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-right-width" PxRem
x
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-left-width" PxRem
x
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-top-width" PxRem
y
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-bottom-width" PxRem
y
border (TRBL PxRem
t PxRem
r PxRem
b PxRem
l) =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"brd" ClassName -> PxRem -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. PxRem
t ClassName -> PxRem -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. PxRem
r ClassName -> PxRem -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. PxRem
b ClassName -> PxRem -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. PxRem
l)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-top-width" PxRem
t
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-right-width" PxRem
r
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-bottom-width" PxRem
b
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> PxRem -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-left-width" PxRem
l


-- | Set a border color. See 'Web.View.Types.ToColor'
borderColor :: (ToColor clr) => clr -> Mod ctx
borderColor :: forall clr ctx. ToColor clr => clr -> Mod ctx
borderColor clr
c =
  Class -> Mod ctx
forall c. Class -> Mod c
addClass (Class -> Mod ctx) -> Class -> Mod ctx
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"brdc" ClassName -> Name -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. clr -> Name
forall a. ToColor a => a -> Name
colorName clr
c)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> HexColor -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"border-color" (clr -> HexColor
forall a. ToColor a => a -> HexColor
colorValue clr
c)


{- | Use a button-like cursor when hovering over the element

Button-like elements:

> btn = pointer . bg Primary . hover (bg PrimaryLight)
>
> options = row id $ do
>   el btn "Login"
>   el btn "Sign Up"
-}
pointer :: Mod c
pointer :: forall c. Mod c
pointer = Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$ ClassName -> Class
cls ClassName
"pointer" Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"cursor" Name
"pointer"


-- | Cut off the contents of the element
truncate :: Mod c
truncate :: forall c. Mod c
truncate =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls ClassName
"truncate"
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"white-space" Name
"nowrap"
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"overflow" Name
"hidden"
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Name -> val -> Class -> Class
prop @Text Name
"text-overflow" Name
"ellipsis"


{- | Animate changes to the given property

> el (transition 100 (Height 400)) "Tall"
> el (transition 100 (Height 100)) "Small"
-}
transition :: Ms -> TransitionProperty -> Mod c
transition :: forall c. Ms -> TransitionProperty -> Mod c
transition Ms
ms = \case
  (Height PxRem
n) -> Name -> PxRem -> Mod c
forall {val} {c}.
(ToClassName val, ToStyleValue val) =>
Name -> val -> Mod c
trans Name
"height" PxRem
n
  (Width PxRem
n) -> Name -> PxRem -> Mod c
forall {val} {c}.
(ToClassName val, ToStyleValue val) =>
Name -> val -> Mod c
trans Name
"width" PxRem
n
  (BgColor HexColor
c) -> Name -> HexColor -> Mod c
forall {val} {c}.
(ToClassName val, ToStyleValue val) =>
Name -> val -> Mod c
trans Name
"background-color" HexColor
c
  (Color HexColor
c) -> Name -> HexColor -> Mod c
forall {val} {c}.
(ToClassName val, ToStyleValue val) =>
Name -> val -> Mod c
trans Name
"color" HexColor
c
 where
  trans :: Name -> val -> Mod c
trans Name
p val
val =
    Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
      ClassName -> Class
cls (ClassName
"t" ClassName -> val -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. val
val ClassName -> Name -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Name
p ClassName -> Ms -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Ms
ms)
        Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Ms -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"transition-duration" Ms
ms
        Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Name -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"transition-property" Name
p
        Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> val -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
p val
val


-- You MUST set the height/width manually when you attempt to transition it
data TransitionProperty
  = Width PxRem
  | Height PxRem
  | BgColor HexColor
  | Color HexColor
  deriving (Int -> TransitionProperty -> ShowS
[TransitionProperty] -> ShowS
TransitionProperty -> String
(Int -> TransitionProperty -> ShowS)
-> (TransitionProperty -> String)
-> ([TransitionProperty] -> ShowS)
-> Show TransitionProperty
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TransitionProperty -> ShowS
showsPrec :: Int -> TransitionProperty -> ShowS
$cshow :: TransitionProperty -> String
show :: TransitionProperty -> String
$cshowList :: [TransitionProperty] -> ShowS
showList :: [TransitionProperty] -> ShowS
Show)


textAlign :: Align -> Mod c
textAlign :: forall c. Align -> Mod c
textAlign Align
a =
  Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> Class -> Mod c
forall a b. (a -> b) -> a -> b
$
    ClassName -> Class
cls (ClassName
"ta" ClassName -> Align -> ClassName
forall a. ToClassName a => ClassName -> a -> ClassName
-. Align
a)
      Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& Name -> Align -> Class -> Class
forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
"text-align" Align
a


-- * Selector Modifiers


{- | Apply when hovering over an element

> el (bg Primary . hover (bg PrimaryLight)) "Hover"
-}
hover :: Mod c -> Mod c
hover :: forall c. Mod c -> Mod c
hover = Pseudo -> Mod c -> Mod c
forall c. Pseudo -> Mod c -> Mod c
applyPseudo Pseudo
Hover


-- | Apply when the mouse is pressed down on an element
active :: Mod c -> Mod c
active :: forall c. Mod c -> Mod c
active = Pseudo -> Mod c -> Mod c
forall c. Pseudo -> Mod c -> Mod c
applyPseudo Pseudo
Active


-- | Apply to even-numbered children
even :: Mod c -> Mod c
even :: forall c. Mod c -> Mod c
even = Pseudo -> Mod c -> Mod c
forall c. Pseudo -> Mod c -> Mod c
applyPseudo Pseudo
Even


-- | Apply to odd-numbered children
odd :: Mod c -> Mod c
odd :: forall c. Mod c -> Mod c
odd = Pseudo -> Mod c -> Mod c
forall c. Pseudo -> Mod c -> Mod c
applyPseudo Pseudo
Odd


{- | Apply when the Media matches the current window. This allows for responsive designs

> el (width 100 . media (MinWidth 800) (width 400))
>   "Big if window > 800"
-}
media :: Media -> Mod c -> Mod c
media :: forall c. Media -> Mod c -> Mod c
media Media
m = (Class -> Class) -> Mod c -> Mod c
forall c. (Class -> Class) -> Mod c -> Mod c
mapModClass ((Class -> Class) -> Mod c -> Mod c)
-> (Class -> Class) -> Mod c -> Mod c
forall a b. (a -> b) -> a -> b
$ \Class
c ->
  Class
c
    { selector = addMedia c.selector
    }
 where
  addMedia :: Selector -> Selector
  addMedia :: Selector -> Selector
addMedia Selector{Maybe Name
Maybe Media
Maybe Pseudo
Maybe ChildCombinator
ClassName
media :: Maybe Media
ancestor :: Maybe Name
child :: Maybe ChildCombinator
pseudo :: Maybe Pseudo
className :: ClassName
$sel:media:Selector :: Selector -> Maybe Media
$sel:ancestor:Selector :: Selector -> Maybe Name
$sel:child:Selector :: Selector -> Maybe ChildCombinator
$sel:pseudo:Selector :: Selector -> Maybe Pseudo
$sel:className:Selector :: Selector -> ClassName
..} = Selector{$sel:media:Selector :: Maybe Media
media = Media -> Maybe Media
forall a. a -> Maybe a
Just Media
m, Maybe Name
Maybe Pseudo
Maybe ChildCombinator
ClassName
ancestor :: Maybe Name
child :: Maybe ChildCombinator
pseudo :: Maybe Pseudo
className :: ClassName
$sel:ancestor:Selector :: Maybe Name
$sel:child:Selector :: Maybe ChildCombinator
$sel:pseudo:Selector :: Maybe Pseudo
$sel:className:Selector :: ClassName
..}


{- | Apply when the element is somewhere inside an anscestor.

For example, the HTMX library applies an "htmx-request" class to the body when a request is pending. We can use this to create a loading indicator

> el (pad 10) $ do
>   el (parent "htmx-request" flexRow . hide) "Loading..."
>   el (parent "htmx-request" hide . flexRow) "Normal Content"
-}
parent :: Text -> Mod c -> Mod c
parent :: forall c. Name -> Mod c -> Mod c
parent Name
p = (Class -> Class) -> Mod c -> Mod c
forall c. (Class -> Class) -> Mod c -> Mod c
mapModClass ((Class -> Class) -> Mod c -> Mod c)
-> (Class -> Class) -> Mod c -> Mod c
forall a b. (a -> b) -> a -> b
$ \Class
c ->
  Class
c
    { selector = addAncestor c.selector
    }
 where
  addAncestor :: Selector -> Selector
  addAncestor :: Selector -> Selector
addAncestor Selector{Maybe Name
Maybe Media
Maybe Pseudo
Maybe ChildCombinator
ClassName
$sel:media:Selector :: Selector -> Maybe Media
$sel:ancestor:Selector :: Selector -> Maybe Name
$sel:child:Selector :: Selector -> Maybe ChildCombinator
$sel:pseudo:Selector :: Selector -> Maybe Pseudo
$sel:className:Selector :: Selector -> ClassName
media :: Maybe Media
ancestor :: Maybe Name
child :: Maybe ChildCombinator
pseudo :: Maybe Pseudo
className :: ClassName
..} = Selector{$sel:ancestor:Selector :: Maybe Name
ancestor = Name -> Maybe Name
forall a. a -> Maybe a
Just Name
p, Maybe Media
Maybe Pseudo
Maybe ChildCombinator
ClassName
$sel:media:Selector :: Maybe Media
$sel:child:Selector :: Maybe ChildCombinator
$sel:pseudo:Selector :: Maybe Pseudo
$sel:className:Selector :: ClassName
media :: Maybe Media
child :: Maybe ChildCombinator
pseudo :: Maybe Pseudo
className :: ClassName
..}


-- Add a pseudo-class like Hover to your style
applyPseudo :: Pseudo -> Mod c -> Mod c
applyPseudo :: forall c. Pseudo -> Mod c -> Mod c
applyPseudo Pseudo
ps = (Class -> Class) -> Mod c -> Mod c
forall c. (Class -> Class) -> Mod c -> Mod c
mapModClass ((Class -> Class) -> Mod c -> Mod c)
-> (Class -> Class) -> Mod c -> Mod c
forall a b. (a -> b) -> a -> b
$ \Class
c ->
  Class
c
    { selector = addToSelector c.selector
    }
 where
  addToSelector :: Selector -> Selector
  addToSelector :: Selector -> Selector
addToSelector Selector{Maybe Name
Maybe Media
Maybe Pseudo
Maybe ChildCombinator
ClassName
$sel:media:Selector :: Selector -> Maybe Media
$sel:ancestor:Selector :: Selector -> Maybe Name
$sel:child:Selector :: Selector -> Maybe ChildCombinator
$sel:pseudo:Selector :: Selector -> Maybe Pseudo
$sel:className:Selector :: Selector -> ClassName
media :: Maybe Media
ancestor :: Maybe Name
child :: Maybe ChildCombinator
pseudo :: Maybe Pseudo
className :: ClassName
..} = Selector{$sel:pseudo:Selector :: Maybe Pseudo
pseudo = Pseudo -> Maybe Pseudo
forall a. a -> Maybe a
Just Pseudo
ps, Maybe Name
Maybe Media
Maybe ChildCombinator
ClassName
$sel:media:Selector :: Maybe Media
$sel:ancestor:Selector :: Maybe Name
$sel:child:Selector :: Maybe ChildCombinator
$sel:className:Selector :: ClassName
media :: Maybe Media
ancestor :: Maybe Name
child :: Maybe ChildCombinator
className :: ClassName
..}


mapModClass :: (Class -> Class) -> Mod c -> Mod c
mapModClass :: forall c. (Class -> Class) -> Mod c -> Mod c
mapModClass Class -> Class
fc Mod c
fm Attributes c
as =
  -- apply the function to all classes added by the mod
  -- ignore
  let as' :: Attributes c
as' = Mod c
fm Mod c -> Mod c
forall a b. (a -> b) -> a -> b
$ [Class] -> Map Name Name -> Attributes c
forall {k} (c :: k). [Class] -> Map Name Name -> Attributes c
Attributes [] []
   in Attributes c
as'
        { classes = as.classes <> map fc as'.classes
        , other = as.other <> as'.other
        }


{- | Setting the same property twice will result in only one of the classes being applied. It is not intuitive, as CSS rules dictate that the order of the class definitions determine precedence. You can mark a `Mod` as important to force it to apply
important :: Mod c -> Mod c
important =
  mapModClass $ \c ->
    c
      { important = True
      }
-}

-- * Creating New Styles


{- | Add a single class

> width :: PxRem -> Mod
> width n =
>   addClass
>     $ cls ("w" -. n)
>     & prop "width" n
>     & prop @Int "flex-shrink" 0
-}
addClass :: Class -> Mod c
addClass :: forall c. Class -> Mod c
addClass Class
c Attributes c
attributes =
  Attributes
    { $sel:classes:Attributes :: [Class]
classes = Class
c Class -> [Class] -> [Class]
forall a. a -> [a] -> [a]
: Attributes c
attributes.classes
    , $sel:other:Attributes :: Map Name Name
other = Attributes c
attributes.other
    }


-- | Construct a class from a ClassName
cls :: ClassName -> Class
cls :: ClassName -> Class
cls ClassName
n = Selector -> Styles -> Class
Class (ClassName -> Selector
selector ClassName
n) []


{- | Construct a mod from a ClassName with no CSS properties. Convenience for situations where external CSS classes need to be referenced.

> el (extClass "btn" . extClass "btn-primary") "Click me!"
-}
extClass :: ClassName -> Mod c
extClass :: forall c. ClassName -> Mod c
extClass = Class -> Mod c
forall c. Class -> Mod c
addClass (Class -> Mod c) -> (ClassName -> Class) -> ClassName -> Mod c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ClassName -> Class
cls


-- | Add a property to a class
prop :: (ToStyleValue val) => Name -> val -> Class -> Class
prop :: forall val. ToStyleValue val => Name -> val -> Class -> Class
prop Name
n val
v Class
c =
  Class
c{properties = M.insert n (toStyleValue v) c.properties}


-- | Hyphenate classnames
(-.) :: (ToClassName a) => ClassName -> a -> ClassName
(ClassName Name
n) -. :: forall a. ToClassName a => ClassName -> a -> ClassName
-. a
a = (Name -> ClassName
ClassName (Name -> ClassName) -> Name -> ClassName
forall a b. (a -> b) -> a -> b
$ Name
n Name -> Name -> Name
forall a. Semigroup a => a -> a -> a
<> Name
"-") ClassName -> ClassName -> ClassName
forall a. Semigroup a => a -> a -> a
<> a -> ClassName
forall a. ToClassName a => a -> ClassName
toClassName a
a


infixl 6 -.