mirror of
https://github.com/lagunoff/htmlt.git
synced 2024-10-04 02:47:08 +03:00
Lightweight frontend library for GHCJS
fbd8c5e16f
simpleList using Dynamic instead of DynRef |
||
---|---|---|
benchmarks | ||
examples | ||
src | ||
.gitignore | ||
8.6.0.nix | ||
8.10.7.nix | ||
htmlt.cabal | ||
README.md | ||
shell.nix |
Lightweight frontend library for GHCJS with focus on minimalism and simplicity
Getting started
First you have to install nix
package manager to download and install the dependecies. By default
nix-shell gets GHCJS compiler from
reflex-platform
project. You have to add their binary caches to your nix.conf
to
avoid building everything from sources
# ~/.config/nix.conf
substituters = https://nixcache.reflex-frp.org
trusted-substituters = https://nixcache.reflex-frp.org
trusted-public-keys = ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=
Build the examples:
# Clone the repository
git clone https://github.com/lagunoff/htmlt.git
cd htmlt
# Enter the nix-shell
nix-shell
# Build examples with cabal
cabal build -fexamples --ghcjs --ghcjs-options="-j"
Once cabal build
is successful you can find the js executables in
dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/htmlt-0.1.0.0/x/
and run them opening index.html
in browser
Simple example
-- Example featuring <input> element and two buttons. The input value
-- is synchronized with 'DynRef's state and can be modified by either entering a
-- number into the input or by clicking one of the two buttons
main :: IO ()
main = void $ attachToBody do
-- First create a 'DynRef'
counterRef <- newRef @Int 0
div_ do
input_ do
-- Show the value inside <input>
dynProp "value" $ T.pack . show <$> fromRef counterRef
-- Parse and update the value on each InputEvent
onDecoder "input" valueDecoder $
modifyRef counterRef . maybe id const . readMaybe . T.unpack
br_
-- Decrease the value on each click
button_ do
on_ "click" $ modifyRef counterRef pred
text "Decrease"
-- Increase the value on each click
button_ do
on_ "click" $ modifyRef counterRef succ
text "Increase"
Quick API summary
-- Constructing DOM
el :: Text -> Html a -> Html a
elns :: Text -> Text -> Html a -> Html a
text :: Text -> Html ()
dynText :: Dynamic Text -> Html ()
-- Applying attributes and properties
prop :: Text -> v -> Html ()
dynProp :: Text -> Dynamic v -> Html ()
attr :: Text -> Text -> Html ()
dynAttr :: Text -> Text -> Html ()
toggleClass :: Text -> Dynamic Bool -> Html ()
toggleAttr :: Text -> Dynamic Bool -> Html ()
dynStyle :: Text -> Dynamic Text -> Html ()
dynStyles :: Dynamic Text -> Html ()
dynValue :: Dynamic Text -> Html ()
dynClass :: Dynamic Text -> Html ()
dynChecked :: Dynamic Bool -> Html ()
dynDisabled :: Dynamic Bool -> Html ()
-- Handling DOM events
on :: EventName -> (DOMEvent -> Transact ()) -> Html ()
on_ :: EventName -> Transact () -> Html ()
onOptions :: EventName -> ListenerOpts -> (DOMEvent -> Transact ()) -> Html ()
onDecoder :: EventName -> Decoder a -> (a -> Transact ()) -> Html ()
onGlobalEvent :: ListenerOpts -> DOMNode -> EventName -> (DOMEvent -> Transact ()) -> Html ()
-- Decoding data from DOM Events
mouseDeltaDecoder :: Decoder MouseDelta
clientXYDecoder :: Decoder Position
offsetXYDecoder :: Decoder Position
pageXYDecoder :: Decoder Position
keyModifiersDecoder :: Decoder KeyModifiers
keyCodeDecoder :: Decoder Int
keyboardEventDecoder :: Decoder KeyboardEvent
targetDecoder :: Decoder JSVal
currentTargetDecoder :: Decoder JSVal
valueDecoder :: Decoder Text
checkedDecoder :: Decoder Bool
-- DOM extras, useful helpers
unsafeHtml :: MonadIO m => Text -> HtmlT m ()
portal :: Monad m => DOMElement -> HtmlT m a -> HtmlT m a
addFinalizer :: MonadReactive m => IO () -> m ()
-- Dynamic collections
simpleList :: DynRef [a] -> (Int -> DynRef a -> Html ()) -> Html ()
-- Arbitrary dynamic content
dyn :: Dynamic (Html ()) -> Html ()
-- Contructing Events
newEvent :: MonadReactive m => m (Event a, Trigger a)
fmap :: (a -> b) -> Event a -> Event a
never :: Event a
updates :: Dynamic a -> Event a
mapMaybeE :: (a -> Maybe b) -> Event a -> Event b
-- Constructing Dynamics
constDyn :: a -> Dynamic a
fromRef :: DynRef a -> Dynamic a
fmap :: (a -> b) -> Dynamic a -> Dynamic b
(<*>) :: Dynamic (a -> b) -> Dynamic a -> Dynamic b
mapDyn :: MonadReactive m => Dynamic a -> (a -> b)-> m (Dynamic b)
mapDyn2 :: MonadReactive m => Dynamic a -> Dynamic b -> (a -> b -> c) -> m (Dynamic c)
holdUniqDyn :: Eq a => Dynamic a -> Dynamic a
holdUniqDynBy :: (a -> a -> Bool) -> Dynamic a -> Dynamic a
-- Constructing DynRefs
newRef :: MonadReactive m => a -> m (DynRef a)
lensMap :: Lens' s a -> DynRef s -> DynRef a
zipRef :: DynRef a -> DynRef b -> DynRef (a, b)
zipRef3 :: DynRef a -> DynRef b -> DynRef c -> DynRef (a, b, c)
-- Read Dynamics
readDyn :: MonadIO m => Dynamic a -> m a
readsDyn :: MonadIO m => (a -> b) -> Dynamic a -> m b
-- Read and write DynRefs
readRef :: MonadIO m => DynRef a -> m a
readsRef :: MonadIO m => (a -> b) -> DynRef a -> m b
writeRef :: MonadIO m => DynRef a -> a -> m ()
writeSync :: DynRef a -> a -> Transact ()
modifyRef :: MonadIO m => DynRef a -> (a -> a) -> m ()
modifySync :: DynRef a -> (a -> a) -> Transact ()
-- Starting and shutting down the application
atatchOptions :: StartOpts -> Html a -> IO (a, RunningApp)
attachTo :: DOMElement -> Html a -> IO (a, RunningApp)
attachToBody :: Html a -> IO (a, RunningApp)
detach :: RunningApp -> IO ()
Other examples
Counter | source | demo |
TodoMVC | source | demo |
Simple Routing | source | demo |
Todos
- API to display sum types
- Reduce compile time by getting rid of
ghcjs-dom
andjsaddle-dom
from dependency list - Add benchmarks
- More examples and documentation
- Similar library for ReactNative