module Graphics.UI.Threepenny.Ext.Flexbox (
ParentProps (..),
parentProps,
display, flexDirection, flexWrap, justifyContent, alignItems, aligContent,
ChildProps (..),
childProps,
order, flexGrow, flexShrink, flexBasis, alignSelf,
ToStyle (..), setFlex,
flex, flex_p, flex_c, flex_pc
) 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
]
parentProps :: ParentProps
parentProps = ParentProps {
pDisplay = CD.flex
, pFlexDirection = CF.row
, pFlexWrap = CF.nowrap
, pJustifyContent = CF.flexStart
, pAlignItems = CF.stretch
, pAlignContent = CF.stretch
}
display x = parentProps { pDisplay = x }
flexDirection x = parentProps { pFlexDirection = x }
flexWrap x = parentProps { pFlexWrap = x }
justifyContent x = parentProps { pJustifyContent = x }
alignItems x = parentProps { pAlignItems = x }
aligContent x = parentProps { pAlignContent = x }
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
]
childProps :: ChildProps
childProps = ChildProps {
cOrder = 1
, cFlexGrow = 0
, cFlexShrink = 1
, cFlexBasis = CC.auto
, cAlignSelf = CC.auto
}
order x = childProps { cOrder = x }
flexGrow x = childProps { cFlexGrow = x }
flexShrink x = childProps { cFlexShrink = x }
flexBasis x = childProps { cFlexBasis = x }
alignSelf x = childProps { cAlignSelf = x }
setFlex :: ToStyle a => a -> UI Element -> UI Element
setFlex props el = el # set UI.style (toStyle props)
flex ::
UI Element
-> ParentProps
-> [(UI Element, ChildProps)]
-> UI Element
flex p pProps cs = do
p' <- p # setFlex pProps
cs' <- mapM (\(c, cProps) -> c # setFlex cProps) cs
element p' #+ map element cs'
flex_p ::
UI Element
-> [(UI Element, ChildProps)]
-> UI Element
flex_p p = flex p parentProps
flex_c ::
UI Element
-> ParentProps
-> [UI Element]
-> UI Element
flex_c p pProps cs = flex p pProps $ zip cs $ repeat childProps
flex_pc ::
UI Element
-> [UI Element]
-> UI Element
flex_pc p = flex_c p parentProps