templates-0.1.0.0: src/Templates/Partials/Buttons.hs
{-# LANGUAGE OverloadedStrings #-}
module Templates.Partials.Buttons where
import Templates.Types
import Classh as C
import Classh.Reflex as C
import Data.Text as T
import Reflex.Dom.Core
import Control.Lens ((%~))
import Data.Proxy
import Data.Char (isAlphaNum, isSpace)
iconButton :: DomBuilder t m => Text -> m (Event t ())
iconButton icon = do
(e, _) <- elClass' "button" classes $ text icon
pure $ domEvent Click e
where
classes = "focus:outline-none bg-primary rounded p-2.5 w-[50%] font-icon text-icon text-white leading-none shadow-button h-[95%]"
iconButton' :: (DomBuilder t m, PostBuild t m) => Dynamic t Bool -> Text -> m (Event t ())
iconButton' enabled icon = do
let attrs = ffor enabled $ \b -> if b then "class" =: classes else "class" =: classes <> "disabled" =: "1"
(e, _) <- elDynAttr' "button" attrs $ text icon
pure $ domEvent Click e
where
classes = "focus:outline-none flex-shrink-0 bg-primary rounded p-2.5 font-icon text-icon text-white leading-none shadow-button"
primaryButton' :: (DomBuilder t m, PostBuild t m) => Dynamic t Bool -> Text -> m (Event t ())
primaryButton' enabled buttonText = do
let attrs = ffor enabled $ \b -> if b then "class" =: classes else "class" =: classes <> "disabled" =: "1"
(e, _) <- elDynAttr' "button" attrs $ text buttonText
pure $ domEvent Click e
where
classes =
"focus:outline-none w-full p-4 mt-12 shadow-button bg-primary \
\ font-facit font-bold text-white text-body text-center rounded \
\ hover:bg-primary-rich active:bg-primary-desaturated \
\ focus:ring-4 ring-primary ring-opacity-50"
secondaryIconButton :: DomBuilder t m => Text -> Text -> m (Event t ())
secondaryIconButton cs icon = do
(e, _) <- elClass' "button" classes $
elClass "div" "font-icon leading-none text-icon text-primary-dark" $ text icon
pure $ domEvent Click e
where
classes =
"focus:outline-none rounded border border-metaline \
\ focus:ring-4 ring-primary ring-opacity-50 \
\ p-2.5 flex-shrink-0 bg-primary-light " <> cs
secondaryButton :: DomBuilder t m => Text -> Text -> m (Event t ())
secondaryButton cs label = do
(e, _) <- elClass' "button" classes $
text label
pure $ domEvent Click e
where
classes =
"w-full p-2.5 leading-none text-center rounded border border-metaline \
\ bg-primary-light text-primary-darker font-bold font-facit focus:outline-none \
\ focus:ring-4 ring-primary ring-opacity-50 " <> cs
sendButton :: DomBuilder t m => m (Event t ())
sendButton = iconButton "send"
navyBlueButton :: DomBuilder t m => Text -> m (Event t ())
navyBlueButton buttonText = do
(e, _) <- elClass' "button" other $ C.textS textCfg' buttonText
pure $ domEvent Click e
where
textCfg' = $(C.classh' [ C.text_color C..~~ C.White
, C.text_font C..~~ C.Font_Custom "Sarabun"
, C.text_weight C..~~ C.Bold
])
other =
"focus:outline-none w-full p-4 shadow-button bg-[#2E3A59] \
\ rounded-3xl hover:bg-primary-rich active:bg-primary-desaturated \
\ focus:ring-4 ring-primary ring-opacity-50 \
\ transition-all duration-300 ease-in-out \
\ transform hover:scale-105 active:scale-95 \
\ hover:shadow-md active:shadow-lg"
-- FROM ACE
primaryButtonImageDyn
:: ( PostBuild t m
, DomBuilder t m
)
=> Dynamic t Text
-> Height
-> Width
-> m (Event t ())
primaryButtonImageDyn dynImageHref height width = do
(e, _) <- elClass' "button" classes $
elDynAttr "img" imgAttrs blank
pure $ domEvent Click e
where
otherImgAttrs = "height" =: height <> "width" =: width <> "class" =: "block mx-auto"
imgAttrs = (\src -> otherImgAttrs <> "src" =: src) <$> dynImageHref
classes =
"focus:outline-none w-full p-4 mt-16 shadow-button bg-[#00B9DA] \
\ font-[Sarabun] font-bold text-white text-body text-center rounded-xl \
\ hover:bg-primary-rich active:bg-primary-desaturated \
\ focus:ring-4 ring-primary ring-opacity-50 \
\ transition-all duration-300 ease-in-out \
\ transform hover:scale-105 active:scale-95 \
\ hover:shadow-md active:shadow-lg"
type Height = Text
type Width = Text
primaryButtonImage :: DomBuilder t m => Text -> Height -> Width -> m (Event t ())
primaryButtonImage imageHref height width = do
(e, _) <- elClass' "button" classes $
elAttr "img" ("src" =: imageHref <> "height" =: height <> "width" =: width <> "class" =: "block mx-auto") blank
pure $ domEvent Click e
where
classes =
"focus:outline-none w-full p-4 mt-16 shadow-button bg-[#00B9DA] \
\ font-[Sarabun] font-bold text-white text-body text-center rounded-xl \
\ hover:bg-primary-rich active:bg-primary-desaturated \
\ focus:ring-4 ring-primary ring-opacity-50 \
\ transition-all duration-300 ease-in-out \
\ transform hover:scale-105 active:scale-95 \
\ hover:shadow-md active:shadow-lg"
primaryButtonImageText :: DomBuilder t m => Text -> Height -> Width -> Text -> m (Event t ())
primaryButtonImageText imageHref height width bottomText = do
(e, _) <- elClass' "button" classes $ do
elAttr "img" ("src" =: imageHref <> "height" =: height <> "width" =: width <> "class" =: "block mx-auto") blank
text bottomText -- TODO: replace with styledText
pure $ domEvent Click e
where
classes =
"focus:outline-none w-full p-4 mt-16 shadow-button bg-[#00B9DA] \
\ font-[Sarabun] font-bold text-white text-body text-center rounded-xl \
\ hover:bg-primary-rich active:bg-primary-desaturated \
\ focus:ring-4 ring-primary ring-opacity-50 \
\ transition-all duration-300 ease-in-out \
\ transform hover:scale-105 active:scale-95 \
\ hover:shadow-md active:shadow-lg"
primaryButtonSized :: DomBuilder t m => TWSize -> TWSize -> Text -> m (Event t ())
primaryButtonSized height width buttonText = do
(e, _) <- elAttr' "button" ("class" =: classTW <> "name" =: name) $ text buttonText
pure $ domEvent Click e
where
classTW = primaryClass <&> ("py-" <> showTW height) <&> ("px-" <> showTW width)
-- for testing / selenium mainly
name = T.filter (\c -> isAlphaNum c || isSpace c ) buttonText
primaryButton :: DomBuilder t m => Text -> m (Event t ())
primaryButton buttonText = do
(e, _) <- elAttr' "button" ("class" =: (primaryClass <&> "py-4 px-8") <> "name" =: name) $ text buttonText
pure $ domEvent Click e
where
-- for testing / selenium mainly
name = T.filter (\c -> isAlphaNum c || isSpace c ) buttonText
primaryClass =
"focus:outline-none shadow-button bg-[#00B9DA] \
\ font-[Sarabun] font-bold text-white text-body text-center rounded-xl \
\ hover:bg-primary-rich active:bg-primary-desaturated \
\ focus:ring-4 ring-primary ring-opacity-50 \
\ transition-all duration-300 ease-in-out \
\ transform hover:scale-105 active:scale-95 \
\ whitespace-nowrap inline-block \
\ hover:shadow-md active:shadow-lg min-[0px]:text-xs md:text-lg"
example :: Template t m => m (Event t ())
example = buttonToggleBody "" True $ \case
True -> text "hey"
False -> text "Hello"
-- | Toggles between 2 inner bodies based on its clicks
buttonToggleBody :: Template t m => Dynamic t T.Text -> Bool -> (Bool -> m a) -> m (Event t ())
buttonToggleBody buttonClasses start dynDom = mdo
(e, _) <- elDynClass' "button" buttonClasses $ dyn $ ffor booly $ dynDom
let clk = domEvent Click e
booly <- toggle start clk
pure clk
-- | Stop event propogation on click
greedyButton :: forall t m a. DomBuilder t m => m a -> m (Event t (), a)
greedyButton c = do
let cfg = (def :: ElementConfig EventResult t (DomBuilderSpace m))
& elementConfig_eventSpec %~ addEventSpecFlags (Proxy :: Proxy (DomBuilderSpace m)) Click (const stopPropagation)
(e, a) <- element "button" cfg c
return (domEvent Click e, a)
greedyButton_ :: forall t m a. DomBuilder t m => m a -> m (Event t ())
greedyButton_ c = fmap fst $ greedyButton c