{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecursiveDo #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
module Reflex.Dom.Widget.Basic
  (
  -- * Displaying Values
    text
  , dynText
  , comment
  , dynComment
  , display
  , button
  , dyn
  , dyn_
  , widgetHold
  , widgetHold_

  -- * Creating DOM Elements
  , el
  , elAttr
  , elClass
  , elDynAttr
  , elDynClass
  , elDynAttrNS

  -- ** With Element Results
  , el'
  , elAttr'
  , elClass'
  , elDynAttr'
  , elDynClass'
  , elDynAttrNS'
  , dynamicAttributesToModifyAttributes
  , dynamicAttributesToModifyAttributesWithInitial

  -- * Specific DOM Elements
  , Link (..)
  , linkClass
  , link
  , divClass
  , dtdd
  , blank

  -- * Tables and Lists
  , tableDynAttr
  , tabDisplay

  , HasAttributes (..)
  , module Data.Map.Misc
  , module Reflex.Collection
  , module Reflex.Workflow
  , partitionMapBySetLT
  ) where

import Reflex.Adjustable.Class
import Reflex.Class
import Reflex.Collection
import Reflex.Dom.Builder.Class
import Reflex.Dom.Class
import Reflex.Dynamic
import Reflex.Network
import Reflex.PostBuild.Class
import Reflex.Workflow

import Control.Arrow
import Control.Lens hiding (children, element)
import Control.Monad.Reader hiding (forM, forM_, mapM, mapM_, sequence, sequence_)
import Data.Align
import Data.Default
import Data.Either
import Data.Foldable
import Data.Functor (void)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Map.Misc
import Data.Maybe
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Text (Text)
import qualified Data.Text as T
import Data.These
import Data.Traversable
import Prelude hiding (mapM, mapM_, sequence, sequence_)

-- | Breaks the given Map into pieces based on the given Set.  Each piece will contain only keys that are less than the key of the piece, and greater than or equal to the key of the piece with the next-smaller key.  There will be one additional piece containing all keys from the original Map that are larger or equal to the largest key in the Set.
-- Either k () is used instead of Maybe k so that the resulting map of pieces is sorted so that the additional piece has the largest key.
-- No empty pieces will be included in the output.

--TODO: This can probably be done more efficiently by dividing and conquering, re-using the structure of the Set instead of going through the Set linearally
{-# DEPRECATED partitionMapBySetLT "This will be removed in future releases." #-}
partitionMapBySetLT :: forall k v. Ord k => Set k -> Map k v -> Map (Either k ()) (Map k v)
partitionMapBySetLT :: Set k -> Map k v -> Map (Either k ()) (Map k v)
partitionMapBySetLT s :: Set k
s m0 :: Map k v
m0 = [(Either k (), Map k v)] -> Map (Either k ()) (Map k v)
forall k a. [(k, a)] -> Map k a
Map.fromDistinctAscList ([(Either k (), Map k v)] -> Map (Either k ()) (Map k v))
-> [(Either k (), Map k v)] -> Map (Either k ()) (Map k v)
forall a b. (a -> b) -> a -> b
$ [k] -> Map k v -> [(Either k (), Map k v)]
go (Set k -> [k]
forall a. Set a -> [a]
Set.toAscList Set k
s) Map k v
m0
  where go :: [k] -> Map k v -> [(Either k (), Map k v)]
        go :: [k] -> Map k v -> [(Either k (), Map k v)]
go [] m :: Map k v
m = if Map k v -> Bool
forall k a. Map k a -> Bool
Map.null Map k v
m
                  then []
                  else [(() -> Either k ()
forall a b. b -> Either a b
Right (), Map k v
m)]
        go (h :: k
h:t :: [k]
t) m :: Map k v
m = let (lt :: Map k v
lt, eq :: Maybe v
eq, gt :: Map k v
gt) = k -> Map k v -> (Map k v, Maybe v, Map k v)
forall k a. Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)
Map.splitLookup k
h Map k v
m
                         geq :: Map k v
geq = (Map k v -> Map k v)
-> (v -> Map k v -> Map k v) -> Maybe v -> Map k v -> Map k v
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Map k v -> Map k v
forall a. a -> a
id (k -> v -> Map k v -> Map k v
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert k
h) Maybe v
eq Map k v
gt
                     in if Map k v -> Bool
forall k a. Map k a -> Bool
Map.null Map k v
lt
                        then [k] -> Map k v -> [(Either k (), Map k v)]
go [k]
t Map k v
geq
                        else (k -> Either k ()
forall a b. a -> Either a b
Left k
h, Map k v
lt) (Either k (), Map k v)
-> [(Either k (), Map k v)] -> [(Either k (), Map k v)]
forall a. a -> [a] -> [a]
: [k] -> Map k v -> [(Either k (), Map k v)]
go [k]
t Map k v
geq

{-# INLINABLE text #-}
text :: DomBuilder t m => Text -> m ()
text :: Text -> m ()
text t :: Text
t = m (TextNode (DomBuilderSpace m) t) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (TextNode (DomBuilderSpace m) t) -> m ())
-> m (TextNode (DomBuilderSpace m) t) -> m ()
forall a b. (a -> b) -> a -> b
$ TextNodeConfig t -> m (TextNode (DomBuilderSpace m) t)
forall t (m :: * -> *).
DomBuilder t m =>
TextNodeConfig t -> m (TextNode (DomBuilderSpace m) t)
textNode (TextNodeConfig t -> m (TextNode (DomBuilderSpace m) t))
-> TextNodeConfig t -> m (TextNode (DomBuilderSpace m) t)
forall a b. (a -> b) -> a -> b
$ TextNodeConfig t
forall a. Default a => a
def TextNodeConfig t
-> (TextNodeConfig t -> TextNodeConfig t) -> TextNodeConfig t
forall a b. a -> (a -> b) -> b
& (Text -> Identity Text)
-> TextNodeConfig t -> Identity (TextNodeConfig t)
forall k (t :: k). Lens' (TextNodeConfig t) Text
textNodeConfig_initialContents ((Text -> Identity Text)
 -> TextNodeConfig t -> Identity (TextNodeConfig t))
-> Text -> TextNodeConfig t -> TextNodeConfig t
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Text
t

{-# INLINABLE dynText #-}
dynText :: forall t m. (PostBuild t m, DomBuilder t m) => Dynamic t Text -> m ()
dynText :: Dynamic t Text -> m ()
dynText t :: Dynamic t Text
t = do
  Event t ()
postBuild <- m (Event t ())
forall t (m :: * -> *). PostBuild t m => m (Event t ())
getPostBuild
  m (TextNode (DomBuilderSpace m) t) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (TextNode (DomBuilderSpace m) t) -> m ())
-> m (TextNode (DomBuilderSpace m) t) -> m ()
forall a b. (a -> b) -> a -> b
$ TextNodeConfig t -> m (TextNode (DomBuilderSpace m) t)
forall t (m :: * -> *).
DomBuilder t m =>
TextNodeConfig t -> m (TextNode (DomBuilderSpace m) t)
textNode (TextNodeConfig t -> m (TextNode (DomBuilderSpace m) t))
-> TextNodeConfig t -> m (TextNode (DomBuilderSpace m) t)
forall a b. (a -> b) -> a -> b
$ (TextNodeConfig t
forall a. Default a => a
def :: TextNodeConfig t) TextNodeConfig t
-> (TextNodeConfig t -> TextNodeConfig t) -> TextNodeConfig t
forall a b. a -> (a -> b) -> b
& (Event t Text -> Identity (Event t Text))
-> TextNodeConfig t -> Identity (TextNodeConfig t)
forall k (t :: k).
Reflex t =>
Lens' (TextNodeConfig t) (Event t Text)
textNodeConfig_setContents ((Event t Text -> Identity (Event t Text))
 -> TextNodeConfig t -> Identity (TextNodeConfig t))
-> Event t Text -> TextNodeConfig t -> TextNodeConfig t
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [Event t Text] -> Event t Text
forall k (t :: k) a. Reflex t => [Event t a] -> Event t a
leftmost
    [ Dynamic t Text -> Event t Text
forall k (t :: k) a. Reflex t => Dynamic t a -> Event t a
updated Dynamic t Text
t
    , Behavior t Text -> Event t () -> Event t Text
forall k (t :: k) b a.
Reflex t =>
Behavior t b -> Event t a -> Event t b
tag (Dynamic t Text -> Behavior t Text
forall k (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t Text
t) Event t ()
postBuild
    ]
  Event t () -> m ()
forall t (m :: * -> *) a. NotReady t m => Event t a -> m ()
notReadyUntil Event t ()
postBuild

comment :: DomBuilder t m => Text -> m ()
comment :: Text -> m ()
comment t :: Text
t = m (CommentNode (DomBuilderSpace m) t) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (CommentNode (DomBuilderSpace m) t) -> m ())
-> m (CommentNode (DomBuilderSpace m) t) -> m ()
forall a b. (a -> b) -> a -> b
$ CommentNodeConfig t -> m (CommentNode (DomBuilderSpace m) t)
forall t (m :: * -> *).
DomBuilder t m =>
CommentNodeConfig t -> m (CommentNode (DomBuilderSpace m) t)
commentNode (CommentNodeConfig t -> m (CommentNode (DomBuilderSpace m) t))
-> CommentNodeConfig t -> m (CommentNode (DomBuilderSpace m) t)
forall a b. (a -> b) -> a -> b
$ CommentNodeConfig t
forall a. Default a => a
def CommentNodeConfig t
-> (CommentNodeConfig t -> CommentNodeConfig t)
-> CommentNodeConfig t
forall a b. a -> (a -> b) -> b
& (Text -> Identity Text)
-> CommentNodeConfig t -> Identity (CommentNodeConfig t)
forall k (t :: k). Lens' (CommentNodeConfig t) Text
commentNodeConfig_initialContents ((Text -> Identity Text)
 -> CommentNodeConfig t -> Identity (CommentNodeConfig t))
-> Text -> CommentNodeConfig t -> CommentNodeConfig t
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Text
t

{-# INLINABLE dynComment #-}
dynComment :: forall t m. (PostBuild t m, DomBuilder t m) => Dynamic t Text -> m ()
dynComment :: Dynamic t Text -> m ()
dynComment t :: Dynamic t Text
t = do
  Event t ()
postBuild <- m (Event t ())
forall t (m :: * -> *). PostBuild t m => m (Event t ())
getPostBuild
  m (CommentNode (DomBuilderSpace m) t) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (CommentNode (DomBuilderSpace m) t) -> m ())
-> m (CommentNode (DomBuilderSpace m) t) -> m ()
forall a b. (a -> b) -> a -> b
$ CommentNodeConfig t -> m (CommentNode (DomBuilderSpace m) t)
forall t (m :: * -> *).
DomBuilder t m =>
CommentNodeConfig t -> m (CommentNode (DomBuilderSpace m) t)
commentNode (CommentNodeConfig t -> m (CommentNode (DomBuilderSpace m) t))
-> CommentNodeConfig t -> m (CommentNode (DomBuilderSpace m) t)
forall a b. (a -> b) -> a -> b
$ (CommentNodeConfig t
forall a. Default a => a
def :: CommentNodeConfig t) CommentNodeConfig t
-> (CommentNodeConfig t -> CommentNodeConfig t)
-> CommentNodeConfig t
forall a b. a -> (a -> b) -> b
& (Event t Text -> Identity (Event t Text))
-> CommentNodeConfig t -> Identity (CommentNodeConfig t)
forall k (t :: k).
Reflex t =>
Lens
  (CommentNodeConfig t)
  (CommentNodeConfig t)
  (Event t Text)
  (Event t Text)
commentNodeConfig_setContents ((Event t Text -> Identity (Event t Text))
 -> CommentNodeConfig t -> Identity (CommentNodeConfig t))
-> Event t Text -> CommentNodeConfig t -> CommentNodeConfig t
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [Event t Text] -> Event t Text
forall k (t :: k) a. Reflex t => [Event t a] -> Event t a
leftmost
    [ Dynamic t Text -> Event t Text
forall k (t :: k) a. Reflex t => Dynamic t a -> Event t a
updated Dynamic t Text
t
    , Behavior t Text -> Event t () -> Event t Text
forall k (t :: k) b a.
Reflex t =>
Behavior t b -> Event t a -> Event t b
tag (Dynamic t Text -> Behavior t Text
forall k (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t Text
t) Event t ()
postBuild
    ]
  Event t () -> m ()
forall t (m :: * -> *) a. NotReady t m => Event t a -> m ()
notReadyUntil Event t ()
postBuild

display :: (PostBuild t m, DomBuilder t m, Show a) => Dynamic t a -> m ()
display :: Dynamic t a -> m ()
display = Dynamic t Text -> m ()
forall t (m :: * -> *).
(PostBuild t m, DomBuilder t m) =>
Dynamic t Text -> m ()
dynText (Dynamic t Text -> m ())
-> (Dynamic t a -> Dynamic t Text) -> Dynamic t a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Text) -> Dynamic t a -> Dynamic t Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> Text
T.pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show)

