Skip to content

Commit

Permalink
No subgraphs (#13)
Browse files Browse the repository at this point in the history
* Adds experiment with no subgraphs

* Adds back docs before editing

* Updates event

* Fixes send to top

* Adds missing files

* Adds example

* Adds portal example

* A farewell to subgraphs

Co-authored-by: Mike Solomon <[email protected]>
  • Loading branch information
Mike Solomon and Mike Solomon authored Apr 23, 2022
1 parent 92c2346 commit d9468d9
Show file tree
Hide file tree
Showing 171 changed files with 4,738 additions and 4,323 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.0] - 2022-04-23

- Gets rid of subgraphs and greatly simplifies code base.

## [0.2.6] - 2022-04-18

- Adds hack for working with a 2D canvas.
Expand Down
33 changes: 17 additions & 16 deletions codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def noop_(x): return None
noop_(f''' , {term}
, {x}
, {x}_''')
print_(f'''import Deku.DOM.Elt.{term.split('_')[0]}''')
print_(f'''import Deku.DOM.Elt.{term.split('_')[0]}({term}, {x}, {x}_)''')

elif CODEGEN_TARGET == GENERATE_DOM_TTD:
for x in TAGS:
Expand All @@ -110,26 +110,27 @@ def noop_(x): return None
import Control.Plus (empty)
import Deku.Attribute (Attribute)
import Deku.Control (elementify)
import Deku.Core (Element)
import FRP.Event (class IsEvent)
import Deku.Control (elementify, class Plant, plant)
import Deku.Core (StreamingElt, Element)
import FRP.Event (Event)
data {term}
{x}
:: forall event payload
. IsEvent event
=> event (Attribute {term})
-> Array (Element event payload)
-> Element event payload
{x} = elementify "{astag(x)}"
:: forall seed lock payload
. Plant seed (Event (Event (StreamingElt lock payload)))
=> Event (Attribute {term})
-> seed
-> Element lock payload
{x} attributes seed = elementify "{astag(x)}" attributes (plant seed)
{x}_
:: forall event payload
. IsEvent event
=> Array (Element event payload)
-> Element event payload
:: forall seed lock payload
. Plant seed (Event (Event (StreamingElt lock payload)))
=> seed
-> Element lock payload
{x}_ = {x} empty
''')
elif CODEGEN_TARGET == GENERATE_ATTR_DECL:
for x in AMAP.keys():
Expand All @@ -145,12 +146,12 @@ def noop_(x): return None
for x in AMAP.keys():
term = bigat(x)
noop_(f''' , {term}(..)''')
print_(f'''import Deku.DOM.Attr.{term}''')
print_(f'''import Deku.DOM.Attr.{term}({term}(..))''')

for x in GLOBAL_EVENT_HANDLERS:
term = 'On'+x.capitalize()
noop_(f''' , {term}(..)''')
print_(f'''import Deku.DOM.Attr.{term}''')
print_(f'''import Deku.DOM.Attr.{term}({term}(..))''')
elif CODEGEN_TARGET == GENERATE_ATTR_DEFS:
x = ival
k = ival
Expand Down
4 changes: 3 additions & 1 deletion examples.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ in conf
, "filterable"
, "affjax"
, "either"
, "integers"
, "aff"
, "argonaut-core"
, "deku-toplevel"
, "web-uievents"
, "http-methods"
, "maybe"
, "typelevel"
]
}
42 changes: 15 additions & 27 deletions examples/canvas/Canvas.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,38 @@ module Deku.Example.Canvas where

import Prelude

import Control.Plus (empty)
import Data.Foldable (for_, oneOfMap)
import Data.Tuple (Tuple(..))
import Deku.Attribute ((:=))
import Deku.Control (deku, flatten)
import Deku.Control (deku2)
import Deku.Core (Element)
import Deku.DOM as D
import Deku.Interpret (FFIDOMSnapshot, effectfulDOMInterpret, makeFFIDOMSnapshot)
import Effect (Effect)
import FRP.Event (Event, create, mapAccum, subscribe)
import FRP.Event (Event, subscribe)
import FRP.Event.Class (bang)
import Graphics.Canvas (fillRect, setFillStyle)
import Web.HTML (window)
import Web.HTML.HTMLDocument (body)
import Web.HTML.HTMLElement (toElement)
import Web.HTML.Window (document)

counter :: forall a. Event a β†’ Event (Tuple a Int)
counter event = mapAccum f event 0
where
f a b = Tuple (b + 1) (Tuple a b)
scene
:: (Boolean -> Effect Unit)
-> Event Boolean
-> Element Event (FFIDOMSnapshot -> Effect Unit)
scene _ _ =
flatten
[ D.canvas
( oneOfMap bang
[ D.Width := "400px"
, D.Height := "400px"
, D.Draw2D := \ctx -> do
setFillStyle ctx "blue"
fillRect ctx { height: 100.0, width: 100.0, x: 0.0, y: 0.0 }
]
)
[]
]
scene :: forall lock. Element lock (FFIDOMSnapshot -> Effect Unit)
scene = D.canvas
( oneOfMap bang
[ D.Width := "400px"
, D.Height := "400px"
, D.Draw2D := \ctx -> do
setFillStyle ctx "blue"
fillRect ctx { height: 100.0, width: 100.0, x: 0.0, y: 0.0 }
]
)
(empty :: Event (Element lock (FFIDOMSnapshot -> Effect Unit)))

main :: Effect Unit
main = do
b' <- window >>= document >>= body
for_ (toElement <$> b') \b -> do
ffi <- makeFFIDOMSnapshot
{ push, event } <- create
let evt = deku b (scene push event) effectfulDOMInterpret
let evt = deku2 b scene effectfulDOMInterpret
void $ subscribe evt \i -> i ffi
push true
49 changes: 28 additions & 21 deletions examples/docs/Component.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,23 @@ module Deku.Example.Docs.Component where

import Prelude

import Control.Plus (class Plus)
import Deku.Attribute (cb, (:=))
import Deku.Control (text_)
import Deku.Control (blank, text_)
import Deku.Core (Element)
import Deku.DOM as D
import Deku.Example.Docs.Types (Page(..))
import Deku.Example.Docs.Util (scrollToTop)
import Deku.Pursx (nut, (~~))
import Effect (Effect)
import FRP.Event (class IsEvent)
import FRP.Event.Class (bang)
import FRP.Event (bang)
import Type.Proxy (Proxy(..))

px = Proxy :: Proxy """<div>
<h1>A Simple Component</h1>
<h3>Slightly more bells and whistles</h3>
<p>
Let's look at an example with several different DOM tags. There are also a few different syntax options depending on what tune your fingers wish to type.
Let's look at an example with several different DOM tags.
</p>
~code~
Expand All @@ -29,20 +27,28 @@ px = Proxy :: Proxy """<div>
<blockquote> ~result~ </blockquote>
<h1>Elements all the way down</h1>
<p>Deku encodes the DOM using functions that represent elements. To create an element with a custom tag called <code>foo</code>, you can call <code>elementify "foo"</code> and that will creat a custom <code>foo</code> tag in your DOM.</p>
<p>The encoding of elements in Deku is not unlike that in React or Halogen. It's a tree, like the Deku tree. So go nuts!</p>
<h1>Creating an element</h1>
<p>To create an element, like for example a <code>span</code> element, the pattern goes like this:</p>
<pre><code>mySpanWithAttrs = D.span attrs children
mySpanWithNoAttrs = D.span_ children
myDivWithNoChildren = D.div attrs blank
</code></pre>
<p><code>attrs</code> contains attributes of type <code>Event (Attribute element)</code>, where <code>element</code> is the current element you're assigning attributes to. You never have to specify this type: it is inferred automatically by the attribute creation operator, aka <code>:=</code>. If you use an attribute that's unsupported by an element, the compiler will complain.</p>
<p>For now, children is an array of children, not unlike Halogen or React sans JSX. We'll see some other types of children later in this guide.</p>
<h1>Attributes</h1>
<p>Elements postfixed with an underscore do not take attributes. That is un-fun, so in this example, you see attributes as well! Attributes like an element's style or id are specified as the first argument to an underscore-less element. Note that, if you have multiple attributes, you have to separate them with <code>alt</code>, aka "the tie fighter." Also, the many <code>bang</code>-s you'll see around attributes are from the <code>purescript-event</code> library. Bang means <i>right now</i>, which is the answer to the question "When should we set this attribute?"</p>
<p>Attributes like an element's style or id are specified as the first argument to an element. Attributes are just <a href="https://github.com/mikesol/purescript-event/blob/master/src/FRP/Event.purs"><code>Event</code>-s</a>, so you can <code>bang</code> them to make them happen <i>now</i>, combine two event streams with <code>alt</code> to compose events, etc.</p>
<p>As an example, we made the input a range slider using <code>bang (Xtype := "range")</code>. Unlike Halogen, there are no checks to make sure you give a valid string. So if you want your range slider to have the value of true, you can. One day, I may build some validators, but passing strings works decently well here.</p>
<h2>Next steps</h2>
<p>In this section, we built a simple component. In the next section, we'll recreate the exact same element using a different input syntax called <a ~next~ style="cursor:pointer;">Pursx</a>.</p>
</div>"""

components :: forall event payload. IsEvent event => Plus event => (Page -> Effect Unit) -> Element event payload
components :: forall lock payload. (Page -> Effect Unit) -> Element lock payload
components dpage = px ~~
{ code: nut
( D.pre_ [D.code_
Expand All @@ -51,17 +57,17 @@ components dpage = px ~~
import Prelude
import Deku.Control (flatten, text_)
import Deku.DOM as D
import Deku.Attribute ((:=))
import Deku.Toplevel ((πŸš€))
import Deku.Control (blank, text_)
import Deku.DOM as D
import Deku.Toplevel (runInBodyA)
import Effect (Effect)
import FRP.Event.Class (bang)
main :: Effect Unit
main = unit πŸš€ \_ _ ->
flatten
[ D.button_ [ text_ "I do nothing" ]
, D.ul_ $ map (D.li_ <<< pure <<< text_) [ "A", "B", "C" ]
main = runInBodyA
( [ D.button_ [ text_ "I do nothing" ]
, D.ul_ $ map (D.li_ <<< text_) [ "A", "B", "C" ]
, D.div_
[ D.a (bang $ D.Href := "https://example.com")
[ text_ "foo " ]
Expand All @@ -71,16 +77,17 @@ main = unit πŸš€ \_ _ ->
]
, D.div_
[ D.div_
[ D.div_ [ D.input (bang $ D.Xtype := "range") [] ]
[ D.div_ [ D.input (bang $ D.Xtype := "range") blank ]
]
]
]"""
]
)"""
]]
)
, result: nut
( D.div_
[ D.button_ [ text_ "I do nothing" ]
, D.ul_ $ map (D.li_ <<< pure <<< text_) [ "A", "B", "C" ]
, D.ul_ $ map (D.li_ <<< text_) [ "A", "B", "C" ]
, D.div_
[ D.a (bang $ D.Href := "https://example.com")
[ text_ "foo " ]
Expand All @@ -90,7 +97,7 @@ main = unit πŸš€ \_ _ ->
]
, D.div_
[ D.div_
[ D.div_ [ D.input (bang $ D.Xtype := "range") [] ]
[ D.div_ [ D.input (bang $ D.Xtype := "range") blank ]
]
]
]
Expand Down
Loading

0 comments on commit d9468d9

Please sign in to comment.