module Web.View.Layout where

import Data.Function
import Data.Text
import Web.View.Element
import Web.View.Style
import Web.View.Types
import Web.View.View (View, tag)


{- | We can intuitively create layouts with combindations of 'row', 'col', 'grow', and 'space'

Wrap main content in 'layout' to allow the view to consume vertical screen space

@
holygrail :: 'View' c ()
holygrail = 'layout' id $ do
  'row' section "Top Bar"
  'row' 'grow' $ do
    'col' section "Left Sidebar"
    'col' (section . 'grow') "Main Content"
    'col' section "Right Sidebar"
  'row' section "Bottom Bar"
  where section = 'border' 1
@
-}
layout :: Mod -> View c () -> View c ()
layout :: forall c. Mod -> View c () -> View c ()
layout Mod
f = Mod -> View c () -> View c ()
forall c. Mod -> View c () -> View c ()
el (Mod
root Mod -> Mod -> Mod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mod
f)


{- | As `layout` but as a 'Mod'

> holygrail = col root $ do
>   ...
-}
root :: Mod
root :: Mod
root =
  Mod
flexCol
    Mod -> Mod -> Mod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Class -> Mod
addClass
      ( ClassName -> Class
cls ClassName
"layout"
          -- [ ("white-space", "pre")
          Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Text -> val -> Class -> Class
prop @Text Text
"width" Text
"100vw"
          Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Text -> val -> Class -> Class
prop @Text Text
"height" Text
"100vh"
          -- not sure if this property is necessary, copied from older code
          Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Text -> val -> Class -> Class
prop @Text Text
"min-height" Text
"100vh"
          Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Text -> val -> Class -> Class
prop @Text Text
"z-index" Text
"0"
      )


{- | Lay out children in a column.

> col grow $ do
>    el_ "Top"
>    space
>    el_ "Bottom"
-}
col :: Mod -> View c () -> View c ()
col :: forall c. Mod -> View c () -> View c ()
col Mod
f = Mod -> View c () -> View c ()
forall c. Mod -> View c () -> View c ()
el (Mod
flexCol Mod -> Mod -> Mod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mod
f)


{- | Lay out children in a row

> row id $ do
>    el_ "Left"
>    space
>    el_ "Right"
-}
row :: Mod -> View c () -> View c ()
row :: forall c. Mod -> View c () -> View c ()
row Mod
f = Mod -> View c () -> View c ()
forall c. Mod -> View c () -> View c ()
el (Mod
flexRow Mod -> Mod -> Mod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mod
f)


{- | Grow to fill the available space in the parent 'Web.View.Layout.row' or 'Web.View.Layout.col'

> row id $ do
>  el grow none
>  el_ "Right"
-}
grow :: Mod
grow :: Mod
grow = Class -> Mod
addClass (Class -> Mod) -> Class -> Mod
forall a b. (a -> b) -> a -> b
$ ClassName -> Class
cls ClassName
"grow" Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Text -> val -> Class -> Class
prop @Int Text
"flex-grow" Int
1


{- | Space that fills the available space in the parent 'Web.View.Layout.row' or 'Web.View.Layout.col'.


> row id $ do
>  space
>  el_ "Right"

This is equivalent to an empty element with 'grow'

> space = el grow none
-}
space :: View c ()
space :: forall c. View c ()
space = Mod -> View c () -> View c ()
forall c. Mod -> View c () -> View c ()
el Mod
grow View c ()
forall c. View c ()
none


-- | Allow items to become smaller than their contents. This is not the opposite of grow!
collapse :: Mod
collapse :: Mod
collapse = Class -> Mod
addClass (Class -> Mod) -> Class -> Mod
forall a b. (a -> b) -> a -> b
$ ClassName -> Class
cls ClassName
"collapse" Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Text -> val -> Class -> Class
prop @Int Text
"min-width" Int
0


{- | Make a fixed 'layout' by putting 'scroll' on a child-element

> document = row root $ do
>   nav (width 300) "Sidebar"
>   col (grow . scroll) "Main Content"
-}
scroll :: Mod
scroll :: Mod
scroll = Class -> Mod
addClass (Class -> Mod) -> Class -> Mod
forall a b. (a -> b) -> a -> b
$ ClassName -> Class
cls ClassName
"scroll" Class -> (Class -> Class) -> Class
forall a b. a -> (a -> b) -> b
& forall val. ToStyleValue val => Text -> val -> Class -> Class
prop @Text Text
"overflow" Text
"auto"


-- | A Nav element
nav :: Mod -> View c () -> View c ()
nav :: forall c. Mod -> View c () -> View c ()
nav Mod
f = Text -> Mod -> View c () -> View c ()
forall c. Text -> Mod -> View c () -> View c ()
tag Text
"nav" (Mod
f Mod -> Mod -> Mod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mod
flexCol)