button :: DomBuilder t m => Text -> m (Event t ())
button :: Text -> m (Event t ())
button t :: Text
t = do
  (e :: Element EventResult (DomBuilderSpace m) t
e, _) <- Text
-> ElementConfig EventResult t (DomBuilderSpace m)
-> m ()
-> m (Element EventResult (DomBuilderSpace m) t, ())
forall t (m :: * -> *) (er :: EventTag -> *) a.
DomBuilder t m =>
Text
-> ElementConfig er t (DomBuilderSpace m)
-> m a
-> m (Element er (DomBuilderSpace m) t, a)
element "button" ElementConfig EventResult t (DomBuilderSpace m)
forall a. Default a => a
def (m () -> m (Element EventResult (DomBuilderSpace m) t, ()))
-> m () -> m (Element EventResult (DomBuilderSpace m) t, ())
forall a b. (a -> b) -> a -> b
$ Text -> m ()
forall t (m :: * -> *). DomBuilder t m => Text -> m ()
text Text
t
  Event t () -> m (Event t ())
forall (m :: * -> *) a. Monad m => a -> m a
return (Event t () -> m (Event t ())) -> Event t () -> m (Event t ())
forall a b. (a -> b) -> a -> b
$ EventName 'ClickTag
-> Element EventResult (DomBuilderSpace m) t
-> Event
     t
     (DomEventType
        (Element EventResult (DomBuilderSpace m) t) 'ClickTag)
forall k (t :: k) target (eventName :: EventTag).
HasDomEvent t target eventName =>
EventName eventName
-> target -> Event t (DomEventType target eventName)
domEvent EventName 'ClickTag
Click Element EventResult (DomBuilderSpace m) t
e

--TODO: Should this be renamed to 'widgetView' for consistency with 'widgetHold'?
-- | Given a Dynamic of widget-creating actions, create a widget that is recreated whenever the Dynamic updates.
--   The returned Event occurs whenever the child widget is updated, which is
--   at post-build in addition to the times at which the input Dynamic is
--   updated, and its value is the result of running the widget.
--   Note:  Often, the type @a@ is an 'Event', in which case the return value is an Event-of-Events that would typically be flattened (via 'switchHold').
dyn :: (Adjustable t m, NotReady t m, PostBuild t m) => Dynamic t (m a) -> m (Event t a)
dyn :: Dynamic t (m a) -> m (Event t a)
dyn = Dynamic t (m a) -> m (Event t a)
forall t (m :: * -> *) a.
(NotReady t m, Adjustable t m, PostBuild t m) =>
Dynamic t (m a) -> m (Event t a)
networkView

-- | Like 'dyn' but discards result.
dyn_ :: (Adjustable t m, NotReady t m, PostBuild t m) => Dynamic t (m a) -> m ()
dyn_ :: Dynamic t (m a) -> m ()
dyn_ = m (Event t a) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (Event t a) -> m ())
-> (Dynamic t (m a) -> m (Event t a)) -> Dynamic t (m a) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dynamic t (m a) -> m (Event t a)
forall t (m :: * -> *) a.
(Adjustable t m, NotReady t m, PostBuild t m) =>
Dynamic t (m a) -> m (Event t a)
dyn

