module Graphics.UI.Threepenny.Ext.Flexbox (
ChildProps (..), ParentProps (..), defaultParentProps, defaultChildProps,
flexbox,
column, row
) where
import qualified Clay.Common as CC
import Clay.Display (Display)
import qualified Clay.Display as CD
import Clay.Flexbox (AlignContentValue,
AlignItemsValue, AlignSelfValue,
FlexDirection, FlexWrap,
JustifyContentValue)
import qualified Clay.Flexbox as CF
import Clay.Property (unKeys, unPlain, unValue)
import Clay.Size (LengthUnit, Size)
import Clay.Stylesheet (Rule (Property), runS)
import Data.Text (unpack)
import qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core hiding (column, row)
class ToStyle a where
toStyle :: a -> [(String, String)]
instance ToStyle Rule where
toStyle (Property k v) =
[(unpack $ unPlain $ unKeys k, unpack $ unPlain $ unValue v)]
data ParentProps = ParentProps {
pDisplay :: Display
, pFlexDirection :: FlexDirection
, pFlexWrap :: FlexWrap
, pJustifyContent :: JustifyContentValue
, pAlignItems :: AlignItemsValue
, pAlignContent :: AlignContentValue
}
instance ToStyle ParentProps where
toStyle p = concatMap toStyle $ concatMap runS [
CD.display $ pDisplay p
, CF.flexDirection $ pFlexDirection p
, CF.flexWrap $ pFlexWrap p
, CF.justifyContent $ pJustifyContent p
, CF.alignItems $ pAlignItems p
, CF.alignContent $ pAlignContent p
]
defaultParentProps :: ParentProps
defaultParentProps = ParentProps {
pDisplay = CD.flex
, pFlexDirection = CF.row
, pFlexWrap = CF.nowrap
, pJustifyContent = CF.flexStart
, pAlignItems = CF.stretch
, pAlignContent = CF.stretch
}
data ChildProps = ChildProps {
cOrder :: Int
, cFlexGrow :: Int
, cFlexShrink :: Int
, cFlexBasis :: Size LengthUnit
, cAlignSelf :: AlignSelfValue
}
instance ToStyle ChildProps where
toStyle c = concatMap toStyle $ concatMap runS [
CF.order $ cOrder c
, CF.flexGrow $ cFlexGrow c
, CF.flexShrink $ cFlexShrink c
, CF.flexBasis $ cFlexBasis c
, CF.alignSelf $ cAlignSelf c
]
defaultChildProps :: ChildProps
defaultChildProps = ChildProps {
cOrder = 1
, cFlexGrow = 0
, cFlexShrink = 1
, cFlexBasis = CC.auto
, cAlignSelf = CC.auto
}
setProps :: ToStyle a => UI Element -> a -> UI Element
setProps el props = el # set UI.style (toStyle props)
flexbox ::
UI Element -> ParentProps
-> [(UI Element, ChildProps)]
-> UI Element
flexbox p pProps cs = do
p' <- setProps p pProps
cs' <- mapM (uncurry setProps) cs
element p' #+ map element cs'
column :: UI Element -> [UI Element] -> UI Element
column p cs = flexbox p defaultParentProps { pFlexDirection = CF.column } $
zip cs $ repeat defaultChildProps
row :: UI Element -> [UI Element] -> UI Element
row p cs = flexbox p defaultParentProps $ zip cs $ repeat defaultChildProps