packages feed

bulmex 1.0.0 → 2.0.0

raw patch · 13 files changed

+547/−372 lines, 13 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Reflex.Bulmex.Load: writeReadDom :: (FromJSON a, ToJSON a, DomBuilder t m, Prerender js t m) => Text -> a -> m (Dynamic t a)
- Reflex.Bulmex.PreventDefault: elDynAttrModConf :: (DomBuilder t m, PostBuild t m) => (ElementConfig EventResult t (DomBuilderSpace m) -> ElementConfig EventResult t (DomBuilderSpace m)) -> Text -> Dynamic t (Map Text Text) -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
- Reflex.Bulmex.PreventDefault: elDynAttrPrevDef :: forall a en m t. (DomBuilder t m, PostBuild t m) => EventName en -> Text -> Dynamic t (Map Text Text) -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
- Reflex.Bulmex.Tag: Down :: ToolDirection
- Reflex.Bulmex.Tag: Lft :: ToolDirection
- Reflex.Bulmex.Tag: Rght :: ToolDirection
- Reflex.Bulmex.Tag: Top :: ToolDirection
- Reflex.Bulmex.Tag: ahref :: (DomBuilder t m, PostBuild t m) => Text -> m a -> m a
- Reflex.Bulmex.Tag: ahref' :: (DomBuilder t m, PostBuild t m) => AttrMap -> Text -> m a -> m a
- Reflex.Bulmex.Tag: ahrefDyn :: (DomBuilder t m, PostBuild t m) => Dynamic t AttrMap -> Dynamic t Text -> m a -> m a
- Reflex.Bulmex.Tag: box :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: buttons :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: column :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: columnClass :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: columns :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: columnsClass :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: container :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: containerClass :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: content :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: control :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: controlClass :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: controlDyn :: (PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> m a -> m a
- Reflex.Bulmex.Tag: data ToolDirection
- Reflex.Bulmex.Tag: defaultEl :: (arg -> arg -> arg) -> (arg -> m a -> m a) -> arg -> arg -> m a -> m a
- Reflex.Bulmex.Tag: direction :: ToolDirection -> Text
- Reflex.Bulmex.Tag: dynAttrEl :: Reflex t => (Dynamic t AttrMap -> m a -> m a) -> AttrMap -> Dynamic t AttrMap -> m a -> m a
- Reflex.Bulmex.Tag: evtText :: (DomBuilder t m, PostBuild t m, MonadHold t m) => Event t Text -> m ()
- Reflex.Bulmex.Tag: field :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: fieldClass :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: fieldGrouped :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: flask :: (PostBuild t m, DomBuilder t m) => m ()
- Reflex.Bulmex.Tag: hero :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: hideDiv :: (PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> Dynamic t Bool -> m a -> m a
- Reflex.Bulmex.Tag: hideDiv_ :: (PostBuild t m, DomBuilder t m) => Dynamic t Bool -> m a -> m a
- Reflex.Bulmex.Tag: hideEmptyDiv :: (Eq (f b), Alternative f, PostBuild t m, DomBuilder t m) => Dynamic t (f b) -> m a -> m a
- Reflex.Bulmex.Tag: hideEmptyDyn :: (Eq (f b), Alternative f, PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> Dynamic t (f b) -> m a -> m a
- Reflex.Bulmex.Tag: icon :: (PostBuild t m, DomBuilder t m) => Text -> m ()
- Reflex.Bulmex.Tag: iconClass :: (PostBuild t m, DomBuilder t m) => Text -> Text -> m ()
- Reflex.Bulmex.Tag: iconDyn :: (PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> Dynamic t AttrMap -> m ()
- Reflex.Bulmex.Tag: image :: DomBuilder t m => Text -> m ()
- Reflex.Bulmex.Tag: imageClass :: DomBuilder t m => Text -> Text -> m ()
- Reflex.Bulmex.Tag: labelClass :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: labelEl :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: labeled' :: DomBuilder t m => m () -> m a -> m a
- Reflex.Bulmex.Tag: loadSpinner :: (DomBuilder t m) => m ()
- Reflex.Bulmex.Tag: partialDiv :: DomBuilder t m => Text -> Text -> m a -> m a
- Reflex.Bulmex.Tag: sect :: (DomBuilder t m) => m a -> m a
- Reflex.Bulmex.Tag: section :: (PostBuild t m, DomBuilder t m) => m a -> m a
- Reflex.Bulmex.Tag: sectionDyn :: (PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> m a -> m a
- Reflex.Bulmex.Tag: subtitle :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: subtitleClass :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: switchDiv :: (PostBuild t m, DomBuilder t m) => Dynamic t Bool -> m () -> m a -> m a
- Reflex.Bulmex.Tag: textSpace :: DomBuilder t m => m ()
- Reflex.Bulmex.Tag: tile :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: tileAncestor :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: tileChild :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: tileChildClass :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: tileParent :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: tileParentClass :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: tipToAttr :: ToolDirection -> Text -> AttrMap
- Reflex.Bulmex.Tag: title :: DomBuilder t m => m a -> m a
- Reflex.Bulmex.Tag: titleClazz :: DomBuilder t m => Text -> m a -> m a
- Reflex.Bulmex.Tag: tooltipText :: (PostBuild t m, DomBuilder t m) => Dynamic t Text -> m a -> m a
- Reflex.Bulmex.Tag: tooltipText' :: (PostBuild t m, DomBuilder t m) => ToolDirection -> Dynamic t Text -> m a -> m a
- Reflex.Bulmex.Tag: txtEl :: (Text -> m a -> m a) -> Text -> Text -> m a -> m a
+ Reflex.Bulmex.Event: evtText :: (DomBuilder t m, PostBuild t m, MonadHold t m) => Event t Text -> m ()
+ Reflex.Bulmex.Html: writeReadDom :: (FromJSON a, ToJSON a, DomBuilder t m, Prerender js t m) => Text -> a -> m (Dynamic t a)
+ Reflex.Bulmex.Tag.Abstract: defaultEl :: (arg -> arg -> arg) -> (arg -> m a -> m a) -> arg -> arg -> m a -> m a
+ Reflex.Bulmex.Tag.Abstract: dynAttrEl :: Reflex t => (Dynamic t AttrMap -> m a -> m a) -> AttrMap -> Dynamic t AttrMap -> m a -> m a
+ Reflex.Bulmex.Tag.Abstract: partialDiv :: DomBuilder t m => Text -> Text -> m a -> m a
+ Reflex.Bulmex.Tag.Abstract: txtEl :: (Text -> m a -> m a) -> Text -> Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: box :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: buttons :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: column :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: columnClass :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: columns :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: columnsClass :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: container :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: containerClass :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: content :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: control :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: controlClass :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: controlDyn :: (PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: field :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: fieldClass :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: fieldGrouped :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: hero :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: labelClass :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: labelEl :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: labeled' :: DomBuilder t m => m () -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: sect :: (DomBuilder t m) => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: section :: (PostBuild t m, DomBuilder t m) => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: sectionDyn :: (PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: subtitle :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: subtitleClass :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: tile :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: tileAncestor :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: tileChild :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: tileChildClass :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: tileParent :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: tileParentClass :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Bulma: title :: DomBuilder t m => m a -> m a
+ Reflex.Bulmex.Tag.Bulma: titleClazz :: DomBuilder t m => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Hide: hideDiv :: (PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> Dynamic t Bool -> m a -> m a
+ Reflex.Bulmex.Tag.Hide: hideDiv_ :: (PostBuild t m, DomBuilder t m) => Dynamic t Bool -> m a -> m a
+ Reflex.Bulmex.Tag.Hide: hideEmptyDiv :: (Eq (f b), Alternative f, PostBuild t m, DomBuilder t m) => Dynamic t (f b) -> m a -> m a
+ Reflex.Bulmex.Tag.Hide: hideEmptyDyn :: (Eq (f b), Alternative f, PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> Dynamic t (f b) -> m a -> m a
+ Reflex.Bulmex.Tag.Hide: switchDiv :: (PostBuild t m, DomBuilder t m) => Dynamic t Bool -> m () -> m a -> m a
+ Reflex.Bulmex.Tag.Icon: flask :: (PostBuild t m, DomBuilder t m) => m ()
+ Reflex.Bulmex.Tag.Icon: icon :: (PostBuild t m, DomBuilder t m) => Text -> m ()
+ Reflex.Bulmex.Tag.Icon: iconClass :: (PostBuild t m, DomBuilder t m) => Text -> Text -> m ()
+ Reflex.Bulmex.Tag.Icon: iconDyn :: (PostBuild t m, DomBuilder t m) => Dynamic t AttrMap -> Dynamic t AttrMap -> m ()
+ Reflex.Bulmex.Tag.Odd: ahref :: (DomBuilder t m, PostBuild t m) => Text -> m a -> m a
+ Reflex.Bulmex.Tag.Odd: ahref' :: (DomBuilder t m, PostBuild t m) => AttrMap -> Text -> m a -> m a
+ Reflex.Bulmex.Tag.Odd: ahrefDyn :: (DomBuilder t m, PostBuild t m) => Dynamic t AttrMap -> Dynamic t Text -> m a -> m a
+ Reflex.Bulmex.Tag.Odd: elDynAttrModConf :: (DomBuilder t m, PostBuild t m) => (ElementConfig EventResult t (DomBuilderSpace m) -> ElementConfig EventResult t (DomBuilderSpace m)) -> Text -> Dynamic t (Map Text Text) -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
+ Reflex.Bulmex.Tag.Odd: elDynAttrPrevDef :: forall a en m t. (DomBuilder t m, PostBuild t m) => EventName en -> Text -> Dynamic t (Map Text Text) -> m a -> m (Element EventResult (DomBuilderSpace m) t, a)
+ Reflex.Bulmex.Tag.Odd: image :: DomBuilder t m => Text -> m ()
+ Reflex.Bulmex.Tag.Odd: imageClass :: DomBuilder t m => Text -> Text -> m ()
+ Reflex.Bulmex.Tag.Odd: textSpace :: DomBuilder t m => m ()
+ Reflex.Bulmex.Tag.Tooltip: Down :: ToolDirection
+ Reflex.Bulmex.Tag.Tooltip: Lft :: ToolDirection
+ Reflex.Bulmex.Tag.Tooltip: Rght :: ToolDirection
+ Reflex.Bulmex.Tag.Tooltip: Top :: ToolDirection
+ Reflex.Bulmex.Tag.Tooltip: data ToolDirection
+ Reflex.Bulmex.Tag.Tooltip: tipToAttr :: ToolDirection -> Text -> AttrMap
+ Reflex.Bulmex.Tag.Tooltip: tooltipText :: (PostBuild t m, DomBuilder t m) => Dynamic t Text -> m a -> m a
+ Reflex.Bulmex.Tag.Tooltip: tooltipText' :: (PostBuild t m, DomBuilder t m) => ToolDirection -> Dynamic t Text -> m a -> m a

Files

README.md view
@@ -1,1 +1,15 @@-# awesome-project-name+# Bulmex, reflex infused with bulma++With a bunch of helper functions such as making server side +rendering easier.+See related [blogpost](https://jappieklooster.nl/reflex-server-side-html-rendering.html).++Reflex: ++- core: https://hackage.haskell.org/package/reflex+- DOM: https://hackage.haskell.org/package/reflex-dom-core++CSS:++- Bulma: https://bulma.io/+- Baloon: https://kazzkiq.github.io/balloon.css/
bulmex.cabal view
@@ -2,12 +2,12 @@ -- -- see: https://github.com/sol/hpack ----- hash: 2b99255d36d075b833dc8c72472ac37a01a82e94c211ebc8955bb3075e4f5d12+-- hash: ff65f5447cccce6ee9bed9f2913c5cfb43a800f93be78f0fc411b1c89f46ab8b  name:           bulmex-version:        1.0.0+version:        2.0.0 synopsis:       Reflex infused with bulma (css)-description:    Please see the README on GitHub at <https://github.com/githubuser/awesome-project-name#readme>+description:    Reflex infused with bulma, With a bunch of helper functions for making server side rendering easier. See related [blogpost](https://jappieklooster.nl/reflex-server-side-html-rendering.html). category:       Web homepage:       https://github.com/jappeace/bulmex#readme bug-reports:    https://github.com/jappeace/bulmex/issues@@ -32,10 +32,14 @@       Reflex.Bulmex.Event       Reflex.Bulmex.Html       Reflex.Bulmex.Input.Polymorphic-      Reflex.Bulmex.Load-      Reflex.Bulmex.PreventDefault       Reflex.Bulmex.Space       Reflex.Bulmex.Tag+      Reflex.Bulmex.Tag.Abstract+      Reflex.Bulmex.Tag.Bulma+      Reflex.Bulmex.Tag.Hide+      Reflex.Bulmex.Tag.Icon+      Reflex.Bulmex.Tag.Odd+      Reflex.Bulmex.Tag.Tooltip   other-modules:       Paths_bulmex   hs-source-dirs:
src/Reflex/Bulmex/Event.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE RankNTypes       #-}+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes        #-}  -- | Helper functions for dealing with events module Reflex.Bulmex.Event where@@ -7,6 +8,7 @@ import           Control.Applicative      (empty) import           Control.Monad            (void) import           Control.Monad.IO.Class   (MonadIO)+import qualified Data.Text                as Text import           Data.Time.Clock          (NominalDiffTime) import           Data.Witherable import           Reflex@@ -83,3 +85,6 @@   delayed <- delay time event   holdEvent defVal (leftmost [pure <$> event, empty <$ delayed]) $     maybe (pure defVal) monadFunc++evtText :: (Dom.DomBuilder t m, PostBuild t m, MonadHold t m) => Event t Text.Text -> m ()+evtText evt = Dom.dynText =<< holdDyn "" evt
src/Reflex/Bulmex/Html.hs view
@@ -7,7 +7,8 @@  -- | A root for an app, --   usefull for server side html rendering.---   has a neat api for the head tag, use this if that api your needs.+--   has a neat api for the head tag, use this if that api suits your needs.+--   For more info see blogpost: https://jappieklooster.nl/reflex-server-side-html-rendering.html module Reflex.Bulmex.Html   ( htmlWidget   -- * Head tag stuff@@ -21,20 +22,43 @@   -- * Defaults   , defScript   , defSettings+  -- * Load+  , writeReadDom   ) where  import           Control.Lens-import           Control.Monad            (void)-import           Data.Foldable            (traverse_)-import qualified Data.Map.Strict          as Map-import qualified Data.Text                as Text-import           GHC.Generics             (Generic)+import           Control.Monad                        (void)+import           Control.Monad                        (join)+import           Data.Aeson+import           Data.Aeson.Text+import qualified Data.ByteString.Lazy                 as LBS+import           Data.Foldable                        (traverse_)+import qualified Data.Map.Strict                      as Map+import           Data.Maybe+import qualified Data.Text                            as Text+import           Data.Text.Encoding+import qualified Data.Text.Lazy                       as LText+import           GHC.Generics                         (Generic)+import           JSDOM+import           JSDOM.Generated.Element+import           JSDOM.Generated.NonElementParentNode import           Network.URI-import qualified Reflex.Dom.Builder.Class as Dom-import qualified Reflex.Dom.Widget        as Dom+import           Reflex+import qualified Reflex.Dom.Builder.Class             as Dom+import qualified Reflex.Dom.Prerender                 as Dom+import qualified Reflex.Dom.Widget                    as Dom  -- | Adds the core html tags. --   we already know most of the head.+--+-- >  <html>+-- >    <head>+-- >     'HeadSettings' <!-- provided settings --!>+-- >    </head>+-- >    <body>+-- >    'm a' <!-- provided monad --!>+-- >    </body>+-- >  </html> htmlWidget :: (Dom.DomBuilder t m) => HeadSettings -> m a -> m a htmlWidget settings content =   Dom.el "html" $ do@@ -108,3 +132,25 @@          (Map.fromList -- bulmo             [("rel", "stylesheet"), ("href", href)])          Dom.blank) $ settings ^.. head_css . traversed . to (Text.pack . show)++-- | Insert an encodable in the document body,+--   in case of the server side rendering we encode it as script tag with jsonval,+--   in case of ghcjsdom we read the value from that script tag+--   first arg is the idname to connect the two up (has to be uniq for a doc)+writeReadDom :: (FromJSON a, ToJSON a, Dom.DomBuilder t m, Dom.Prerender js t m) =>+  Text.Text -> a -> m (Dynamic t a)+writeReadDom comelid serverState =+  Dom.prerender (do+    Dom.elAttr "script" (Map.fromList [+                            ("type", "application/json"),+                            ("id", comelid)+                            ]) $+      Dom.text $ LText.toStrict $ encodeToLazyText serverState+    pure serverState+    ) $ do+        mayDoc <- currentDocument+        mayEl' <- sequence $ (getElementById <$> mayDoc) <*> pure comelid+        mayInner  <- sequence $ getInnerHTML <$> join mayEl'+        let result = (join $ decode . LBS.fromStrict .  encodeUtf8 <$> mayInner)+        pure $ fromMaybe serverState  -- TODO don't fail silently+            result
− src/Reflex/Bulmex/Load.hs
@@ -1,43 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}---- | Load functions-module Reflex.Bulmex.Load where--import           Control.Monad                        (join)-import           Data.Aeson-import           Data.Aeson.Text-import qualified Data.ByteString.Lazy                 as LBS-import qualified Data.Map                             as Map-import           Data.Maybe-import qualified Data.Text                            as Text-import           Data.Text.Encoding-import qualified Data.Text.Lazy                       as LText-import           JSDOM-import           JSDOM.Generated.Element-import           JSDOM.Generated.NonElementParentNode-import           Reflex-import qualified Reflex.Dom.Builder.Class             as Dom-import qualified Reflex.Dom.Prerender                 as Dom-import qualified Reflex.Dom.Widget.Basic              as Dom---- | Insert an encodable in the document body,---   in case of the server side rendering we encode it as script tag with jsonval,---   in case of ghcjsdom we read the value from that script tag---   first arg is the idname to connect the two up (has to be uniq for a doc)-writeReadDom :: (FromJSON a, ToJSON a, Dom.DomBuilder t m, Dom.Prerender js t m) =>-  Text.Text -> a -> m (Dynamic t a)-writeReadDom comelid serverState =-  Dom.prerender (do-    Dom.elAttr "script" (Map.fromList [-                            ("type", "application/json"),-                            ("id", comelid)-                            ]) $-      Dom.text $ LText.toStrict $ encodeToLazyText serverState-    pure serverState-    ) $ do-        mayDoc <- currentDocument-        mayEl' <- sequence $ (getElementById <$> mayDoc) <*> pure comelid-        mayInner  <- sequence $ getInnerHTML <$> join mayEl'-        let result = (join $ decode . LBS.fromStrict .  encodeUtf8 <$> mayInner)-        pure $ fromMaybe serverState  -- TODO don't fail silently-            result
− src/Reflex/Bulmex/PreventDefault.hs
@@ -1,48 +0,0 @@-{-# LANGUAGE RankNTypes          #-}-{-# LANGUAGE ScopedTypeVariables #-}---- | ripped from https://gist.github.com/3noch/134b1ee7fa48c347be9d164c3fac4ef7-module Reflex.Bulmex.PreventDefault where--import           Control.Lens    ((%~), (.~))-import           Data.Map        (Map)-import           Data.Proxy      (Proxy (..))-import           Data.Text       (Text)-import           Reflex.Dom.Core---- | Like 'elDynAttr'' but configures "prevent default" on the given event.-elDynAttrPrevDef ::-     forall a en m t. (DomBuilder t m, PostBuild t m)-  => EventName en -- ^ Event on the element to configure with 'preventDefault'-  -> Text -- ^ Element tag-  -> Dynamic t (Map Text Text) -- ^ Element attributes-  -> m a -- ^ Child of element-  -> m (Element EventResult (DomBuilderSpace m) t, a) -- An element and the result of the child-elDynAttrPrevDef ev =-  elDynAttrModConf-    (\elCfg ->-       elCfg &-       elementConfig_eventSpec %~-       addEventSpecFlags-         (Proxy :: Proxy (DomBuilderSpace m))-         ev-         (const preventDefault))---- | Like 'elDynAttr'' but allows you to modify the element configuration.------ Special thanks to @luigy: https://gist.github.com/luigy/b49ce04de8462e594c9c2b5b455ae5a5#file-foo-hs-elDynAttrModConf ::-     (DomBuilder t m, PostBuild t m)-  => (ElementConfig EventResult t (DomBuilderSpace m) -> ElementConfig EventResult t (DomBuilderSpace m))-  -> Text-  -> Dynamic t (Map Text Text)-  -> m a-  -> m (Element EventResult (DomBuilderSpace m) t, a)-elDynAttrModConf f elementTag attrs child = do-  modifyAttrs <- dynamicAttributesToModifyAttributes attrs-  let cfg =-        def & modifyAttributes .~ fmapCheap mapKeysToAttributeName modifyAttrs-  result <- element elementTag (f cfg) child-  postBuild <- getPostBuild-  notReadyUntil postBuild-  pure result
src/Reflex/Bulmex/Tag.hs view
@@ -1,266 +1,10 @@-{-# LANGUAGE GADTs             #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RankNTypes        #-}---- | bulma divs-module Reflex.Bulmex.Tag where--import           Control.Applicative-import           Data.Bool-import qualified Data.Map.Strict          as Map-import qualified Data.Text                as Text-import           Reflex-import           Reflex.Bulmex.Attr-import           Reflex.Bulmex.Space-import qualified Reflex.Dom.Builder.Class as Dom-import qualified Reflex.Dom.Widget        as Dom-import qualified Reflex.Tags              as T--container :: Dom.DomBuilder t m => m a -> m a-container = containerClass mempty--containerClass  :: Dom.DomBuilder t m => Text.Text -> m a -> m a-containerClass = partialDiv "container"--partialDiv :: Dom.DomBuilder t m => Text.Text -> Text.Text -> m a -> m a-partialDiv = txtEl T.divClass--txtEl :: (Text.Text -> m a -> m a) -> Text.Text -> Text.Text -> m a -> m a-txtEl = defaultEl spaceJoin---- | allows us to set a default value for tags by defining a join function---   not a monoid because often it does it wrong, text needs a space---    for example in case of classes, and the default map monoid is broken-defaultEl :: (arg -> arg -> arg) -> (arg -> m a -> m a) -> arg -> arg -> m a -> m a-defaultEl monoidF elF a b = elF $ monoidF a b--buttons :: Dom.DomBuilder t m => m a -> m a-buttons = T.divClass "buttons"---- | kindoff hard to set an image tag in reflex-image :: Dom.DomBuilder t m => Text.Text -> m()-image url = T.imgAttr (Map.singleton "src" url) Dom.blank---- | first class second src-imageClass :: Dom.DomBuilder t m => Text.Text -> Text.Text -> m()-imageClass clazz url = T.imgAttr (Map.fromList [("src",url), ("class", clazz)]) Dom.blank---- | bulma hero sturcture--- | <section class="hero">--- |  <div class="hero-body">--- |     <div class="container">-hero :: Dom.DomBuilder t m => Text.Text -> m a -> m a-hero styles =-  txtEl T.sectionClass "hero" styles . T.divClass "hero-body" . container--content :: Dom.DomBuilder t m => m a -> m a-content = T.divClass "content"--sect :: (Dom.DomBuilder t m) => m a -> m a-sect = T.divClass "section"--section :: (PostBuild t m, Dom.DomBuilder t m) => m a -> m a-section = sectionDyn $ constDyn mempty--sectionDyn ::-     (PostBuild t m, Dom.DomBuilder t m) => Dynamic t AttrMap -> m a -> m a-sectionDyn =-  dynAttrEl (\a b -> T.divDynAttr a $ container b) $ classAttr "section"--columns :: Dom.DomBuilder t m => m a -> m a-columns = columnsClass mempty--column :: Dom.DomBuilder t m => m a -> m a-column = columnClass mempty--columnsClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a-columnsClass = partialDiv "columns"--columnClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a-columnClass = partialDiv "column"--control :: Dom.DomBuilder t m => m a -> m a-control = controlClass mempty--controlClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a-controlClass = partialDiv "control"--controlDyn ::-     (PostBuild t m, Dom.DomBuilder t m) => Dynamic t AttrMap -> m a -> m a-controlDyn = dynAttrEl T.divDynAttr $ classAttr "control"--tile :: Dom.DomBuilder t m => Text.Text -> m a -> m a-tile = partialDiv "tile"--tileChild :: Dom.DomBuilder t m => m a -> m a-tileChild = tileChildClass mempty--tileChildClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a-tileChildClass = txtEl tile "is-child"--tileParentClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a-tileParentClass = txtEl tile "is-parent"--tileParent :: Dom.DomBuilder t m => m a -> m a-tileParent = tileParentClass mempty--tileAncestor :: Dom.DomBuilder t m => m a -> m a-tileAncestor = tile "is-ancestor"--dynAttrEl ::-     Reflex t-  => (Dynamic t AttrMap -> m a -> m a)-  -> AttrMap-  -> Dynamic t AttrMap-  -> m a-  -> m a-dynAttrEl f = defaultEl ((<*>) . (<$>) attrUnion) f . constDyn--field :: Dom.DomBuilder t m => m a -> m a-field = fieldClass mempty--fieldClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a-fieldClass = partialDiv "field"--fieldGrouped :: Dom.DomBuilder t m => m a -> m a-fieldGrouped = fieldClass "is-grouped"--title :: Dom.DomBuilder t m => m a -> m a-title = titleClazz "is-1"--titleClazz :: Dom.DomBuilder t m => Text.Text -> m a -> m a-titleClazz = txtEl T.h1Class "title"--subtitle :: Dom.DomBuilder t m => m a -> m a-subtitle = subtitleClass "is-3"--subtitleClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a-subtitleClass = txtEl T.h2Class "subtitle"--box :: Dom.DomBuilder t m => m a -> m a-box = T.divClass "box"--evtText :: (Dom.DomBuilder t m, PostBuild t m, MonadHold t m) => Event t Text.Text -> m ()-evtText evt = Dom.dynText =<< holdDyn "" evt---labeled' :: Dom.DomBuilder t m => m () -> m a -> m a-labeled' labelM inputM = do-  labelEl labelM-  control inputM---- | named labelEl cause didn't want to fix name clashes-labelEl :: Dom.DomBuilder t m => m a -> m a-labelEl = labelClass mempty--labelClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a-labelClass = txtEl T.labelClass "label"--data ToolDirection-  = Top -- top is graphic bugged-  | Lft-  | Rght-  | Down---- | balloon css, for example: https://cdnjs.cloudflare.com/ajax/libs/balloon-css/0.5.0/balloon.min.css-tooltipText ::-     (PostBuild t m, Dom.DomBuilder t m) => Dynamic t Text.Text -> m a -> m a-tooltipText = tooltipText' Rght--tooltipText' ::-     (PostBuild t m, Dom.DomBuilder t m)-  => ToolDirection-  -> Dynamic t Text.Text-  -> m a-  -> m a-tooltipText' dir tipDyn monad = T.spanDynAttr (tipToAttr dir <$> tipDyn) $ monad--tipToAttr :: ToolDirection -> Text.Text -> AttrMap-tipToAttr dir "" = tipToAttr dir "-"-tipToAttr dir tip =-  Map.fromList [("data-balloon", tip), ("data-balloon-pos", direction dir)]--direction :: ToolDirection -> Text.Text-direction Top  = "top"-direction Lft  = "left"-direction Rght = "right"-direction Down = "down"--icon :: (PostBuild t m, Dom.DomBuilder t m) => Text.Text -> m ()-icon = iconClass ""---- | second is name-iconClass ::-     (PostBuild t m, Dom.DomBuilder t m) => Text.Text -> Text.Text -> m ()-iconClass wrapClass =-  iconDyn (constDyn (classAttr wrapClass)) . constDyn . classAttr--iconDyn ::-     (PostBuild t m, Dom.DomBuilder t m)-  => Dynamic t AttrMap-  -> Dynamic t AttrMap-  -> m ()-iconDyn wrapClass mdiClass = do-  textSpace-  T.spanDynAttr (attrUnion (classAttr "icon") <$> wrapClass) $-    T.iDynAttr (Map.unionWith (<>) (classAttr "mdi mdi-") <$> mdiClass) $-    Dom.blank-  textSpace---- | sometimes you just need 2 pieces of text to seperate with a space-textSpace :: Dom.DomBuilder t m => m ()-textSpace = Dom.text space--flask :: (PostBuild t m, Dom.DomBuilder t m) => m ()-flask = icon "flask"---- | a html tag that accepts any text into it's href value-ahref :: (Dom.DomBuilder t m, PostBuild t m) => Text.Text -> m a -> m a-ahref = ahref' mempty--ahref' :: (Dom.DomBuilder t m, PostBuild t m) => AttrMap -> Text.Text -> m a -> m a-ahref' uno = ahrefDyn (constDyn uno) . constDyn--ahrefDyn :: (Dom.DomBuilder t m, PostBuild t m) => Dynamic t AttrMap -> Dynamic t Text.Text -> m a -> m a-ahrefDyn uno txt = T.aDynAttr $ (attrUnion <$> uno) <*> (Map.singleton "href" <$> txt)--switchDiv ::-     (PostBuild t m, Dom.DomBuilder t m)-  => Dynamic t Bool-  -> m ()-  -> m a-  -> m a-switchDiv attrDyn true false = do-  hideDiv_ (not <$> attrDyn) true-  hideDiv_ attrDyn false---- | when dynamic is true ishidden will be added, else the attrmap is used-hideDiv ::-     (PostBuild t m, Dom.DomBuilder t m)-  => Dynamic t AttrMap-  -> Dynamic t Bool-  -> m a-  -> m a-hideDiv attrDyn hide =-  T.divDynAttr $ bool <$> attrDyn <*> constDyn isHidden <*> hide--hideDiv_ :: (PostBuild t m, Dom.DomBuilder t m) => Dynamic t Bool -> m a -> m a-hideDiv_ = hideDiv $ constDyn Map.empty--loadSpinner :: (Dom.DomBuilder t m) => m ()-loadSpinner = imageClass "loadSpinner" "spinner.svg"--hideEmptyDiv ::-     (Eq (f b), Alternative f, PostBuild t m, Dom.DomBuilder t m)-  => Dynamic t (f b)-  -> m a-  -> m a-hideEmptyDiv = hideEmptyDyn $ constDyn Map.empty+module Reflex.Bulmex.Tag+  ( module X+  ) where -hideEmptyDyn ::-     (Eq (f b), Alternative f, PostBuild t m, Dom.DomBuilder t m)-  => Dynamic t AttrMap-  -> Dynamic t (f b)-  -> m a-  -> m a-hideEmptyDyn dyn = hideDiv dyn . fmap ((==) empty)+import           Reflex.Bulmex.Tag.Abstract as X+import           Reflex.Bulmex.Tag.Bulma    as X+import           Reflex.Bulmex.Tag.Hide     as X+import           Reflex.Bulmex.Tag.Icon     as X+import           Reflex.Bulmex.Tag.Odd      as X+import           Reflex.Bulmex.Tag.Tooltip  as X
+ src/Reflex/Bulmex/Tag/Abstract.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE GADTs             #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes        #-}++-- | Abstract tags, most tags have very similiar overload mechanisms+--   this provides an abstraction over that+module Reflex.Bulmex.Tag.Abstract(+   defaultEl+  , txtEl+  , dynAttrEl+  , partialDiv+  ) where++import qualified Data.Text                as Text+import           Reflex+import           Reflex.Bulmex.Attr+import           Reflex.Bulmex.Space+import qualified Reflex.Dom.Builder.Class as Dom+import qualified Reflex.Tags              as T++partialDiv :: Dom.DomBuilder t m => Text.Text -> Text.Text -> m a -> m a+partialDiv = txtEl T.divClass++txtEl :: (Text.Text -> m a -> m a) -> Text.Text -> Text.Text -> m a -> m a+txtEl = defaultEl spaceJoin++-- | allows us to set a default value for tags by defining a join function+--   not a monoid because often it does it wrong, text needs a space+--    for example in case of classes, and the default map monoid is broken+defaultEl :: (arg -> arg -> arg) -> (arg -> m a -> m a) -> arg -> arg -> m a -> m a+defaultEl monoidF elF a b = elF $ monoidF a b++dynAttrEl ::+     Reflex t+  => (Dynamic t AttrMap -> m a -> m a)+  -> AttrMap+  -> Dynamic t AttrMap+  -> m a+  -> m a+dynAttrEl f = defaultEl ((<*>) . (<$>) attrUnion) f . constDyn
+ src/Reflex/Bulmex/Tag/Bulma.hs view
@@ -0,0 +1,165 @@+{-# LANGUAGE GADTs             #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes        #-}++-- | Bulma styled tags: https://bulma.io/+module Reflex.Bulmex.Tag.Bulma+  (+  -- * Layout+    container+  , containerClass+  , hero+  , content+  , sect+  , section+  , sectionDyn+  , columns+  , column+  , columnsClass+  , columnClass+  -- * Tiles+  , tile+  , tileChild+  , tileChildClass+  , tileParentClass+  , tileParent+  , tileAncestor+  -- * Form+  , control+  , controlClass+  , controlDyn+  , buttons+  , field+  , fieldClass+  , fieldGrouped+  , labeled'+  , labelEl+  , labelClass+  -- * Title+  , title+  , titleClazz+  , subtitle+  , subtitleClass+  -- * Box+  , box+  ) where++import qualified Data.Text                  as Text+import           Reflex+import           Reflex.Bulmex.Attr+import           Reflex.Bulmex.Tag.Abstract+import qualified Reflex.Dom.Builder.Class   as Dom+import qualified Reflex.Tags                as T++-- | Container: https://bulma.io/documentation/layout/container/+container :: Dom.DomBuilder t m => m a -> m a+container = containerClass mempty++containerClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a+containerClass = partialDiv "container"++buttons :: Dom.DomBuilder t m => m a -> m a+buttons = T.divClass "buttons"++-- | bulma hero sturcture https://bulma.io/documentation/layout/hero/+--+-- > <section class="hero">+-- >  <div class="hero-body">+-- >    <div class="container">++hero :: Dom.DomBuilder t m => Text.Text -> m a -> m a+hero styles =+  txtEl T.sectionClass "hero" styles . T.divClass "hero-body" . container++content :: Dom.DomBuilder t m => m a -> m a+content = T.divClass "content"++sect :: (Dom.DomBuilder t m) => m a -> m a+sect = T.divClass "section"++-- | https://bulma.io/documentation/layout/section/+section :: (PostBuild t m, Dom.DomBuilder t m) => m a -> m a+section = sectionDyn $ constDyn mempty++sectionDyn ::+     (PostBuild t m, Dom.DomBuilder t m) => Dynamic t AttrMap -> m a -> m a+sectionDyn =+  dynAttrEl (\a b -> T.divDynAttr a $ container b) $ classAttr "section"++-- | https://bulma.io/documentation/columns/+columns :: Dom.DomBuilder t m => m a -> m a+columns = columnsClass mempty++column :: Dom.DomBuilder t m => m a -> m a+column = columnClass mempty++columnsClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a+columnsClass = partialDiv "columns"++columnClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a+columnClass = partialDiv "column"++control :: Dom.DomBuilder t m => m a -> m a+control = controlClass mempty++controlClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a+controlClass = partialDiv "control"++controlDyn ::+     (PostBuild t m, Dom.DomBuilder t m) => Dynamic t AttrMap -> m a -> m a+controlDyn = dynAttrEl T.divDynAttr $ classAttr "control"++-- | https://bulma.io/documentation/layout/tiles/+tile :: Dom.DomBuilder t m => Text.Text -> m a -> m a+tile = partialDiv "tile"++tileChild :: Dom.DomBuilder t m => m a -> m a+tileChild = tileChildClass mempty++tileChildClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a+tileChildClass = txtEl tile "is-child"++tileParentClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a+tileParentClass = txtEl tile "is-parent"++tileParent :: Dom.DomBuilder t m => m a -> m a+tileParent = tileParentClass mempty++tileAncestor :: Dom.DomBuilder t m => m a -> m a+tileAncestor = tile "is-ancestor"++field :: Dom.DomBuilder t m => m a -> m a+field = fieldClass mempty++fieldClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a+fieldClass = partialDiv "field"++fieldGrouped :: Dom.DomBuilder t m => m a -> m a+fieldGrouped = fieldClass "is-grouped"++title :: Dom.DomBuilder t m => m a -> m a+title = titleClazz "is-1"++titleClazz :: Dom.DomBuilder t m => Text.Text -> m a -> m a+titleClazz = txtEl T.h1Class "title"++subtitle :: Dom.DomBuilder t m => m a -> m a+subtitle = subtitleClass "is-3"++subtitleClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a+subtitleClass = txtEl T.h2Class "subtitle"++box :: Dom.DomBuilder t m => m a -> m a+box = T.divClass "box"++labeled' :: Dom.DomBuilder t m => m () -> m a -> m a+labeled' labelM inputM = do+  labelEl labelM+  control inputM++-- | named labelEl cause didn't want to fix name clashes+labelEl :: Dom.DomBuilder t m => m a -> m a+labelEl = labelClass mempty++labelClass :: Dom.DomBuilder t m => Text.Text -> m a -> m a+labelClass = txtEl T.labelClass "label"
+ src/Reflex/Bulmex/Tag/Hide.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE GADTs             #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes        #-}++-- | A div that can hide with bulma is-hidden class+module Reflex.Bulmex.Tag.Hide where++import           Control.Applicative+import           Data.Bool+import qualified Data.Map.Strict          as Map+import           Reflex+import           Reflex.Bulmex.Attr+import qualified Reflex.Dom.Builder.Class as Dom+import qualified Reflex.Tags              as T++switchDiv ::+     (PostBuild t m, Dom.DomBuilder t m)+  => Dynamic t Bool+  -> m ()+  -> m a+  -> m a+switchDiv attrDyn true false = do+  hideDiv_ (not <$> attrDyn) true+  hideDiv_ attrDyn false++-- | when dynamic is true ishidden will be added, else the attrmap is used+hideDiv ::+     (PostBuild t m, Dom.DomBuilder t m)+  => Dynamic t AttrMap+  -> Dynamic t Bool+  -> m a+  -> m a+hideDiv attrDyn hide =+  T.divDynAttr $ bool <$> attrDyn <*> constDyn isHidden <*> hide++hideDiv_ :: (PostBuild t m, Dom.DomBuilder t m) => Dynamic t Bool -> m a -> m a+hideDiv_ = hideDiv $ constDyn Map.empty++hideEmptyDiv ::+     (Eq (f b), Alternative f, PostBuild t m, Dom.DomBuilder t m)+  => Dynamic t (f b)+  -> m a+  -> m a+hideEmptyDiv = hideEmptyDyn $ constDyn Map.empty++hideEmptyDyn ::+     (Eq (f b), Alternative f, PostBuild t m, Dom.DomBuilder t m)+  => Dynamic t AttrMap+  -> Dynamic t (f b)+  -> m a+  -> m a+hideEmptyDyn dyn = hideDiv dyn . fmap ((==) empty)
+ src/Reflex/Bulmex/Tag/Icon.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE GADTs             #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes        #-}++-- | Icons with material design+module Reflex.Bulmex.Tag.Icon+  (-- * Icon+    icon+  , iconClass+  , iconDyn+  ,-- * Flask+    flask+  ) where++import qualified Data.Map.Strict          as Map+import qualified Data.Text                as Text+import           Reflex+import           Reflex.Bulmex.Attr+import           Reflex.Bulmex.Tag.Odd+import qualified Reflex.Dom.Builder.Class as Dom+import qualified Reflex.Dom.Widget        as Dom+import qualified Reflex.Tags              as T++icon :: (PostBuild t m, Dom.DomBuilder t m) => Text.Text -> m ()+icon = iconClass ""++-- | second is name+iconClass ::+     (PostBuild t m, Dom.DomBuilder t m) => Text.Text -> Text.Text -> m ()+iconClass wrapClass =+  iconDyn (constDyn (classAttr wrapClass)) . constDyn . classAttr++iconDyn ::+     (PostBuild t m, Dom.DomBuilder t m)+  => Dynamic t AttrMap+  -> Dynamic t AttrMap+  -> m ()+iconDyn wrapClass mdiClass = do+  textSpace+  T.spanDynAttr (attrUnion (classAttr "icon") <$> wrapClass) $+    T.iDynAttr (Map.unionWith (<>) (classAttr "mdi mdi-") <$> mdiClass) $+    Dom.blank+  textSpace++flask :: (PostBuild t m, Dom.DomBuilder t m) => m ()+flask = icon "flask"
+ src/Reflex/Bulmex/Tag/Odd.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE GADTs               #-}+{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE RankNTypes          #-}+{-# LANGUAGE ScopedTypeVariables #-}+++-- | Odd tag helpers, these have uncommen html attributes+--   They don't fit in the 'normal' pattern of Abstract+module Reflex.Bulmex.Tag.Odd+  (+  -- * Image+    image+  , imageClass+  -- * Link+  , ahref+  , ahref'+  , ahrefDyn+  -- * Space+  , textSpace+  -- * Prevent browser default+  , elDynAttrPrevDef+  , elDynAttrModConf+  ) where++import           Control.Lens             ((%~), (.~))+import           Data.Map                 (Map)+import qualified Data.Map.Strict          as Map+import           Data.Proxy               (Proxy (..))+import           Data.Text                (Text)+import qualified Data.Text                as Text+import           Reflex+import           Reflex.Bulmex.Attr+import           Reflex.Bulmex.Space+import qualified Reflex.Dom.Builder.Class as Dom+import           Reflex.Dom.Core+import qualified Reflex.Dom.Widget        as Dom+import qualified Reflex.Tags              as T+++-- | kindoff hard to set an image tag in reflex+image :: Dom.DomBuilder t m => Text.Text -> m()+image url = T.imgAttr (Map.singleton "src" url) Dom.blank++-- | first class second src+imageClass :: Dom.DomBuilder t m => Text.Text -> Text.Text -> m()+imageClass clazz url = T.imgAttr (Map.fromList [("src",url), ("class", clazz)]) Dom.blank++-- | sometimes you just need 2 pieces of text to seperate with a space+textSpace :: Dom.DomBuilder t m => m ()+textSpace = Dom.text space++-- | a html tag that accepts any text into it's href value+ahref :: (Dom.DomBuilder t m, PostBuild t m) => Text.Text -> m a -> m a+ahref = ahref' mempty++ahref' :: (Dom.DomBuilder t m, PostBuild t m) => AttrMap -> Text.Text -> m a -> m a+ahref' uno = ahrefDyn (constDyn uno) . constDyn++ahrefDyn :: (Dom.DomBuilder t m, PostBuild t m) => Dynamic t AttrMap -> Dynamic t Text.Text -> m a -> m a+ahrefDyn uno txt = T.aDynAttr $ (attrUnion <$> uno) <*> (Map.singleton "href" <$> txt)++-- | From https://gist.github.com/3noch/134b1ee7fa48c347be9d164c3fac4ef7+--   Like 'elDynAttr'' but configures "prevent default" on the given event.+--   Blocks for example a context menu from poping up on right mouse click.+--   This should be used with caution, as it may be unexpected for end user.+elDynAttrPrevDef ::+     forall a en m t. (DomBuilder t m, PostBuild t m)+  => EventName en -- ^ Event on the element to configure with 'preventDefault'+  -> Text -- ^ Element tag+  -> Dynamic t (Map Text Text) -- ^ Element attributes+  -> m a -- ^ Child of element+  -> m (Element EventResult (DomBuilderSpace m) t, a) -- An element and the result of the child+elDynAttrPrevDef ev =+  elDynAttrModConf+    (\elCfg ->+       elCfg &+       elementConfig_eventSpec %~+       addEventSpecFlags+         (Proxy :: Proxy (DomBuilderSpace m))+         ev+         (const preventDefault))++-- | Like 'elDynAttr'' but allows you to modify the element configuration.+--+-- Special thanks to @luigy: https://gist.github.com/luigy/b49ce04de8462e594c9c2b5b455ae5a5#file-foo-hs+elDynAttrModConf ::+     (DomBuilder t m, PostBuild t m)+  => (ElementConfig EventResult t (DomBuilderSpace m) -> ElementConfig EventResult t (DomBuilderSpace m))+  -> Text+  -> Dynamic t (Map Text Text)+  -> m a+  -> m (Element EventResult (DomBuilderSpace m) t, a)+elDynAttrModConf f elementTag attrs child = do+  modifyAttrs <- dynamicAttributesToModifyAttributes attrs+  let cfg =+        def & modifyAttributes .~ fmapCheap mapKeysToAttributeName modifyAttrs+  result <- element elementTag (f cfg) child+  postBuild <- getPostBuild+  notReadyUntil postBuild+  pure result
+ src/Reflex/Bulmex/Tag/Tooltip.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE GADTs             #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes        #-}++-- | Tooltips with balloon css+module Reflex.Bulmex.Tag.Tooltip(+  tooltipText,+  tooltipText',+  ToolDirection(..),+  tipToAttr+  ) where++import qualified Data.Map.Strict          as Map+import qualified Data.Text                as Text+import           Reflex+import           Reflex.Bulmex.Attr+import qualified Reflex.Dom.Builder.Class as Dom+import qualified Reflex.Tags              as T++data ToolDirection+  = Top -- top is graphic bugged+  | Lft+  | Rght+  | Down++-- | balloon css, for example: https://cdnjs.cloudflare.com/ajax/libs/balloon-css/0.5.0/balloon.min.css+--   uses a span underneath+tooltipText ::+     (PostBuild t m, Dom.DomBuilder t m) => Dynamic t Text.Text -> m a -> m a+tooltipText = tooltipText' Rght++-- | Allows setting of initial direction+tooltipText' ::+     (PostBuild t m, Dom.DomBuilder t m)+  => ToolDirection+  -> Dynamic t Text.Text+  -> m a+  -> m a+tooltipText' dir tipDyn monad = T.spanDynAttr (tipToAttr dir <$> tipDyn) $ monad++tipToAttr :: ToolDirection -> Text.Text -> AttrMap+tipToAttr dir "" = tipToAttr dir "-"+tipToAttr dir tip =+  Map.fromList [("data-balloon", tip), ("data-balloon-pos", direction dir)]++direction :: ToolDirection -> Text.Text+direction Top  = "top"+direction Lft  = "left"+direction Rght = "right"+direction Down = "down"