-- | Given an initial widget and an Event of widget-creating actions, create a widget that is recreated whenever the Event fires.
--   The returned Dynamic of widget results occurs when the Event does.
--   Note:  Often, the type 'a' is an Event, in which case the return value is a Dynamic-of-Events that would typically be flattened (via 'switchDyn').
widgetHold :: (Adjustable t m, MonadHold t m) => m a -> Event t (m a) -> m (Dynamic t a)
widgetHold :: m a -> Event t (m a) -> m (Dynamic t a)
widgetHold = m a -> Event t (m a) -> m (Dynamic t a)
forall t (m :: * -> *) a.
(Adjustable t m, MonadHold t m) =>
m a -> Event t (m a) -> m (Dynamic t a)
networkHold

-- | Like 'widgetHold' but discards result.
widgetHold_ :: (Adjustable t m, MonadHold t m) => m a -> Event t (m a) -> m ()
widgetHold_ :: m a -> Event t (m a) -> m ()
widgetHold_ z :: m a
z = m (Dynamic t a) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (Dynamic t a) -> m ())
-> (Event t (m a) -> m (Dynamic t a)) -> Event t (m a) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> Event t (m a) -> m (Dynamic t a)
forall t (m :: * -> *) a.
(Adjustable t m, MonadHold t m) =>
m a -> Event t (m a) -> m (Dynamic t a)
widgetHold m a
z

