Skip to content

Instantly share code, notes, and snippets.

@pete-murphy
Last active September 4, 2022 00:26
Show Gist options
  • Save pete-murphy/5605231047155a3bf4b834daa03b510e to your computer and use it in GitHub Desktop.
Save pete-murphy/5605231047155a3bf4b834daa03b510e to your computer and use it in GitHub Desktop.
Halogen click
module Main where
import Prelude
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Effect.Aff (Aff, delay, Milliseconds(..))
import Halogen as H
import Halogen.Aff as HA
import Halogen.HTML as HH
import Halogen.HTML.Events as HE
import Halogen.VDom.Driver (runUI)
import Type.Proxy (Proxy(..))
import Data.Foldable (traverse_)
type Slots =
( button1 :: forall q i. H.Slot q i Unit
, button2 :: forall q i. H.Slot q i Unit
)
main :: Effect Unit
main = HA.runHalogenAff do
body <- HA.awaitBody
runUI component unit body
component =
H.mkComponent
{ initialState: \_ -> unit
, render
, eval: H.mkEval $ H.defaultEval { handleAction = absurd }
}
where
render :: _ -> H.ComponentHTML Void Slots Aff
render state =
HH.div_
[ HH.p_ [ HH.text "button1 has minimal state, but doesn't always keep success message displayed with repeated clicks" ]
, HH.slot_ (Proxy :: _ "button1") unit button1 unit
, HH.p_ [ HH.text "button2 keeps the success message displayed with repeated clicks, but state is more complicated" ]
, HH.slot_ (Proxy :: _ "button2") unit button2 unit
]
-------------------------------------------------------------------------
-------------------------------------------------------------------------
button1 =
H.mkComponent
{ initialState: \_ -> Nothing
, render
, eval: H.mkEval $ H.defaultEval { handleAction = handleAction }
}
where
render :: Maybe Boolean -> H.ComponentHTML Unit () Aff
render state = do
let
message = case state of
Just true -> "✅ Copied to clipboard"
Just false -> "❌ Failed to copy to clipboard"
Nothing -> "Click me"
HH.button [ HE.onClick \_ -> unit ] [ HH.text message ]
handleAction _ = do
H.modify_ \_ -> Just true
H.liftAff (delay (1_000.0 # Milliseconds))
H.modify_ \_ -> Nothing
-------------------------------------------------------------------------
-------------------------------------------------------------------------
type Button2State =
{ showNotification :: Maybe Boolean
, forkId :: Maybe H.ForkId
}
button2 =
H.mkComponent
{ initialState: \_ -> { showNotification: Nothing, forkId: Nothing }
, render
, eval: H.mkEval $ H.defaultEval { handleAction = handleAction }
}
where
render :: Button2State -> H.ComponentHTML Unit () Aff
render state = do
let
message = case state.showNotification of
Just true -> "✅ Copied to clipboard"
Just false -> "❌ Failed to copy to clipboard"
Nothing -> "Click me"
HH.button [ HE.onClick \_ -> unit ] [ HH.text message ]
handleAction _ = do
H.gets _.forkId >>= traverse_ H.kill
H.modify_ _ { showNotification = Just true }
forkId <- H.fork do
H.liftAff (delay (1_000.0 # Milliseconds))
H.modify_ _ { showNotification = Nothing }
H.modify_ _ { forkId = Just forkId }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment