Skip to content

Commit

Permalink
Adds pursx (#8)
Browse files Browse the repository at this point in the history
* Adds pursx

* Fixes ffi bug
  • Loading branch information
Mike Solomon authored Mar 24, 2022
1 parent 44acd51 commit 2f6ba99
Show file tree
Hide file tree
Showing 23 changed files with 4,390 additions and 2,564 deletions.
2 changes: 2 additions & 0 deletions codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ def print_(x): return o.append(x)
unsafeUn{term} :: {term} -> {{ | {term}' }}
unsafeUn{term} ({term} unsafe) = unsafe
instance tagToDeku{term} :: TagToDeku "{astag(x)}" {term}
instance typeToSym{term} ::
TypeToSym {term} "{astag(x)}"
Expand Down
8 changes: 8 additions & 0 deletions examples/docs/Docs.purs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import Deku.Example.Docs.Effects as Effects
import Deku.Example.Docs.Events as Events
import Deku.Example.Docs.HelloWorld as HelloWorld
import Deku.Example.Docs.Intro as Intro
import Deku.Example.Docs.Pursx1 as Pursx1
import Deku.Example.Docs.Pursx2 as Pursx2
import Deku.Example.Docs.SSR as SSR
import Deku.Example.Docs.SimpleComponent as SimpleComponent
import Deku.Example.Docs.Subgraphs as Subgraph
Expand Down Expand Up @@ -69,10 +71,14 @@ scene elt dt =
/\ "Hello world"
/\ true +> SimpleComponent
/\ "Component"
/\ true +> PURSX1
/\ "Pursx 1"
/\ true +> Events
/\ "Events"
/\ true +> Effects
/\ "Effects"
/\ true +> PURSX2
/\ "Pursx 2"
/\ true +> Subgraph
/\ "Subgraphs"
/\ true +> SSR
Expand Down Expand Up @@ -107,6 +113,8 @@ scene elt dt =
page dpage Intro = Intro.intro dpage
page dpage HelloWorld = HelloWorld.helloWorld dpage
page dpage SimpleComponent = SimpleComponent.simpleComponent dpage
page dpage PURSX1 = Pursx1.pursx1 dpage
page dpage PURSX2 = Pursx2.pursx2 dpage
page dpage Events = Events.events dt dpage
page dpage Effects = Effects.effects dt dpage
page dpage SSR = SSR.serverSide dpage
Expand Down
6 changes: 3 additions & 3 deletions examples/docs/Effects.purs
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,16 @@ main = do
( detup $
D.span []
( S.text
"""In more complicated apps, like this documentation, we'll want to split up our components into sub-components and create a way for them to communicate back and forth. In the next section, we'll see one way to do this via """
"""It is also possible to handle events (and by extension effectful actions in events, like network calls) in Pursx. Let's see how in """
)
/\ D.a
[ cot dt $ cb
( const $ dpage Subgraph *>
( const $ dpage PURSX2 *>
scrollToTop
)
, D.Style := "cursor:pointer;"
]
(S.text "subgraphs")
(S.text "the second Pursx section")
/\ D.span []
( S.text "."
)
Expand Down
171 changes: 171 additions & 0 deletions examples/docs/Pursx1.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
module Deku.Example.Docs.Pursx1 where

import Prelude

import Data.Tuple.Nested ((/\))
import Deku.Control.Functions (u, freeze, (%>))
import Deku.Example.Docs.Types (Page(..))
import Deku.Example.Docs.Util (scrollToTop)
import Deku.Graph.Attribute (cb)
import Deku.Graph.DOM (ResolvedSubgraphSig, (:=))
import Deku.Graph.DOM as D
import Deku.Graph.DOM.Shorthand as S
import Deku.Pursx ((~!))
import Deku.Util (detup)
import Effect (Effect)
import Type.Proxy (Proxy(..))

pursx1 :: (Page -> Effect Unit) -> ResolvedSubgraphSig Unit Unit
pursx1 dpage =
( \_ _ ->
u
{ head: D.div []
{ header: D.header []
{ title: D.h1 [] (S.text "PursX 1")
, subtitle: D.h3 []
( S.text
"Like JSX... but better!"
)
}
, pars: D.div []
( detup
$
D.p []
( S.text
"""Writing out PureScript code for the DOM only really makes sense if you're doing some sort of interesting manipulations on the JS layer. Otherwise, it's pretty tedious and longer than HTML. Thankfully, there's a solution: PursX."""
)
/\ D.p []
( S.text
"""PursX takes its name from JSX and it accomplishes a similar goal: the ability to embed HTML in your document. In the example below, we create the same exact component from the previous article, but in PursX."""
)
/\
( D.pre []
( S.code []
( S.text $
"""module Deku.Example.Docs.Example.ComponentPursx where
import Prelude
import Data.Foldable (for_)
import Data.Tuple.Nested ((/\))
import Data.Vec ((+>), empty)
import Deku.Control.Functions (freeze, u, (@>))
import Deku.Control.Types (Frame0, Scene)
import Deku.Graph.DOM ((:=), root)
import Deku.Graph.DOM as D
import Deku.Graph.DOM.Shorthand as S
import Deku.Interpret (class DOMInterpret, makeFFIDOMSnapshot)
import Deku.Pursx ((~!))
import Deku.Run (defaultOptions, run)
import Deku.Util (detup, vex)
import Effect (Effect)
import FRP.Event (subscribe)
import Type.Proxy (Proxy(..))
import Web.DOM (Element)
import Web.HTML (window)
import Web.HTML.HTMLDocument (body)
import Web.HTML.HTMLElement (toElement)
import Web.HTML.Window (document)
scene
:: forall env dom engine push res
. Monoid res
=> DOMInterpret dom engine
=> Element
-> Scene env dom engine Frame0 push res
scene elt =
( \_ _ ->
( u $ root elt $ (Proxy :: _ """ <> "\"\"\"" <> """
<div>
<button>I do nothing</button>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
<div>
<a href="https://github.com/mikesol/purescript-deku">foo</a>
<i>bar</i>
<span style="font-weight:800;">baz</span>
</div>
<div><div></div><div><input type="range"/></div></div>
</div>
""" <> "\"\"\"" <> """") ~! {}
)
) @> freeze
main :: Effect Unit
main = do
b' <- window >>= document >>= body
for_ (toElement <$> b') \elt -> do
ffi <- makeFFIDOMSnapshot
subscribe
( run (pure unit) (pure unit) defaultOptions ffi(scene elt) )
(_.res >>> pure)
"""
)
)
)

/\ D.p []
( detup $
( D.text
"Here's what it produces:"
)
/\ unit
)
/\ D.blockquote []
((Proxy :: _ """
<div>
<button>I do nothing</button>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
<div>
<a href="https://github.com/mikesol/purescript-deku"></a>
<i>bar</i>
<span style="font-weight:800;">baz</span>
</div>
<div><div></div><div><input type="range"/></div></div>
</div>
""") ~! {})
/\ D.h2 [] (S.text "Puurrrrrr ...sx")
/\ D.p []
( detup $
D.text
"""Pursx can be activated with the operators """
/\ D.code [] (S.text "~!")
/\ D.text
""", which creates a one-off record, and """
/\ D.code [] (S.text "~~")
/\ D.text
"""for when you already have a record that you're embedding it in. It's also slightly faster than the JS layer, as it just sets the """
/\ D.code [] (S.text "innerHTML")
/\ D.text
""" property of a node with the HTML. JavaScript parsers are blazingly fast at setting innerHTML these days, and you can achieve substantial performance gains this way, especially with larger documents. In a later section, we'll see how to modify our PursX and embed PureScript within it, just like we do with JSX."""
/\ unit
)
/\ D.h2 [] (S.text "Next steps")
/\ D.p []
( S.span []
(detup $ D.text
"""In this section, we PursX to build the same component as the previous section. In the next section, we'll learn how to respond to """
/\ D.a
[ D.OnClick := cb
( const $ dpage Events *>
scrollToTop
)
, D.Style := "cursor:pointer;"
]
(S.text "events")
/\ D.span []
( S.text "."
)
/\ unit
)
) /\ unit)
}
}
) %> freeze
Loading

0 comments on commit 2f6ba99

Please sign in to comment.