{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultilineStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE LambdaCase #-}
module Miso.UI.Dialog
(
DialogProps (..)
, defaultDialogProps
, dialog_
, dialogHeader_
, dialogSection_
, dialogFooter_
, dialogCloseButton_
, dialogComponent
, dialogCodeSample
, dialogPropsApi
) where
import Control.Monad
import Miso
import qualified Miso.CSS as CSS
import qualified Miso.Html.Element as H
import qualified Miso.Html.Event as E
import qualified Miso.Html.Property as P
import Miso.Lens
import Miso.UI.Button
import Miso.UI.Icons
import Miso.UI.Input
import Miso.UI.Label
import Miso.UI.Types
data DialogProps action
= DialogProps
{ forall action. DialogProps action -> MisoString
dialogId :: MisoString
, forall action. DialogProps action -> [MisoString]
dialogClasses :: [MisoString]
, forall action. DialogProps action -> [Attribute action]
dialogAttrs :: [Attribute action]
}
defaultDialogProps :: DialogProps action
defaultDialogProps :: forall action. DialogProps action
defaultDialogProps
= DialogProps
{ dialogId :: MisoString
dialogId = MisoString
"dialog"
, dialogClasses :: [MisoString]
dialogClasses = [ MisoString
"w-full", MisoString
"sm:max-w-[425px]", MisoString
"max-h-[612px]" ]
, dialogAttrs :: [Attribute action]
dialogAttrs = []
}
dialog_
:: DialogProps action
-> [View model action]
-> View model action
dialog_ :: forall action model.
DialogProps action -> [View model action] -> View model action
dialog_ DialogProps {[MisoString]
[Attribute action]
MisoString
dialogId :: forall action. DialogProps action -> MisoString
dialogClasses :: forall action. DialogProps action -> [MisoString]
dialogAttrs :: forall action. DialogProps action -> [Attribute action]
dialogId :: MisoString
dialogClasses :: [MisoString]
dialogAttrs :: [Attribute action]
..} [View model action]
kids =
[Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.dialog_
( [[Attribute action]] -> [Attribute action]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.id_ MisoString
dialogId
, [MisoString] -> Attribute action
forall action. [MisoString] -> Attribute action
P.classes_ (MisoString
"dialog" MisoString -> [MisoString] -> [MisoString]
forall a. a -> [a] -> [a]
: [MisoString]
dialogClasses)
, MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"labelledby" (MisoString
dialogId MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-title")
, MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"describedby" (MisoString
dialogId MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-description")
]
, [Attribute action]
dialogAttrs
]
) [View model action]
kids
dialogHeader_
:: MisoString
-> [View model action]
-> [View model action]
-> View model action
MisoString
did [View model action]
title [View model action]
description =
[Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.header_ []
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.h2_ [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.id_ (MisoString
did MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-title") ] [View model action]
title
, [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.p_ [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.id_ (MisoString
did MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-description") ] [View model action]
description
]
dialogSection_
:: [Attribute action]
-> [View model action]
-> View model action
dialogSection_ :: forall action model.
[Attribute action] -> [View model action] -> View model action
dialogSection_ = [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.section_
dialogFooter_
:: [Attribute action]
-> [View model action]
-> View model action
= [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.footer_
dialogCloseButton_ :: action -> View model action
dialogCloseButton_ :: forall action model. action -> View model action
dialogCloseButton_ action
close =
[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.type_ MisoString
"button"
, MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"label" MisoString
"Close dialog"
, [Style] -> Attribute action
forall action. [Style] -> Attribute action
CSS.style_ [ MisoString -> Style
CSS.cursor MisoString
"pointer" ]
, action -> Attribute action
forall action. action -> Attribute action
E.onClick action
close
]
[ [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
xIcon [] ]
data Action
= ShowDialog MisoString DOMRef
| CloseDialog
| NoOp
dialogComponent :: Component parent props MisoString Action
dialogComponent :: forall parent props. Component parent props MisoString Action
dialogComponent = MisoString
-> (Action -> Effect parent props MisoString Action)
-> (props -> MisoString -> View MisoString Action)
-> Component parent props MisoString Action
forall model action parent props.
model
-> (action -> Effect parent props model action)
-> (props -> model -> View model action)
-> Component parent props model action
component MisoString
"" Action -> Effect parent props MisoString Action
forall {parent} {props} {action}.
Action
-> RWST
(ComponentInfo parent props)
[Schedule action]
MisoString
Identity
()
update_ ((props -> MisoString -> View MisoString Action)
-> Component parent props MisoString Action)
-> (props -> MisoString -> View MisoString Action)
-> Component parent props MisoString Action
forall a b. (a -> b) -> a -> b
$ \props
_ MisoString
_ -> View MisoString Action
view_
where
update_ :: Action
-> RWST
(ComponentInfo parent props)
[Schedule action]
MisoString
Identity
()
update_ Action
NoOp = ()
-> RWST
(ComponentInfo parent props)
[Schedule action]
MisoString
Identity
()
forall a.
a
-> RWST
(ComponentInfo parent props)
[Schedule action]
MisoString
Identity
a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
update_ (ShowDialog MisoString
sel JSVal
domRef) = do
Lens MisoString MisoString
forall a. Lens a a
this Lens MisoString MisoString
-> MisoString
-> RWST
(ComponentInfo parent props)
[Schedule action]
MisoString
Identity
()
forall record (m :: * -> *) field.
MonadState record m =>
Lens record field -> field -> m ()
.= MisoString
sel
IO ()
-> RWST
(ComponentInfo parent props)
[Schedule action]
MisoString
Identity
()
forall parent props model action.
IO () -> Effect parent props model action
io_ (IO ()
-> RWST
(ComponentInfo parent props)
[Schedule action]
MisoString
Identity
())
-> IO ()
-> RWST
(ComponentInfo parent props)
[Schedule action]
MisoString
Identity
()
forall a b. (a -> b) -> a -> b
$ do
dialogRef <- JSVal -> IO JSVal
nextSibling JSVal
domRef
void $ dialogRef # ("showModal" :: MisoString) $ ()
update_ Action
CloseDialog = do
sel <- Lens MisoString MisoString
-> RWST
(ComponentInfo parent props)
[Schedule action]
MisoString
Identity
MisoString
forall record (m :: * -> *) field.
MonadState record m =>
Lens record field -> m field
use Lens MisoString MisoString
forall a. Lens a a
this
io_ $ do
dialog <- jsg "document"
# ("getElementById" :: MisoString)
$ [sel :: MisoString]
void $ dialog # ("close" :: MisoString) $ ()
view_ :: View MisoString Action
view_ :: View MisoString Action
view_ =
[Attribute Action]
-> [View MisoString Action] -> View MisoString 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-4" ]
[ ButtonProps Action
-> [View MisoString Action] -> View MisoString Action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps (ZonkAny 0)
forall action. ButtonProps action
defaultButtonProps
{ buttonVariant = Outline
, buttonAttrs = [ P.type_ "button", E.onClickWith (ShowDialog "demo-dialog-edit-profile") ]
}
[ View MisoString Action
"Edit Profile" ]
, DialogProps Action
-> [View MisoString Action] -> View MisoString Action
forall action model.
DialogProps action -> [View model action] -> View model action
dialog_ DialogProps (ZonkAny 1)
forall action. DialogProps action
defaultDialogProps
{ dialogId = "demo-dialog-edit-profile"
, dialogAttrs = [ E.onClick CloseDialog ]
}
[ [Attribute Action]
-> [View MisoString Action] -> View MisoString Action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
[ Options -> Action -> Attribute Action
forall action. Options -> action -> Attribute action
E.onClickWithOptions Options
stopPropagation Action
NoOp ]
[ MisoString
-> [View MisoString Action]
-> [View MisoString Action]
-> View MisoString Action
forall model action.
MisoString
-> [View model action] -> [View model action] -> View model action
dialogHeader_ MisoString
"demo-dialog-edit-profile"
[ View MisoString Action
"Edit profile" ]
[ View MisoString Action
"Make changes to your profile here. Click save when you're done." ]
, [Attribute Action]
-> [View MisoString Action] -> View MisoString Action
forall action model.
[Attribute action] -> [View model action] -> View model action
dialogSection_ []
[ [Attribute Action]
-> [View MisoString Action] -> View MisoString Action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.form_
[ MisoString -> Attribute Action
forall action. MisoString -> Attribute action
P.class_ MisoString
"form grid gap-4" ]
[ [Attribute Action]
-> [View MisoString Action] -> View MisoString 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
"grid gap-3" ]
[ LabelProps Action
-> [View MisoString Action] -> View MisoString Action
forall action model.
LabelProps action -> [View model action] -> View model action
label_ LabelProps Action
forall action. LabelProps action
defaultLabelProps { labelFor = Just "demo-dialog-edit-profile-name" }
[ View MisoString Action
"Name" ]
, InputProps Action -> View MisoString Action
forall action model. InputProps action -> View model action
input_ InputProps Action
forall action. InputProps action
defaultInputProps { inputId = Just "demo-dialog-edit-profile-name" }
]
, [Attribute Action]
-> [View MisoString Action] -> View MisoString 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
"grid gap-3" ]
[ LabelProps Action
-> [View MisoString Action] -> View MisoString Action
forall action model.
LabelProps action -> [View model action] -> View model action
label_ LabelProps Action
forall action. LabelProps action
defaultLabelProps { labelFor = Just "demo-dialog-edit-profile-username" }
[ View MisoString Action
"Username" ]
, InputProps Action -> View MisoString Action
forall action model. InputProps action -> View model action
input_ InputProps Action
forall action. InputProps action
defaultInputProps { inputId = Just "demo-dialog-edit-profile-username" }
]
]
]
, [Attribute Action]
-> [View MisoString Action] -> View MisoString Action
forall action model.
[Attribute action] -> [View model action] -> View model action
dialogFooter_ []
[ ButtonProps Action
-> [View MisoString Action] -> View MisoString Action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps (ZonkAny 2)
forall action. ButtonProps action
defaultButtonProps
{ buttonVariant = Outline, buttonAttrs = [ E.onClick CloseDialog ] }
[ View MisoString Action
"Cancel" ]
, ButtonProps Action
-> [View MisoString Action] -> View MisoString Action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps (ZonkAny 3)
forall action. ButtonProps action
defaultButtonProps
{ buttonAttrs = [ E.onClick CloseDialog ] }
[ View MisoString Action
"Save changes" ]
]
, Action -> View MisoString Action
forall action model. action -> View model action
dialogCloseButton_ Action
CloseDialog
]
]
, ButtonProps Action
-> [View MisoString Action] -> View MisoString Action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps (ZonkAny 4)
forall action. ButtonProps action
defaultButtonProps
{ buttonVariant = Outline
, buttonAttrs = [ P.type_ "button", E.onClickWith (ShowDialog "dialog-example") ]
}
[ View MisoString Action
"Scrollable Content" ]
, DialogProps Action
-> [View MisoString Action] -> View MisoString Action
forall action model.
DialogProps action -> [View model action] -> View model action
dialog_ DialogProps (ZonkAny 5)
forall action. DialogProps action
defaultDialogProps
{ dialogId = "dialog-example"
, dialogAttrs = [ E.onClick CloseDialog ]
}
[ [Attribute Action]
-> [View MisoString Action] -> View MisoString Action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
[ Options -> Action -> Attribute Action
forall action. Options -> action -> Attribute action
E.onClickWithOptions Options
stopPropagation Action
NoOp ]
[ MisoString
-> [View MisoString Action]
-> [View MisoString Action]
-> View MisoString Action
forall model action.
MisoString
-> [View model action] -> [View model action] -> View model action
dialogHeader_ MisoString
"dialog-example"
[ View MisoString Action
"Scrollable Content" ]
[ View MisoString Action
"This is a dialog with scrollable content." ]
, [Attribute Action]
-> [View MisoString Action] -> View MisoString Action
forall action model.
[Attribute action] -> [View model action] -> View model action
dialogSection_
[ MisoString -> Attribute Action
forall action. MisoString -> Attribute action
P.class_ MisoString
"overflow-y-auto scrollbar" ]
[ [Attribute Action]
-> [View MisoString Action] -> View MisoString 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
"space-y-4 text-sm" ]
[ [Attribute Action]
-> [View MisoString Action] -> View MisoString Action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.p_ [] [ View MisoString Action
lorem ] | Int
_ <- [ (Int
1 :: Int) .. Int
10 ] ]
]
, [Attribute Action]
-> [View MisoString Action] -> View MisoString Action
forall action model.
[Attribute action] -> [View model action] -> View model action
dialogFooter_ []
[ ButtonProps Action
-> [View MisoString Action] -> View MisoString Action
forall action model.
ButtonProps action -> [View model action] -> View model action
button_ ButtonProps (ZonkAny 6)
forall action. ButtonProps action
defaultButtonProps
{ buttonVariant = Outline, buttonAttrs = [ E.onClick CloseDialog ] }
[ View MisoString Action
"Close" ]
]
, Action -> View MisoString Action
forall action model. action -> View model action
dialogCloseButton_ Action
CloseDialog
]
]
]
where
lorem :: View MisoString Action
lorem =
View MisoString Action
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
dialogCodeSample :: View model action
dialogCodeSample :: forall model action. View model action
dialogCodeSample =
View model action
"""
-----------------------------------------------------------------------------
module MyDialog (dialogComponent) where
-----------------------------------------------------------------------------
import Control.Monad
import Miso
import Miso.Html.Event
import Miso.Lens
import qualified Miso.Html as H
import qualified Miso.Html.Property as P
-----------------------------------------------------------------------------
import Miso.UI.Button
import Miso.UI.Dialog
import Miso.UI.Types
-----------------------------------------------------------------------------
data Action
= ShowDialog MisoString DOMRef
| CloseDialog
| NoOp
-----------------------------------------------------------------------------
dialogComponent :: Component parent props MisoString Action
dialogComponent = component "" update_ $ \\_ _ ->
H.div_ []
[ button_ defaultButtonProps
{ buttonVariant = Outline
, buttonAttrs = [ onClickWith (ShowDialog "my-dialog") ]
}
[ "Edit Profile" ]
, dialog_ defaultDialogProps
{ dialogId = "my-dialog"
, dialogAttrs = [ onClick CloseDialog ]
}
[ H.div_
[ onClickWithOptions stopPropagation NoOp ]
[ dialogHeader_ "my-dialog"
[ "Edit profile" ]
[ "Make changes to your profile here." ]
, dialogFooter_ []
[ button_ defaultButtonProps
{ buttonAttrs = [ onClick CloseDialog ] }
[ "Save changes" ]
]
, dialogCloseButton_ CloseDialog
]
]
]
where
update_ NoOp = pure ()
update_ (ShowDialog sel domRef) = do
this .= sel
io_ $ do
dialogRef <- nextSibling domRef
void $ dialogRef # ("showModal" :: MisoString) $ ()
update_ CloseDialog = do
sel <- use this
io_ $ do
dialog <- jsg "document"
# ("getElementById" :: MisoString)
$ [sel :: MisoString]
void $ dialog # ("close" :: MisoString) $ ()
"""
dialogPropsApi :: View model action
dialogPropsApi :: forall model action. View model action
dialogPropsApi =
View model action
"""
-- | Props for 'dialog_' (the native @dialog@ element)
data DialogProps action
= DialogProps
{ dialogId :: MisoString
-- ^ id of the dialog; @-title@ \\/ @-description@ ids derive from it
, dialogClasses :: [MisoString]
-- ^ Extra classes appended to @dialog.dialog@
, dialogAttrs :: [Attribute action]
}
-----------------------------------------------------------------------------
-- | Smart constructor
defaultDialogProps :: DialogProps action
defaultDialogProps
= DialogProps
{ dialogId = "dialog"
, dialogClasses = [ "w-full", "sm:max-w-[425px]", "max-h-[612px]" ]
, dialogAttrs = []
}
"""