-- | Create a DOM element
--
-- >>> el "div" (text "Hello World")
-- <div>Hello World</div>
{-# INLINABLE el #-}
el :: forall t m a. DomBuilder t m => Text -> m a -> m a
el :: Text -> m a -> m a
el elementTag :: Text
elementTag child :: m a
child = (Element EventResult (DomBuilderSpace m) t, a) -> a
forall a b. (a, b) -> b
snd ((Element EventResult (DomBuilderSpace m) t, a) -> a)
-> m (Element EventResult (DomBuilderSpace m) t, a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) a.
DomBuilder t m =>
Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
el' Text
elementTag m a
child

-- | Create a DOM element with attributes
--
-- >>> elAttr "a" ("href" =: "https://reflex-frp.org") (text "Reflex-FRP!")
-- <a href="https://reflex-frp.org">Reflex-FRP!</a>
{-# INLINABLE elAttr #-}
elAttr :: forall t m a. DomBuilder t m => Text -> Map Text Text -> m a -> m a
elAttr :: Text -> Map Text Text -> m a -> m a
elAttr elementTag :: Text
elementTag attrs :: Map Text Text
attrs child :: m a
child = (Element EventResult (DomBuilderSpace m) t, a) -> a
forall a b. (a, b) -> b
snd ((Element EventResult (DomBuilderSpace m) t, a) -> a)
-> m (Element EventResult (DomBuilderSpace m) t, a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text
-> Map Text Text
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) a.
DomBuilder t m =>
Text
-> Map Text Text
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elAttr' Text
elementTag Map Text Text
attrs m a
child

-- | Create a DOM element with classes
--
-- >>> elClass "div" "row" (return ())
-- <div class="row"></div>
{-# INLINABLE elClass #-}
elClass :: forall t m a. DomBuilder t m => Text -> Text -> m a -> m a
elClass :: Text -> Text -> m a -> m a
elClass elementTag :: Text
elementTag c :: Text
c child :: m a
child = (Element EventResult (DomBuilderSpace m) t, a) -> a
forall a b. (a, b) -> b
snd ((Element EventResult (DomBuilderSpace m) t, a) -> a)
-> m (Element EventResult (DomBuilderSpace m) t, a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text
-> Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) a.
DomBuilder t m =>
Text
-> Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
elClass' Text
elementTag Text
c m a
child

-- | Create a DOM element with Dynamic Attributes
--
-- >>> elClass "div" (constDyn ("class" =: "row")) (return ())
-- <div class="row"></div>
{-# INLINABLE elDynAttr #-}
elDynAttr :: forall t m a. (DomBuilder t m, PostBuild t m) => Text -> Dynamic t (Map Text Text) -> m a -> m a
elDynAttr :: Text -> Dynamic t (Map Text Text) -> m a -> m a
elDynAttr elementTag :: Text
elementTag attrs :: Dynamic t (Map Text Text)
attrs child :: m a
child = (Element EventResult (DomBuilderSpace m) t, a) -> a
forall a b. (a, b) -> b
snd ((Element EventResult (DomBuilderSpace m) t, a) -> a)
-> m (Element EventResult (DomBuilderSpace m) t, a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) a.
(DomBuilder t m, PostBuild t m) =>
Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elDynAttr' Text
elementTag Dynamic t (Map Text Text)
attrs m a
child

-- | Create a DOM element with a Dynamic Class
--
-- >>> elDynClass "div" (constDyn "row") (return ())
-- <div class="row"></div>
{-# INLINABLE elDynClass #-}
elDynClass :: forall t m a. (DomBuilder t m, PostBuild t m) => Text -> Dynamic t Text -> m a -> m a
elDynClass :: Text -> Dynamic t Text -> m a -> m a
elDynClass elementTag :: Text
elementTag c :: Dynamic t Text
c child :: m a
child = (Element EventResult (DomBuilderSpace m) t, a) -> a
forall a b. (a, b) -> b
snd ((Element EventResult (DomBuilderSpace m) t, a) -> a)
-> m (Element EventResult (DomBuilderSpace m) t, a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text
-> Dynamic t Text
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) a.
(DomBuilder t m, PostBuild t m) =>
Text
-> Dynamic t Text
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elDynClass' Text
elementTag Dynamic t Text
c m a
child

-- | Create a DOM element and return the element
--
-- @
--  do (e, _) <- el' "div" (text "Click")
--     return $ domEvent Click e
-- @
{-# INLINABLE el' #-}
el' :: forall t m a. DomBuilder t m => Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
el' :: Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
el' elementTag :: Text
elementTag = Text
-> ElementConfig EventResult t (DomBuilderSpace m)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) (er :: EventTag -> *) a.
DomBuilder t m =>
Text
-> ElementConfig er t (DomBuilderSpace m)
-> m a
-> m (Element er (DomBuilderSpace m) t, a)
element Text
elementTag ElementConfig EventResult t (DomBuilderSpace m)
forall a. Default a => a
def

-- | Create a DOM element with attributes and return the element
{-# INLINABLE elAttr' #-}
elAttr' :: forall t m a. DomBuilder t m => Text -> Map Text Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
elAttr' :: Text
-> Map Text Text
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elAttr' elementTag :: Text
elementTag attrs :: Map Text Text
attrs = Text
-> ElementConfig EventResult t (DomBuilderSpace m)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) (er :: EventTag -> *) a.
DomBuilder t m =>
Text
-> ElementConfig er t (DomBuilderSpace m)
-> m a
-> m (Element er (DomBuilderSpace m) t, a)
element Text
elementTag (ElementConfig EventResult t (DomBuilderSpace m)
 -> m a -> m (Element EventResult (DomBuilderSpace m) t, a))
-> ElementConfig EventResult t (DomBuilderSpace m)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall a b. (a -> b) -> a -> b
$ ElementConfig EventResult t (DomBuilderSpace m)
forall a. Default a => a
def
  ElementConfig EventResult t (DomBuilderSpace m)
-> (ElementConfig EventResult t (DomBuilderSpace m)
    -> ElementConfig EventResult t (DomBuilderSpace m))
-> ElementConfig EventResult t (DomBuilderSpace m)
forall a b. a -> (a -> b) -> b
& (Map AttributeName Text -> Identity (Map AttributeName Text))
-> ElementConfig EventResult t (DomBuilderSpace m)
-> Identity (ElementConfig EventResult t (DomBuilderSpace m))
forall a. InitialAttributes a => Lens' a (Map AttributeName Text)
initialAttributes ((Map AttributeName Text -> Identity (Map AttributeName Text))
 -> ElementConfig EventResult t (DomBuilderSpace m)
 -> Identity (ElementConfig EventResult t (DomBuilderSpace m)))
-> Map AttributeName Text
-> ElementConfig EventResult t (DomBuilderSpace m)
-> ElementConfig EventResult t (DomBuilderSpace m)
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Text -> AttributeName) -> Map Text Text -> Map AttributeName Text
forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
Map.mapKeys (Maybe Text -> Text -> AttributeName
AttributeName Maybe Text
forall a. Maybe a
Nothing) Map Text Text
attrs

-- | Create a DOM element with a class and return the element
{-# INLINABLE elClass' #-}
elClass' :: forall t m a. DomBuilder t m => Text -> Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
elClass' :: Text
-> Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
elClass' elementTag :: Text
elementTag c :: Text
c = Text
-> Map Text Text
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) a.
DomBuilder t m =>
Text
-> Map Text Text
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elAttr' Text
elementTag ("class" Index (Map Text Text) -> IxValue (Map Text Text) -> Map Text Text
forall m. (At m, Monoid m) => Index m -> IxValue m -> m
=: Text
IxValue (Map Text Text)
c)

-- | Create a DOM element with Dynamic Attributes and return the element
{-# INLINABLE elDynAttr' #-}
elDynAttr' :: forall t m a. (DomBuilder t m, PostBuild t m) => Text -> Dynamic t (Map Text Text) -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
elDynAttr' :: Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elDynAttr' = Maybe Text
-> Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) a.
(DomBuilder t m, PostBuild t m) =>
Maybe Text
-> Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elDynAttrNS' Maybe Text
forall a. Maybe a
Nothing

-- | Create a DOM element with a Dynamic class and return the element
{-# INLINABLE elDynClass' #-}
elDynClass' :: forall t m a. (DomBuilder t m, PostBuild t m) => Text -> Dynamic t Text -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
elDynClass' :: Text
-> Dynamic t Text
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elDynClass' elementTag :: Text
elementTag c :: Dynamic t Text
c = Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) a.
(DomBuilder t m, PostBuild t m) =>
Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elDynAttr' Text
elementTag ((Text -> Map Text Text)
-> Dynamic t Text -> Dynamic t (Map Text Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ("class" Index (Map Text Text) -> IxValue (Map Text Text) -> Map Text Text
forall m. (At m, Monoid m) => Index m -> IxValue m -> m
=:) Dynamic t Text
c)

{-# INLINABLE elDynAttrNS' #-}
elDynAttrNS' :: forall t m a. (DomBuilder t m, PostBuild t m) => Maybe Text -> Text -> Dynamic t (Map Text Text) -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
elDynAttrNS' :: Maybe Text
-> Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elDynAttrNS' mns :: Maybe Text
mns elementTag :: Text
elementTag attrs :: Dynamic t (Map Text Text)
attrs child :: m a
child = do
  Event t (Map Text (Maybe Text))
modifyAttrs <- Dynamic t (Map Text Text) -> m (Event t (Map Text (Maybe Text)))
forall k t (m :: * -> *).
(Ord k, PostBuild t m) =>
Dynamic t (Map k Text) -> m (Event t (Map k (Maybe Text)))
dynamicAttributesToModifyAttributes Dynamic t (Map Text Text)
attrs
  let cfg :: ElementConfig EventResult t (DomBuilderSpace m)
cfg = ElementConfig EventResult t (DomBuilderSpace m)
forall a. Default a => a
def
        ElementConfig EventResult t (DomBuilderSpace m)
-> (ElementConfig EventResult t (DomBuilderSpace m)
    -> ElementConfig EventResult t (DomBuilderSpace m))
-> ElementConfig EventResult t (DomBuilderSpace m)
forall a b. a -> (a -> b) -> b
& (Maybe Text -> Identity (Maybe Text))
-> ElementConfig EventResult t (DomBuilderSpace m)
-> Identity (ElementConfig EventResult t (DomBuilderSpace m))
forall k1 k2 (er :: EventTag -> *) (t :: k1) (s :: k2).
Lens' (ElementConfig er t s) (Maybe Text)
elementConfig_namespace ((Maybe Text -> Identity (Maybe Text))
 -> ElementConfig EventResult t (DomBuilderSpace m)
 -> Identity (ElementConfig EventResult t (DomBuilderSpace m)))
-> Maybe Text
-> ElementConfig EventResult t (DomBuilderSpace m)
-> ElementConfig EventResult t (DomBuilderSpace m)
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Maybe Text
mns
        ElementConfig EventResult t (DomBuilderSpace m)
-> (ElementConfig EventResult t (DomBuilderSpace m)
    -> ElementConfig EventResult t (DomBuilderSpace m))
-> ElementConfig EventResult t (DomBuilderSpace m)
forall a b. a -> (a -> b) -> b
& (Event t (Map AttributeName (Maybe Text))
 -> Identity (Event t (Map AttributeName (Maybe Text))))
-> ElementConfig EventResult t (DomBuilderSpace m)
-> Identity (ElementConfig EventResult t (DomBuilderSpace m))
forall k (t :: k) a.
(ModifyAttributes t a, Reflex t) =>
Lens' a (Event t (Map AttributeName (Maybe Text)))
modifyAttributes ((Event t (Map AttributeName (Maybe Text))
  -> Identity (Event t (Map AttributeName (Maybe Text))))
 -> ElementConfig EventResult t (DomBuilderSpace m)
 -> Identity (ElementConfig EventResult t (DomBuilderSpace m)))
-> Event t (Map AttributeName (Maybe Text))
-> ElementConfig EventResult t (DomBuilderSpace m)
-> ElementConfig EventResult t (DomBuilderSpace m)
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Map Text (Maybe Text) -> Map AttributeName (Maybe Text))
-> Event t (Map Text (Maybe Text))
-> Event t (Map AttributeName (Maybe Text))
forall k (t :: k) a b.
Reflex t =>
(a -> b) -> Event t a -> Event t b
fmapCheap Map Text (Maybe Text) -> Map AttributeName (Maybe Text)
forall v. Map Text v -> Map AttributeName v
mapKeysToAttributeName Event t (Map Text (Maybe Text))
modifyAttrs
  (Element EventResult (DomBuilderSpace m) t, a)
result <- Text
-> ElementConfig EventResult t (DomBuilderSpace m)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) (er :: EventTag -> *) a.
DomBuilder t m =>
Text
-> ElementConfig er t (DomBuilderSpace m)
-> m a
-> m (Element er (DomBuilderSpace m) t, a)
element Text
elementTag ElementConfig EventResult t (DomBuilderSpace m)
cfg m a
child
  Event t ()
postBuild <- m (Event t ())
forall t (m :: * -> *). PostBuild t m => m (Event t ())
getPostBuild
  Event t () -> m ()
forall t (m :: * -> *) a. NotReady t m => Event t a -> m ()
notReadyUntil Event t ()
postBuild
  (Element EventResult (DomBuilderSpace m) t, a)
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Element EventResult (DomBuilderSpace m) t, a)
result

{-# INLINABLE elDynAttrNS #-}
elDynAttrNS :: forall t m a. (DomBuilder t m, PostBuild t m) => Maybe Text -> Text -> Dynamic t (Map Text Text) -> m a -> m a
elDynAttrNS :: Maybe Text -> Text -> Dynamic t (Map Text Text) -> m a -> m a
elDynAttrNS mns :: Maybe Text
mns elementTag :: Text
elementTag attrs :: Dynamic t (Map Text Text)
attrs child :: m a
child = ((Element EventResult (DomBuilderSpace m) t, a) -> a)
-> m (Element EventResult (DomBuilderSpace m) t, a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Element EventResult (DomBuilderSpace m) t, a) -> a
forall a b. (a, b) -> b
snd (m (Element EventResult (DomBuilderSpace m) t, a) -> m a)
-> m (Element EventResult (DomBuilderSpace m) t, a) -> m a
forall a b. (a -> b) -> a -> b
$ Maybe Text
-> Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
forall t (m :: * -> *) a.
(DomBuilder t m, PostBuild t m) =>
Maybe Text
-> Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elDynAttrNS' Maybe Text
mns Text
elementTag Dynamic t (Map Text Text)
attrs m a
child

dynamicAttributesToModifyAttributes :: (Ord k, PostBuild t m) => Dynamic t (Map k Text) -> m (Event t (Map k (Maybe Text)))
dynamicAttributesToModifyAttributes :: Dynamic t (Map k Text) -> m (Event t (Map k (Maybe Text)))
dynamicAttributesToModifyAttributes = Map k Text
-> Dynamic t (Map k Text) -> m (Event t (Map k (Maybe Text)))
forall k t (m :: * -> *).
(Ord k, PostBuild t m) =>
Map k Text
-> Dynamic t (Map k Text) -> m (Event t (Map k (Maybe Text)))
dynamicAttributesToModifyAttributesWithInitial Map k Text
forall a. Monoid a => a
mempty

dynamicAttributesToModifyAttributesWithInitial :: (Ord k, PostBuild t m) => Map k Text -> Dynamic t (Map k Text) -> m (Event t (Map k (Maybe Text)))
dynamicAttributesToModifyAttributesWithInitial :: Map k Text
-> Dynamic t (Map k Text) -> m (Event t (Map k (Maybe Text)))
dynamicAttributesToModifyAttributesWithInitial attrs0 :: Map k Text
attrs0 d :: Dynamic t (Map k Text)
d = do
  Event t ()
postBuild <- m (Event t ())
forall t (m :: * -> *). PostBuild t m => m (Event t ())
getPostBuild
  let modificationsNeeded :: Event t (Map k (Maybe Text))
modificationsNeeded = ((These () (Map k Text) -> PushM t (Maybe (Map k (Maybe Text))))
 -> Event t (These () (Map k Text)) -> Event t (Map k (Maybe Text)))
-> Event t (These () (Map k Text))
-> (These () (Map k Text) -> PushM t (Maybe (Map k (Maybe Text))))
-> Event t (Map k (Maybe Text))
forall a b c. (a -> b -> c) -> b -> a -> c
flip (These () (Map k Text) -> PushM t (Maybe (Map k (Maybe Text))))
-> Event t (These () (Map k Text)) -> Event t (Map k (Maybe Text))
forall k (t :: k) a b.
Reflex t =>
(a -> PushM t (Maybe b)) -> Event t a -> Event t b
push (Event t ()
-> Event t (Map k Text) -> Event t (These () (Map k Text))
forall (f :: * -> *) a b.
Semialign f =>
f a -> f b -> f (These a b)
align Event t ()
postBuild (Event t (Map k Text) -> Event t (These () (Map k Text)))
-> Event t (Map k Text) -> Event t (These () (Map k Text))
forall a b. (a -> b) -> a -> b
$ Dynamic t (Map k Text) -> Event t (Map k Text)
forall k (t :: k) a. Reflex t => Dynamic t a -> Event t a
updated Dynamic t (Map k Text)
d) ((These () (Map k Text) -> PushM t (Maybe (Map k (Maybe Text))))
 -> Event t (Map k (Maybe Text)))
-> (These () (Map k Text) -> PushM t (Maybe (Map k (Maybe Text))))
-> Event t (Map k (Maybe Text))
forall a b. (a -> b) -> a -> b
$ \x :: These () (Map k Text)
x -> do
        Map k (Maybe Text)
p <- case These () (Map k Text)
x of
          This () -> do
            Map k Text
new <- Behavior t (Map k Text) -> PushM t (Map k Text)
forall k (t :: k) (m :: * -> *) a.
MonadSample t m =>
Behavior t a -> m a
sample (Behavior t (Map k Text) -> PushM t (Map k Text))
-> Behavior t (Map k Text) -> PushM t (Map k Text)
forall a b. (a -> b) -> a -> b
$ Dynamic t (Map k Text) -> Behavior t (Map k Text)
forall k (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t (Map k Text)
d
            Map k (Maybe Text) -> PushM t (Map k (Maybe Text))
forall (m :: * -> *) a. Monad m => a -> m a
return (Map k (Maybe Text) -> PushM t (Map k (Maybe Text)))
-> Map k (Maybe Text) -> PushM t (Map k (Maybe Text))
forall a b. (a -> b) -> a -> b
$ Map k Text -> Map k Text -> Map k (Maybe Text)
forall k v. (Ord k, Eq v) => Map k v -> Map k v -> Map k (Maybe v)
diffMap Map k Text
attrs0 Map k Text
new
          These () new :: Map k Text
new -> Map k (Maybe Text) -> PushM t (Map k (Maybe Text))
forall (m :: * -> *) a. Monad m => a -> m a
return (Map k (Maybe Text) -> PushM t (Map k (Maybe Text)))
-> Map k (Maybe Text) -> PushM t (Map k (Maybe Text))
forall a b. (a -> b) -> a -> b
$ Map k Text -> Map k Text -> Map k (Maybe Text)
forall k v. (Ord k, Eq v) => Map k v -> Map k v -> Map k (Maybe v)
diffMap Map k Text
attrs0 Map k Text
new
          That new :: Map k Text
new -> do
            Map k Text
old <- Behavior t (Map k Text) -> PushM t (Map k Text)
forall k (t :: k) (m :: * -> *) a.
MonadSample t m =>
Behavior t a -> m a
sample (Behavior t (Map k Text) -> PushM t (Map k Text))
-> Behavior t (Map k Text) -> PushM t (Map k Text)
forall a b. (a -> b) -> a -> b
$ Dynamic t (Map k Text) -> Behavior t (Map k Text)
forall k (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t (Map k Text)
d
            Map k (Maybe Text) -> PushM t (Map k (Maybe Text))
forall (m :: * -> *) a. Monad m => a -> m a
return (Map k (Maybe Text) -> PushM t (Map k (Maybe Text)))
-> Map k (Maybe Text) -> PushM t (Map k (Maybe Text))
forall a b. (a -> b) -> a -> b
$ Map k Text -> Map k Text -> Map k (Maybe Text)
forall k v. (Ord k, Eq v) => Map k v -> Map k v -> Map k (Maybe v)
diffMap Map k Text
old Map k Text
new
        Maybe (Map k (Maybe Text)) -> PushM t (Maybe (Map k (Maybe Text)))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Map k (Maybe Text))
 -> PushM t (Maybe (Map k (Maybe Text))))
-> Maybe (Map k (Maybe Text))
-> PushM t (Maybe (Map k (Maybe Text)))
forall a b. (a -> b) -> a -> b
$ if Map k (Maybe Text) -> Bool
forall k a. Map k a -> Bool
Map.null Map k (Maybe Text)
p then Maybe (Map k (Maybe Text))
forall a. Maybe a
Nothing else Map k (Maybe Text) -> Maybe (Map k (Maybe Text))
forall a. a -> Maybe a
Just Map k (Maybe Text)
p
  Event t (Map k (Maybe Text)) -> m (Event t (Map k (Maybe Text)))
forall (m :: * -> *) a. Monad m => a -> m a
return Event t (Map k (Maybe Text))
modificationsNeeded

newtype Link t
  = Link { Link t -> Event t ()
_link_clicked :: Event t ()
         }

linkClass :: DomBuilder t m => Text -> Text -> m (Link t)
linkClass :: Text -> Text -> m (Link t)
linkClass s :: Text
s c :: Text
c = do
  (l :: Element EventResult (DomBuilderSpace m) t
l,_) <- Text
-> Map Text Text
-> m ()
-> m (Element EventResult (DomBuilderSpace m) t, ())
forall t (m :: * -> *) a.
DomBuilder t m =>
Text
-> Map Text Text
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elAttr' "a" ("class" Index (Map Text Text) -> IxValue (Map Text Text) -> Map Text Text
forall m. (At m, Monoid m) => Index m -> IxValue m -> m
=: Text
IxValue (Map Text Text)
c) (m () -> m (Element EventResult (DomBuilderSpace m) t, ()))
-> m () -> m (Element EventResult (DomBuilderSpace m) t, ())
forall a b. (a -> b) -> a -> b
$ Text -> m ()
forall t (m :: * -> *). DomBuilder t m => Text -> m ()
text Text
s
  Link t -> m (Link t)
forall (m :: * -> *) a. Monad m => a -> m a
return (Link t -> m (Link t)) -> Link t -> m (Link t)
forall a b. (a -> b) -> a -> b
$ Event t () -> Link t
forall t. Event t () -> Link t
Link (Event t () -> Link t) -> Event t () -> Link t
forall a b. (a -> b) -> a -> b
$ EventName 'ClickTag
-> Element EventResult (DomBuilderSpace m) t
-> Event
     t
     (DomEventType
        (Element EventResult (DomBuilderSpace m) t) 'ClickTag)
forall k (t :: k) target (eventName :: EventTag).
HasDomEvent t target eventName =>
EventName eventName
-> target -> Event t (DomEventType target eventName)
domEvent EventName 'ClickTag
Click Element EventResult (DomBuilderSpace m) t
l

link :: DomBuilder t m => Text -> m (Link t)
link :: Text -> m (Link t)
link s :: Text
s = Text -> Text -> m (Link t)
forall t (m :: * -> *).
DomBuilder t m =>
Text -> Text -> m (Link t)
linkClass Text
s ""

divClass :: forall t m a. DomBuilder t m => Text -> m a -> m a
divClass :: Text -> m a -> m a
divClass = Text -> Text -> m a -> m a
forall t (m :: * -> *) a.
DomBuilder t m =>
Text -> Text -> m a -> m a
elClass "div"

dtdd :: forall t m a. DomBuilder t m => Text -> m a -> m a
dtdd :: Text -> m a -> m a
dtdd h :: Text
h w :: m a
w = do
  Text -> m () -> m ()
forall t (m :: * -> *) a. DomBuilder t m => Text -> m a -> m a
el "dt" (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ Text -> m ()
forall t (m :: * -> *). DomBuilder t m => Text -> m ()
text Text
h
  Text -> m a -> m a
forall t (m :: * -> *) a. DomBuilder t m => Text -> m a -> m a
el "dd" m a
w

blank :: forall m. Monad m => m ()
blank :: m ()
blank = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- TODO: Move to an example project.
-- | A widget to display a table with static columns and dynamic rows.
tableDynAttr :: forall t m r k v. (Ord k, DomBuilder t m, MonadHold t m, PostBuild t m, MonadFix m)
  => Text                                   -- ^ Class applied to <table> element
  -> [(Text, k -> Dynamic t r -> m v)]      -- ^ Columns of (header, row key -> row value -> child widget)
  -> Dynamic t (Map k r)                      -- ^ Map from row key to row value
  -> (k -> m (Dynamic t (Map Text Text))) -- ^ Function to compute <tr> element attributes from row key
  -> m (Dynamic t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))        -- ^ Map from row key to (El, list of widget return values)
tableDynAttr :: Text
-> [(Text, k -> Dynamic t r -> m v)]
-> Dynamic t (Map k r)
-> (k -> m (Dynamic t (Map Text Text)))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
tableDynAttr klass :: Text
klass cols :: [(Text, k -> Dynamic t r -> m v)]
cols dRows :: Dynamic t (Map k r)
dRows rowAttrs :: k -> m (Dynamic t (Map Text Text))
rowAttrs = Text
-> Map Text Text
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
forall t (m :: * -> *) a.
DomBuilder t m =>
Text -> Map Text Text -> m a -> m a
elAttr "div" (Text -> Text -> Map Text Text
forall k a. k -> a -> Map k a
Map.singleton "style" "zoom: 1; overflow: auto; background: white;") (m (Dynamic
      t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
 -> m (Dynamic
         t (Map k (Element EventResult (DomBuilderSpace m) t, [v]))))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
forall a b. (a -> b) -> a -> b
$
    Text
-> Map Text Text
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
forall t (m :: * -> *) a.
DomBuilder t m =>
Text -> Map Text Text -> m a -> m a
elAttr "table" (Text -> Text -> Map Text Text
forall k a. k -> a -> Map k a
Map.singleton "class" Text
klass) (m (Dynamic
      t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
 -> m (Dynamic
         t (Map k (Element EventResult (DomBuilderSpace m) t, [v]))))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
forall a b. (a -> b) -> a -> b
$ do
      Text -> m () -> m ()
forall t (m :: * -> *) a. DomBuilder t m => Text -> m a -> m a
el "thead" (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ Text -> m () -> m ()
forall t (m :: * -> *) a. DomBuilder t m => Text -> m a -> m a
el "tr" (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
        ((Text, k -> Dynamic t r -> m v) -> m ())
-> [(Text, k -> Dynamic t r -> m v)] -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(h :: Text
h, _) -> Text -> m () -> m ()
forall t (m :: * -> *) a. DomBuilder t m => Text -> m a -> m a
el "th" (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ Text -> m ()
forall t (m :: * -> *). DomBuilder t m => Text -> m ()
text Text
h) [(Text, k -> Dynamic t r -> m v)]
cols
      Text
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
forall t (m :: * -> *) a. DomBuilder t m => Text -> m a -> m a
el "tbody" (m (Dynamic
      t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
 -> m (Dynamic
         t (Map k (Element EventResult (DomBuilderSpace m) t, [v]))))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
forall a b. (a -> b) -> a -> b
$
        Dynamic t (Map k r)
-> (k
    -> Dynamic t r
    -> m (Element EventResult (DomBuilderSpace m) t, [v]))
-> m (Dynamic
        t (Map k (Element EventResult (DomBuilderSpace m) t, [v])))
forall t k v (m :: * -> *) a.
(Ord k, Adjustable t m, PostBuild t m, MonadFix m,
 MonadHold t m) =>
Dynamic t (Map k v)
-> (k -> Dynamic t v -> m a) -> m (Dynamic t (Map k a))
listWithKey Dynamic t (Map k r)
dRows (\k :: k
k r :: Dynamic t r
r -> do
          Dynamic t (Map Text Text)
dAttrs <- k -> m (Dynamic t (Map Text Text))
rowAttrs k
k
          Text
-> Dynamic t (Map Text Text)
-> m [v]
-> m (Element EventResult (DomBuilderSpace m) t, [v])
forall t (m :: * -> *) a.
(DomBuilder t m, PostBuild t m) =>
Text
-> Dynamic t (Map Text Text)
-> m a
-> m (Element EventResult (DomBuilderSpace m) t, a)
elDynAttr' "tr" Dynamic t (Map Text Text)
dAttrs (m [v] -> m (Element EventResult (DomBuilderSpace m) t, [v]))
-> m [v] -> m (Element EventResult (DomBuilderSpace m) t, [v])
forall a b. (a -> b) -> a -> b
$ ((Text, k -> Dynamic t r -> m v) -> m v)
-> [(Text, k -> Dynamic t r -> m v)] -> m [v]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\x :: (Text, k -> Dynamic t r -> m v)
x -> Text -> m v -> m v
forall t (m :: * -> *) a. DomBuilder t m => Text -> m a -> m a
el "td" (m v -> m v) -> m v -> m v
forall a b. (a -> b) -> a -> b
$ (Text, k -> Dynamic t r -> m v) -> k -> Dynamic t r -> m v
forall a b. (a, b) -> b
snd (Text, k -> Dynamic t r -> m v)
x k
k Dynamic t r
r) [(Text, k -> Dynamic t r -> m v)]
cols)

-- TODO: Move to an example project.
-- | A widget to construct a tabbed view that shows only one of its child widgets at a time.
--   Creates a header bar containing a <ul> with one <li> per child; clicking a <li> displays
--   the corresponding child and hides all others.
tabDisplay :: forall t m k. (MonadFix m, DomBuilder t m, MonadHold t m, PostBuild t m, Ord k)
  => Text               -- ^ Class applied to <ul> element
  -> Text               -- ^ Class applied to currently active <li> element
  -> Map k (Text, m ()) -- ^ Map from (arbitrary) key to (tab label, child widget)
  -> m ()
tabDisplay :: Text -> Text -> Map k (Text, m ()) -> m ()
tabDisplay ulClass :: Text
ulClass activeClass :: Text
activeClass tabItems :: Map k (Text, m ())
tabItems = do
  let t0 :: Maybe k
t0 = [k] -> Maybe k
forall a. [a] -> Maybe a
listToMaybe ([k] -> Maybe k) -> [k] -> Maybe k
forall a b. (a -> b) -> a -> b
$ Map k (Text, m ()) -> [k]
forall k a. Map k a -> [k]
Map.keys Map k (Text, m ())
tabItems
  rec Demux t (Maybe k)
currentTab :: Demux t (Maybe k) <- Text
-> Map Text Text -> m (Demux t (Maybe k)) -> m (Demux t (Maybe k))
forall t (m :: * -> *) a.
DomBuilder t m =>
Text -> Map Text Text -> m a -> m a
elAttr "ul" ("class" Index (Map Text Text) -> IxValue (Map Text Text) -> Map Text Text
forall m. (At m, Monoid m) => Index m -> IxValue m -> m
=: Text
IxValue (Map Text Text)
ulClass) (m (Demux t (Maybe k)) -> m (Demux t (Maybe k)))
-> m (Demux t (Maybe k)) -> m (Demux t (Maybe k))
forall a b. (a -> b) -> a -> b
$ do
        [Event t k]
tabClicksList :: [Event t k] <- Map k (Event t k) -> [Event t k]
forall k a. Map k a -> [a]
Map.elems (Map k (Event t k) -> [Event t k])
-> m (Map k (Event t k)) -> m [Event t k]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (k -> (Text, m ()) -> m (Event t k))
-> Map k (Text, m ()) -> m (Map k (Event t k))
forall i (t :: * -> *) (m :: * -> *) a b.
(TraversableWithIndex i t, Monad m) =>
(i -> a -> m b) -> t a -> m (t b)
imapM (\k :: k
k (s :: Text
s,_) -> Text -> k -> Dynamic t Bool -> m (Event t k)
headerBarLink Text
s k
k (Dynamic t Bool -> m (Event t k))
-> Dynamic t Bool -> m (Event t k)
forall a b. (a -> b) -> a -> b
$ Demux t (Maybe k) -> Maybe k -> Dynamic t Bool
forall k1 (t :: k1) k2.
(Reflex t, Eq k2) =>
Demux t k2 -> k2 -> Dynamic t Bool
demuxed Demux t (Maybe k)
currentTab (k -> Maybe k
forall a. a -> Maybe a
Just k
k)) Map k (Text, m ())
tabItems
        let Event t k
eTabClicks :: Event t k = [Event t k] -> Event t k
forall k (t :: k) a. Reflex t => [Event t a] -> Event t a
leftmost [Event t k]
tabClicksList
        (Dynamic t (Maybe k) -> Demux t (Maybe k))
-> m (Dynamic t (Maybe k)) -> m (Demux t (Maybe k))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Dynamic t (Maybe k) -> Demux t (Maybe k)
forall k1 (t :: k1) k2.
(Reflex t, Ord k2) =>
Dynamic t k2 -> Demux t k2
demux (m (Dynamic t (Maybe k)) -> m (Demux t (Maybe k)))
-> m (Dynamic t (Maybe k)) -> m (Demux t (Maybe k))
forall a b. (a -> b) -> a -> b
$ Maybe k -> Event t (Maybe k) -> m (Dynamic t (Maybe k))
forall k (t :: k) (m :: * -> *) a.
MonadHold t m =>
a -> Event t a -> m (Dynamic t a)
holdDyn Maybe k
t0 (Event t (Maybe k) -> m (Dynamic t (Maybe k)))
-> Event t (Maybe k) -> m (Dynamic t (Maybe k))
forall a b. (a -> b) -> a -> b
$ (k -> Maybe k) -> Event t k -> Event t (Maybe k)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap k -> Maybe k
forall a. a -> Maybe a
Just Event t k
eTabClicks
  Text -> m () -> m ()
forall t (m :: * -> *) a. DomBuilder t m => Text -> m a -> m a
el "div" (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Map k (Text, m ()) -> (k -> (Text, m ()) -> m ()) -> m ()
forall i (t :: * -> *) (m :: * -> *) a b.
(FoldableWithIndex i t, Monad m) =>
t a -> (i -> a -> m b) -> m ()
iforM_ Map k (Text, m ())
tabItems ((k -> (Text, m ()) -> m ()) -> m ())
-> (k -> (Text, m ()) -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \k :: k
k (_, w :: m ()
w) -> do
      let isSelected :: Dynamic t Bool
isSelected = Demux t (Maybe k) -> Maybe k -> Dynamic t Bool
forall k1 (t :: k1) k2.
(Reflex t, Eq k2) =>
Demux t k2 -> k2 -> Dynamic t Bool
demuxed Demux t (Maybe k)
currentTab (Maybe k -> Dynamic t Bool) -> Maybe k -> Dynamic t Bool
forall a b. (a -> b) -> a -> b
$ k -> Maybe k
forall a. a -> Maybe a
Just k
k
          attrs :: Dynamic t (Map Text Text)
attrs = Dynamic t Bool
-> (Bool -> Map Text Text) -> Dynamic t (Map Text Text)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
ffor Dynamic t Bool
isSelected ((Bool -> Map Text Text) -> Dynamic t (Map Text Text))
-> (Bool -> Map Text Text) -> Dynamic t (Map Text Text)
forall a b. (a -> b) -> a -> b
$ \s :: Bool
s -> if Bool
s then Map Text Text
forall k a. Map k a
Map.empty else Text -> Text -> Map Text Text
forall k a. k -> a -> Map k a
Map.singleton "style" "display:none;"
      Text -> Dynamic t (Map Text Text) -> m () -> m ()
forall t (m :: * -> *) a.
(DomBuilder t m, PostBuild t m) =>
Text -> Dynamic t (Map Text Text) -> m a -> m a
elDynAttr "div" Dynamic t (Map Text Text)
attrs m ()
w
    () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  where
    headerBarLink :: Text -> k -> Dynamic t Bool -> m (Event t k)
    headerBarLink :: Text -> k -> Dynamic t Bool -> m (Event t k)
headerBarLink x :: Text
x k :: k
k isSelected :: Dynamic t Bool
isSelected = do
      let attrs :: Dynamic t (Map Text Text)
attrs = (Bool -> Map Text Text)
-> Dynamic t Bool -> Dynamic t (Map Text Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\b :: Bool
b -> if Bool
b then Text -> Text -> Map Text Text
forall k a. k -> a -> Map k a
Map.singleton "class" Text
activeClass else Map Text Text
forall k a. Map k a
Map.empty) Dynamic t Bool
isSelected
      Text -> Dynamic t (Map Text Text) -> m (Event t k) -> m (Event t k)
forall t (m :: * -> *) a.
(DomBuilder t m, PostBuild t m) =>
Text -> Dynamic t (Map Text Text) -> m a -> m a
elDynAttr "li" Dynamic t (Map Text Text)
attrs (m (Event t k) -> m (Event t k)) -> m (Event t k) -> m (Event t k)
forall a b. (a -> b) -> a -> b
$ do
        Link t
a <- Text -> m (Link t)
forall t (m :: * -> *). DomBuilder t m => Text -> m (Link t)
link Text
x
        Event t k -> m (Event t k)
forall (m :: * -> *) a. Monad m => a -> m a
return (Event t k -> m (Event t k)) -> Event t k -> m (Event t k)
forall a b. (a -> b) -> a -> b
$ (() -> k) -> Event t () -> Event t k
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (k -> () -> k
forall a b. a -> b -> a
const k
k) (Link t -> Event t ()
forall t. Link t -> Event t ()
_link_clicked Link t
a)

class HasAttributes a where
  type Attrs a :: *
  attributes :: Lens' a (Attrs a)