hyperbole-0.5.0: src/Web/Hyperbole/HyperView/Input.hs
module Web.Hyperbole.HyperView.Input where
import Data.String.Conversions (cs)
import Data.Text (Text)
import Web.Atomic.Types
import Web.Hyperbole.Data.Param (ParamValue (..), ToParam (..))
import Web.Hyperbole.HyperView.Event (DelayMs, onChange, onClick, onInput)
import Web.Hyperbole.HyperView.Types (HyperView (..))
import Web.Hyperbole.HyperView.ViewAction (ViewAction (..))
import Web.Hyperbole.Route (Route (..), routeUri)
import Web.Hyperbole.View
{- | \<button\> HTML tag which sends the action when pressed
@
#EMBED Example/Page/Simple.hs messageView
@
-}
button :: (ViewAction (Action id)) => Action id -> View id () -> View id ()
button action cnt = do
tag "button" cnt @ onClick action
-- tag "button" @ att "whatber" "asdf" $ cnt
-- {- | \<input type="checkbox"\> which toggles automatically
--
-- > toggle True SetIsSelected id
-- -}
-- toggle :: (ViewAction (Action id)) => Bool -> (Bool -> Action id) -> Mod id -> View id ()
-- toggle isSelected clickAction f = do
-- tag "input" (att "type" "checkbox" . checked isSelected . onClick (clickAction (not isSelected)) . f) none
{- | Type-safe dropdown. Sends (opt -> Action id) when selected. The default will be selected.
#EXAMPLE /data/filter
@
#EMBED Example/Page/DataLists/Filter.hs familyDropdown
@
-}
dropdown
:: (ViewAction (Action id))
=> (opt -> Action id)
-> opt -- default option
-> View (Option opt id) ()
-> View id ()
dropdown act defOpt options = do
tag "select" @ onChange act $ do
addContext (Option defOpt) options
-- | An option for a 'dropdown' or 'select'
option
:: (ViewAction (Action id), Eq opt, ToParam opt)
=> opt
-> Text
-> View (Option opt id) ()
option opt cnt = do
os <- context
tag "option" @ att "value" (toParam opt).value @ selected (os.defaultOption == opt) $ text cnt
-- | sets selected = true if the 'dropdown' predicate returns True
selected :: (Attributable h) => Bool -> Attributes h -> Attributes h
selected b = if b then att "selected" "true" else id
-- | The view context for an 'option'
data Option opt id = Option
{ defaultOption :: opt
}
{- | A live search field. Set a DelayMs to avoid hitting the server on every keystroke
@
#EMBED Example/Page/Errors.hs viewSearchUsers
@
-}
search :: (ViewAction (Action id)) => (Text -> Action id) -> DelayMs -> View id ()
search go delay = do
tag "input" none @ onInput go delay
-- | Set checkbox = checked via the client (VDOM doesn't work)
checked :: (Attributable a) => Bool -> Attributes a -> Attributes a
checked c =
att "data-checked" (cs $ show c)
. if c then att "checked" "" else id
{- | A hyperlink to another route
>>> route (User 100) id "View User"
<a href="/user/100">View User</a>
-}
route :: (Route a) => a -> View c () -> View c ()
route r = link (routeUri r)