{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultilineStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Miso.UI.Button
(
ButtonProps (..)
, defaultButtonProps
, button_
, buttonClass
, buttonUsage
, buttonSample
, buttonCodeSample
, buttonPropsApi
) where
import Miso
import qualified Miso.Html.Element as H
import qualified Miso.Html.Property as P
import qualified Miso.String as MS
import Miso.UI.Types
import Miso.UI.Icons
data ButtonProps action
= ButtonProps
{ forall action. ButtonProps action -> Variant
buttonVariant :: Variant
, forall action. ButtonProps action -> Size
buttonSize :: Size
, forall action. ButtonProps action -> Bool
buttonIcon :: Bool
, forall action. ButtonProps action -> Bool
buttonDisabled :: Bool
, forall action. ButtonProps action -> [MisoString]
buttonClasses :: [MisoString]
, forall action. ButtonProps action -> [Attribute action]
buttonAttrs :: [Attribute action]
}
defaultButtonProps :: ButtonProps action
defaultButtonProps :: forall action. ButtonProps action
defaultButtonProps
= ButtonProps
{ buttonVariant :: Variant
buttonVariant = Variant
Primary
, buttonSize :: Size
buttonSize = Size
DefaultSize
, buttonIcon :: Bool
buttonIcon = Bool
False
, buttonDisabled :: Bool
buttonDisabled = Bool
False
, buttonClasses :: [MisoString]
buttonClasses = []
, buttonAttrs :: [Attribute action]
buttonAttrs = []
}
buttonClass :: ButtonProps action -> MisoString
buttonClass :: forall action. ButtonProps action -> MisoString
buttonClass ButtonProps {Bool
[MisoString]
[Attribute action]
Size
Variant
buttonVariant :: forall action. ButtonProps action -> Variant
buttonSize :: forall action. ButtonProps action -> Size
buttonIcon :: forall action. ButtonProps action -> Bool
buttonDisabled :: forall action. ButtonProps action -> Bool
buttonClasses :: forall action. ButtonProps action -> [MisoString]
buttonAttrs :: forall action. ButtonProps action -> [Attribute action]
buttonVariant :: Variant
buttonSize :: Size
buttonIcon :: Bool
buttonDisabled :: Bool
buttonClasses :: [MisoString]
buttonAttrs :: [Attribute action]
..} = MisoString -> [MisoString] -> MisoString
MS.intercalate MisoString
"-" ([MisoString] -> MisoString) -> [MisoString] -> MisoString
forall a b. (a -> b) -> a -> b
$ [[MisoString]] -> [MisoString]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ MisoString
"btn" ]
, [ Size -> MisoString
sizeSuffix Size
buttonSize | Size
buttonSize Size -> Size -> Bool
forall a. Eq a => a -> a -> Bool
/= Size
DefaultSize ]
, [ MisoString
"icon" | Bool
buttonIcon ]
, [ Variant -> MisoString
variantSuffix Variant
buttonVariant | Variant
buttonVariant Variant -> Variant -> Bool
forall a. Eq a => a -> a -> Bool
/= Variant
Primary ]
]
button_
:: ButtonProps action
-> [View model action]
-> View model action
button_ :: forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
cfg [View model action]
kids =
([Attribute action] -> [View model action] -> View model action)
-> [Attribute action]
-> Bool
-> [Attribute action]
-> [View model action]
-> View model action
forall action model.
([Attribute action] -> [View model action] -> View model action)
-> [Attribute action]
-> Bool
-> [Attribute action]
-> [View model action]
-> View model action
optionalAttrs
[Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.button_
( [MisoString] -> Attribute action
forall action. [MisoString] -> Attribute action
P.classes_ (ButtonProps action -> MisoString
forall action. ButtonProps action -> MisoString
buttonClass ButtonProps action
cfg MisoString -> [MisoString] -> [MisoString]
forall a. a -> [a] -> [a]
: ButtonProps action -> [MisoString]
forall action. ButtonProps action -> [MisoString]
buttonClasses ButtonProps action
cfg)
Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: ButtonProps action -> [Attribute action]
forall action. ButtonProps action -> [Attribute action]
buttonAttrs ButtonProps action
cfg
)
(ButtonProps action -> Bool
forall action. ButtonProps action -> Bool
buttonDisabled ButtonProps action
cfg)
[ Attribute action
forall action. Attribute action
P.disabled_ ]
[View model action]
kids
buttonUsage :: View model action
buttonUsage :: forall model action. View model action
buttonUsage =
[Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
[ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"flex flex-wrap items-center gap-2" ]
[ ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps [ View model action
"Primary" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonVariant = Outline } [ View model action
"Outline" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonVariant = Ghost } [ View model action
"Ghost" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonVariant = Destructive }
[ [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
sendIcon [], View model action
"Danger" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = Small, buttonVariant = Secondary }
[ View model action
"Small" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = Large } [ View model action
"Large" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonIcon = True, buttonVariant = Outline }
[ [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
arrowRightIcon [] ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonVariant = Outline, buttonDisabled = True }
[ [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
loaderIcon [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"animate-spin" ], View model action
"Loading" ]
]
buttonSample :: View model action
buttonSample :: forall model action. View model action
buttonSample =
[Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
[ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"flex flex-col gap-6" ]
[ Size -> View model action
forall {model} {action}. Size -> View model action
row Size
DefaultSize, Size -> View model action
forall {model} {action}. Size -> View model action
row Size
Small, Size -> View model action
forall {model} {action}. Size -> View model action
row Size
Large, View model action
forall model action. View model action
icons ]
where
row :: Size -> View model action
row Size
size =
[Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
[ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"flex flex-wrap items-center gap-2 md:flex-row" ]
[ ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = size } [ View model action
"Primary" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = size, buttonVariant = Outline } [ View model action
"Outline" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = size, buttonVariant = Ghost } [ View model action
"Ghost" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = size, buttonVariant = Destructive }
[ [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
sendIcon [], View model action
"Danger" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = size, buttonVariant = Secondary } [ View model action
"Secondary" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = size, buttonVariant = Link } [ View model action
"Link" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = size, buttonVariant = Outline }
[ [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
sendIcon [], View model action
"Send" ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = size, buttonVariant = Outline }
[ View model action
"Learn more", [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
arrowRightIcon [] ]
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonSize = size, buttonVariant = Outline, buttonDisabled = True }
[ [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
loaderIcon [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"animate-spin" ], View model action
"Loading" ]
]
icons :: View model action
icons =
[Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
[ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"flex flex-wrap items-center gap-2 md:flex-row" ]
[ Variant -> View model action -> View model action
forall {model} {action}.
Variant -> View model action -> View model action
iconButton Variant
Primary ([Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
downloadIcon [])
, Variant -> View model action -> View model action
forall {model} {action}.
Variant -> View model action -> View model action
iconButton Variant
Secondary ([Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
uploadIcon [])
, Variant -> View model action -> View model action
forall {model} {action}.
Variant -> View model action -> View model action
iconButton Variant
Outline ([Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
arrowRightIcon [])
, Variant -> View model action -> View model action
forall {model} {action}.
Variant -> View model action -> View model action
iconButton Variant
Ghost ([Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
dotsIcon [])
, Variant -> View model action -> View model action
forall {model} {action}.
Variant -> View model action -> View model action
iconButton Variant
Destructive ([Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
trashIcon [])
, ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps
{ buttonIcon = True
, buttonVariant = Outline
, buttonDisabled = True
}
[ [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
loaderIcon [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"animate-spin" ] ]
]
iconButton :: Variant -> View model action -> View model action
iconButton Variant
v View model action
icon =
ButtonProps action -> [View model action] -> View model action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps action
forall action. ButtonProps action
defaultButtonProps { buttonIcon = True, buttonVariant = v } [ View model action
icon ]
buttonCodeSample :: View model action
buttonCodeSample :: forall model action. View model action
buttonCodeSample =
View model action
"""
-----------------------------------------------------------------------------
module MyButton (buttonUsage) where
-----------------------------------------------------------------------------
import Miso
import qualified Miso.Html.Element as H
import qualified Miso.Html.Property as P
import qualified Miso.String as MS
import Miso.UI.Types
import Miso.UI.Icons
import Miso.UI.Button
-----------------------------------------------------------------------------
buttonUsage :: View model action
buttonUsage =
H.div_
[ P.class_ "flex flex-wrap items-center gap-2" ]
[ button_ defaultButtonProps [ "Primary" ]
, button_ defaultButtonProps { buttonVariant = Outline } [ "Outline" ]
, button_ defaultButtonProps { buttonVariant = Ghost } [ "Ghost" ]
, button_ defaultButtonProps { buttonVariant = Destructive }
[ sendIcon [], "Danger" ]
, button_ defaultButtonProps { buttonSize = Small, buttonVariant = Secondary }
[ "Small" ]
, button_ defaultButtonProps { buttonSize = Large } [ "Large" ]
, button_ defaultButtonProps { buttonIcon = True, buttonVariant = Outline }
[ arrowRightIcon [] ]
, button_ defaultButtonProps { buttonVariant = Outline, buttonDisabled = True }
[ loaderIcon [ P.class_ "animate-spin" ], "Loading" ]
]
"""
buttonPropsApi :: View model action
buttonPropsApi :: forall model action. View model action
buttonPropsApi =
View model action
"""
-- | Props for 'button'
data ButtonProps action
= ButtonProps
{ buttonVariant :: Variant
-- ^ 'Primary', 'Secondary', 'Destructive', 'Outline', 'Ghost' or 'Link'
, buttonSize :: Size
-- ^ 'DefaultSize', 'Small' or 'Large'
, buttonIcon :: Bool
-- ^ Square icon-only button (e.g. @btn-icon-outline@)
, buttonDisabled :: Bool
, buttonClasses :: [MisoString]
-- ^ Extra classes appended to the computed basecoat class
, buttonAttrs :: [Attribute action]
-- ^ Extra attributes (e.g. @onClick@)
}
-----------------------------------------------------------------------------
-- | Smart constructor: primary variant, default size
defaultButtonProps :: ButtonProps action
defaultButtonProps
= ButtonProps
{ buttonVariant = Primary
, buttonSize = DefaultSize
, buttonIcon = False
, buttonDisabled = False
, buttonClasses = []
, buttonAttrs = []
}
"""