alexmingoia / purescript-pux Goto Github PK
View Code? Open in Web Editor NEWBuild type-safe web apps with PureScript.
Home Page: https://www.purescript-pux.org
License: Other
Build type-safe web apps with PureScript.
Home Page: https://www.purescript-pux.org
License: Other
Shouldn't (#) from http://www.alexmingoia.com/purescript-pux/docs/API/Pux/Html.html have right fixity instead of left fixity. To me it makes sense to write something like div # h5 # text "lala"
but this doesn't work without parenthesis div # (h5 # text "lala")
or with Pux.Html.bind div # do h5 # text "lala"
"&" get's turned into & by the "text" function.
is there a function for rendering html without further processing ?
For those who need a custom start
function, it would be useful to export the render
function from Pux
.
I had looked around for information about using Pux with existing React components but was not successful in finding anything. I have an existing React system and I'd like to start converting it over bit by bit into Purescript. Is there an existing way to have a view render existing components including passing down props? If not, where would be a good place to look to add such functionality?
I'm trying to translate some Elm tutorials into Pux, but currently getting stuck with inter-component communication: https://github.com/evancz/elm-architecture-tutorial/#example-4-a-fancier-list-of-counters.
I'm struggling with how to get the child to communicate with the parent. In javascript, I could just pass a callback to the child. In Elm, they have the notion of addresses, for decoupled communication. I'm wondering how to do this in a typesafe way, without cyclical dependencies?
Thanks from an FP beginner :)
The documentation is out of date with latest release. For example the following snippet (from the docs) no longer compiles:
div # do
button ! onClick (const Increment) # text "Increment"
span # text (show count)
button ! onClick (const Decrement) # text "Decrement"
https://www.alexmingoia.com/purescript-pux/docs/API/Pux/Html.html
https://github.com/alexmingoia/purescript-pux/blob/master/src/Pux/Router.js#L37 is failing in IE. To workaround I had to use https://github.com/krambuhl/custom-event-polyfill with window.Event = window.CustomEvent
. There is a more detailed discussion at krambuhl/custom-event-polyfill#6 (comment) where maintainer of custom-event-polyfill
claims this should be fixed in purescript-pux
.
If you find this a valid point, we can use CustomEvent
implementation if browser doesn't support Event
but I am not sure this should be pux
concern at all.
I want an Action
to do nothing to the State
and kick off an effect (whose result does something to the state). The problem is that in update
I don't see a way not to set the state, even if I want it not to change. And if the effect returns very quickly, its signal gets rendered before the do-nothing change to the state. Here is a really contrived minimal example (the actual way I found this was more complicated and involved random numbers):
data Action = Increment | EffIncrement | Receive Int
type State = Int
update :: Action -> State -> EffModel State Action (console :: CONSOLE)
update Increment count =
trace ("Increment: " ++ show count) \_ -> { state: count + 1, effects: [] }
update (Receive c) count =
trace ("Receive: " ++ show c) \_ -> { state: c, effects: [] }
update EffIncrement count =
-- I don't actually want to change the state here, but what can I do?
trace "EffIncrement" \_ -> { state: count, effects: [pure $ Receive (count + 1)]}
view :: State -> Html Action
view count =
div # do
button ! onClick (const Increment) # text "Increment"
span # text (show count)
button ! onClick (const EffIncrement) # text "EffIncrement"
If I click on EffIncrement
, the Receive (count + 1)
signal gets rendered first. So if I click EffIncrement
, what happens is the Receive 1
redraw happens before the state: 0
redraw, so the state gets updated but the UI appears not to. Then if you (e.g.) click Increment
it goes up to 3.
A hacky solution is to artificially add a small delay to my fast effects, is there a better way?
(gist with full code: https://gist.github.com/joelgrus/f65b4106cdf32f4bc1109f0e1a0e0497)
Currently all events with a target specify target :: Target
and type Target = { value :: String }
which is incorrect. Inspecting the value returned in the MouseEvent shows that target is a DOM element. This could be represented by a Pux type or probably better a DOM.Node.Node
so that it could be passed in directly to DOM functions.
I'm working with an API where every API call can potentially fail with a "two-factor-authentication-code-required" error and need to be retried with the exact same arguments (modulo the two factor code). There's also some additional stuff with using HMAC for authentication.
To make the API a bit easier to use, there's a purescript library I've already implemented. The library uses the Reader monad to take a function from the UI that runs the API call, and if the call fails it promps the user for a two-factor code and passes it to the API call:
type Runner a e =
(Maybe TwoFactor -> Aff (AuthEffects e) (Either TwoFactorRequired (Either APIError (APIResponse a))))
-> MaybeT (Aff a) (Either APIError (APIResponse a))
type MyAPI e a = forall a b. (Respondable b) =>
ReaderT { runner :: Runner a e} (MaybeT (Aff a)) (AffjaxResponse (APIResponse b))
getProfile :: forall e . GetProfileReq -> MyAPI (now:: NOW | e) GetProfileResp
Is there a good way to create this callback in pux, using signals and channels?
This should be made available as a third party wrapper component. Maybe purescript-pux-transition
or something
I'm thinking it might be useful to turn Pux.Router
into a separate project by moving the tiny bits that depend on Pux.Html
and perhaps on Signal
out of Pux.Router
. Would that make sense, as an alternative to https://github.com/slamdata/purescript-routing?
In React, you can render children components using props.children
const Layout = props => (<div>{props.children}</div>)
const Menu = () => (<Layout><ul><li><a>Link</a></li></ul></Layout>)
which would render <ul><li><a>Link</a></li></ul>
inside the Layout div.
Is there any way to do this in Pux?
Thanks
Hi,
I'm experimenting with pux in a public project. Its just pretty much a pux app with a bunch of small demos of increasing complexity. One of them is an AJAX-backed list. I have a component for the AJAXList and a child component for the AJAXListItem, and the Action for AJAXList is partly composed of child actions for AJAXListItem, which seems pretty standard. Interestingly, in the AJAX list case, firing an item's Delete action should get wrapped in the parent's ItemAction constructor, but it actually results in a pattern match failure. It almost seems like the wrong signal is being provided to the wrong component.
Here's how you'd repro it:
git clone https://github.com/MichaelXavier/pux-scrapyard.git --branch rest
cd pux-scrapyard
npm install
bower install
npm run-script build
npm run-script server
Browse to http://localhost:8000 and click on AJAX List
, then open your dev console and click Delete
by the first item. You'll see the following error in the console:
index.js:25374 Uncaught Error: Failed pattern match at Components.AJAXList line 60, column 1 - line 61, column 45: DeleteItem,Object
The function in question is expecting to receive ItemAction Int AJAXListItem.Action
but is instead receiving AJAXListItem.Action
, despite the types check passing.
Interestingly, there's also a demo there for a non-effectful list/listitem component that works fine. This leads me to believe that something about the effects system may be causing a signal to get routed to the wrong component or perhaps its dropping the wrapped version of the signal it uses for the parent's update function.
Sorry for the somewhat convoluted repro steps. Please let me know if there's any further info I can provide!
I'm trying to figure out how to translate some Javascript architecture into Pux / Purescript. This is for a desktop application using Electron. I have in several places UI events that fire off Async events that are currently observed by several different components via Flux store change emit events. I was thinking that the extra inputs array that can be provided to a component could possibly be used for this, but the action
type for all the signals must be the same so that they can be merged. I could expose a global signal and then wire up Signal.runSignal somewhere via FFI but that feels pretty messy. Do you have any idea how I could provide a global events signal that can be used by my async background processes to signal progress/success/failure to all the components that would need it? Is there perhaps a better way to do what I'm going for that doesn't require components up the chain to be explicitly aware of the data needed by components down the chain?
I'm thinking of something like:
myHtml :: Maybe v -> Html Action
myHtml v = div [] [
span [] [ text "my text" ]
, case v of
Just v -> span [] [ text v ]
Nothing -> Nothing --<< how do I represent a "null" element -- similar to "when" in monadic code?
]
equivalent to:
if (myVar == true) {
html += "<div>text</div>"
}
in a real application there is likely to numerous values / properties that might conditionally generate html so it isn't practical to duplicate the entire function for every element.
I love the shorthand syntax for specifying HTML elements. However, some elements don't have children, for example:
img ! href "foo.jpg"
Unfortunately this doesn't work ๐ญ
hey, cool that 1.0.0 is out, I discovered it by accident today. a couple of challenges:
Html a
type, the !
sugar doesn't work for childless elements. e.g. in previous versions I would have done something likeimg ! src "me.jpg" ! alt "me"
but now the types don't work out. I ended up doing
img [src "me.jpg", alt "me"]
but is there a better way?
withChildren
method feels like it should be called withChild
? Since it takes a single Html a
child element? I don't know if it's just me, but I always end up needing to use an array of child elements. I see in the examples you use ol [] $ map ..
. Is that the cleanest way?I ended up defining
withChildren' :: forall a.
(Array (Attribute a) -> Array (Html a) -> Html a) ->
Array (Html a) ->
Html a
withChildren' f htmls = f [] htmls
infixl 4 withChildren' as ##
and then doing div ## map ...
but wasn't sure if there's a simpler way.
3 I got some issues about react
and react-dom
not being defined, I ended up having to npm install
them. I guess maybe that's expected? Might be nice in the docs.
Anyway, still love the framework. :)
I can't find this package in pursuit.purescript.org. Please help I have a demo organized on saturday for my team to use PureScript with Pux.
Thanks in advance!
I use onClick on a bunch of div
elements and the Action handler needs to know which of those div
elements was clicked.
It does not look like there is a way to do this?
There is event.target.value
(a String) but the browser craps out when trying to access this field:
[Error] TypeError: undefined is not an object (evaluating 'val.constructor')
(anonymous function) (Anonymous Script 16 (line 20))
stringify
stateToString (Anonymous Script 16 (line 19))
(anonymous function) (Anonymous Script 17 (line 243))
(anonymous function) (Anonymous Script 18 (line 75))
(anonymous function) (Anonymous Script 19 (line 25))
(anonymous function) (Anonymous Script 19 (line 14))
forEach
set (Anonymous Script 19 (line 14))
(anonymous function) (Anonymous Script 19 (line 25))
(anonymous function) (Anonymous Script 19 (line 14))
forEach
set (Anonymous Script 19 (line 14))
(anonymous function) (Anonymous Script 19 (line 57))
(anonymous function) (Anonymous Script 19 (line 14))
forEach
set (Anonymous Script 19 (line 14))
(anonymous function) (Anonymous Script 19 (line 14))
forEach
set (Anonymous Script 19 (line 14))
(anonymous function) (Anonymous Script 20 (line 16))
(anonymous function) (Anonymous Script 21 (line 12))
(anonymous function)
dispatchEvent
invokeGuardedCallback (Anonymous Script 22 (line 70))
executeDispatch (Anonymous Script 23 (line 89))
executeDispatchesInOrder (Anonymous Script 23 (line 112))
executeDispatchesAndRelease (Anonymous Script 24 (line 44))
forEach
forEachAccumulated (Anonymous Script 25 (line 25))
processEventQueue (Anonymous Script 24 (line 231))
runEventQueueInBatch (Anonymous Script 26 (line 18))
handleTopLevel (Anonymous Script 26 (line 29))
handleTopLevelImpl (Anonymous Script 27 (line 73))
perform (Anonymous Script 9 (line 138))
batchedUpdates (Anonymous Script 10 (line 63))
batchedUpdates (Anonymous Script 11 (line 98))
dispatchEvent (Anonymous Script 27 (line 150))
dispatchEvent
Is this related to #40?
As the title says, for some reason after the hot reload takes place, the effects returned by my update
function happens twice. And it seems like it's only for the PageView
action.
To reproduce...
update
function to use EffModel
, add a couple routes, and add some link
to the Counter view so we can change between pages.console.log
fires once per page view, great.console.log
messages fire twice each time! If you hot-reload a third time, now each page view triggers 3 console logs... and so on.From a fresh project and an update function is as simple as this...
update (PageView route) state =
{ state: state { route = route }
, effects: [ (liftEff $ log "pageview action" >>= (\_ -> pure NoOp)) ]
}
It only doubles the effects of the PageView actions, so it's something related to the popstate handler / history API, but as far as I can tell the javascript handlers in Router.js
are only being run once.
Am I doing something seriously wrong or did I find a bug? Could it be something to do with webpack 2?
(I can upload a GitHub repo that reproduces the issue)
It might make sense to make these explicit dependencies in the bower file.
This is supposed to be a discussion thread about CSS in Pux
.
Currently - due to its use of react
- Pux
's style
function takes a record of camelCased versions of CSS properties.
myStyle = { backgroundColor : "red" }
As it stands, there are a few things that I think could be improved:
Currently, errors like
myStyle = { backgroundColor : "re" }
or
myStyle = { backgroundColo : "red" }
are not caught at compile time. By using a solution like purescript-css, this could be remedied.
In PureScript, it's not (yet) possible to combine two records into one.
As far as I can tell, things like
const myStyleWithRedBorder =
{ ...myStyle
, border : "1px solid red"
}
are not possible right now in Pux
.
For this issue, one could adopt Elm
's approach of style
taking an Array of (key, value) pairs.
@alexmingoia I'm sure you have already thought about these issues and so I'd be curious to know your stance on this.
Options like:
I have a hard time to choose between them, a highlevel overview of what sets them apart would be awesome!
What are your thoughts on Elm 0.17-like subscriptions
?
From what I can tell there are basically two advantages to signals:
MouseMove
events.It should also make the architecture simpler in some cases:
Suppose there's a deeply nested component in your app that needs to know about window dimensions. With the current architecture you would need to feed Signal.DOM.windowDimensions
to the inputs
array at the top-level and manually pass that information down your component tree either via props or via actions.
With the subscription-based approach, it should be possible to have a deeply nested component declare that it wants to listen to window dimensions and let the framework take care of the rest.
-- Deeply nested component
data Action = ResizeEvent WindowDimensions
updateSub :: Action -> Model -> Sub Action
updateSub _ _ = Subscription.DOM.windowDimensions ResizeEvent
-- Intermediate components would simply map over the child components
data Action = ChildAction Child.Action
updateSub :: Action -> Model -> Sub Action
updateSub (ChildAction act) state =
possiblyLocalSubscriptions <> map ChildAction (Child.updateSub act state.childState)
What do you think about this?
I'm working on a toy app with a recursive structure. Here's my action:
data Action
= Child Int Action
| UpdateWeight Int Number
| UpdateScore (Score Number)
| AddGrade
| Undo
| Redo
And an example on how I'm using it:
renderScore :: Array (Score Number) -> Html Action
renderScore gs = H.div # do
H.button ! E.onClick (const AddGrade) # H.text "Add Grade"
H.ul ##
forEachIndexed gs \i g ->
H.li # (H.forwardTo (Child i) (viewGrade g))
When the UI gets nested, forwardTo
uses the most recent function given. It'd be nice if it composed the functions instead.
Background: I'm kind of new to Purescript and FP in general
While adding new pages the pux start app, I faced a runtime talking about puxParentAction
. I had no idea where I was wrong.
foreign.js:28 Uncaught TypeError: Cannot read property 'puxParentAction' of undefined
That's only after a long debugging session in the compiled JS that I could realize that my new view did not return a react component:
view :: forall state action. state -> Html action
view _ = text "Hello!"
This perfectly compiled however, and I was convinced that using text
from Pux.Html
was a fair use. This has been very confusing for a beginner like me, who has at least a good knowledge of react.
Html
is defined as follows (same for Attributes
):
foreign import data Html :: * -> *
In my opinion, the fact that Html
can be anything is a flaw in pux as it can easily lead to mistakes causing runtime crashes.
Considering react's architecture, we'd need some smart way to manage two kinds: elements and child elements. Indeed, the render
function must strictly return a react component (or "null" since react 15). Child elements however can be strings or arrays.
I hope this issue makes sense, please tell me if I misunderstood anything, and thanks for your commitment in this community!
-- | App configuration
config :: forall eff. State -> Eff (dom :: DOM | eff) (Config State Action AppEffects)
config state = do
-- | Create a signal of URL changes.
urlSignal <- sampleUrl
-- | Map a signal of URL changes to PageView actions.
let routeSignal = urlSignal ~> \r -> PageView (match r)
pure
{ initialState: state
, update: update
, view: view
, inputs: [ routeSignal
, constant DummyOne -- Note the addtional constant inputs
, constant DummyTwo
]
}
-- | Entry point for the browser.
main :: State -> Eff (CoreEffects AppEffects) (App State Action)
main state = do
app <- start =<< config state
renderToDOM "#app" app.html
-- | Used by hot-reloading code in support/index.js
pure app
Given inputs: [ routeSignal, constant DummyOne, constant DummyTwo]
, the only action initially run when you load the page will be DummyTwo, and DummyOne and PageView are never emitted.
However, if you have inputs: [routeSignal, every second ~> const DummyOne, constant DummyTwo]
, then, while the only action to be fired initially is DummyTwo, DummyOne will be fired every second after the website is loaded.
This was discussed on the Gitter channel. Since the output of Pux is 1 React component there is no place to use React's shouldComponentUpdate
and thus avoid constructing vdom elements. Alex has suggested thunkifying the views which would allow deferring running them similarly to how React avoids running render.
Some questions:
โข What does React put in the vdom when shouldComponentUpdate returns false?
โข How can views be thunkified without requiring the user to add something to their code?
Right now it seems Pux will call preventDefault
only for onSubmit
and onClick
event handlers. Trying to use the drag-and-drop API, for example to handle dropped files, requires calling this function for the drag and drop events (for example, it's required to prevent the browser from navigating away from the page when an image file is dropped, most browsers will navigate to the dropped file):
Also, can this be made optional? Is it a good idea to force Pux users to call preventDefault, when there might be situations to run a function before allowing the default action to happen?
It'd be easier if instead of keeping examples in the pux repository, they would instead be branches of the pux-starter-app repository. That way anyone could get an example up and running by cloning that branch and running npm start
.
How would one paint onto a canvas element with the Pux approach?
The documentation could always be better. I'd like this issue to be an open-ended discussion on the documentation.
Todo
EXCEPTION
effect because Pux's start
/ CoreEffects
is already parametized with it.Hello,
is there a way to define component lifecycle methods when defining a view
?
Thanks for this awesome library ! ๐
I'm writing a somewhat extensive app using Pux (currently around 20 components, but likely to be 200 or more). Basically, it's typical app but goes well beyond the relatively simple (but elegant) example apps that currently exist like #https://github.com/spicydonuts/pux-rock-paper-scissors.
To give you an idea, my app implements nested routes as discussed here ##59. It has a structure very similar to this:
โโโ Application
โ โโโ Repository
โ โ โโโ Issues
โ โ โ โโโ IssueList.purs
โ โ โ โโโ NewIssue.purs
โ โ โโโ Issues.purs
โ โโโ Repository.purs
โโโ Application.purs
For various reasons there are certain values that would be useful to share throughout most of the app. For example a user id, name and authentication token. (But also, conceivably numerous run time configuration options). The only way I can see to do this is by explicitly passing these values through Actions which seems quite clumsy and verbose?
I'm aware of purescript-refs although I'm not quite sure how to use it. Might that be a reasonable solution?
Am I missing something else?
This would be great to have for Pux.
The <text>
element is missing form Pux.Html.Elements
. Probably because the function would be in name conflict with the existing text
function (text :: forall a. String -> Html a
).
In my project I created a svgText
function, but I'm not happy with the naming because it is not consistent with the other functions.
What about removing the current text
function in favour of fromString
(which it really is, after all), and so we can use text
for the HTML element?
It seems that Pux.Router
(line 37) is missing a dependency - purescript-globals/src/Global.purs - can anybody reproduce this?
the fix is simple - add
"purescript-globals": "^1.0.0"
to the dependencies in bower.json
Providing an array of external signals via the inputs
field can be problematic if one uses signals that typically fire only once at the beginning.
Take e.g. the following example in which the app is supposed to read in the current window dimensions and the current route via Signal.DOM.windowDimensions
and Pux.Router.sampleUrl
:
module Main where
import Control.Alt ( (<|>) )
import Control.Apply ( (<*) )
import Control.Monad.Eff ( Eff )
import Data.Functor ( (<$) )
import Data.Generic ( class Generic, gShow )
import Data.Maybe ( fromMaybe )
import DOM ( DOM )
import Prelude ( class Show, ($), (<<<), (<>), bind, map, show )
import Pux ( fromSimple, renderToDOM, start )
import Pux.Html ( Html, div, text )
import Pux.Router ( end, lit, router, sampleUrl )
import Signal ( Signal )
import Signal.DOM ( DimensionPair, windowDimensions )
import Signal.Time ( Time, every )
-- ##############
-- ### Router ###
-- ##############
data Route = Home | Login | NotFound
derive instance genericRoute :: Generic Route
instance showRoute :: Show Route where
show = gShow
match :: String -> Route
match url = fromMaybe NotFound $ router url $
Home <$ end
<|>
Login <$ (lit "login") <* end
-- ###############
-- ### Signals ###
-- ###############
routeSignal' :: forall eff. Eff (dom :: DOM | eff) (Signal Action)
routeSignal' = ( map <<< map ) ( RouteAction <<< match ) sampleUrl
windowDimensionsSignal' :: forall eff. Eff (dom :: DOM | eff) (Signal Action)
windowDimensionsSignal' = ( map <<< map ) ResizeAction windowDimensions
timeSignal :: Signal Action
timeSignal = map TimeAction (every 2000.0)
-- #############
-- ### State ###
-- #############
type State =
{ width :: Int
, height :: Int
, route :: Route
, time :: Time
}
init :: { width :: Int, height :: Int } -> String -> Time -> State
init { width, height } initialPath time =
{ width : width
, height : height
, route : match initialPath
, time : time
}
-- ##############
-- ### Update ###
-- ##############
data Action
= ResizeAction DimensionPair
| RouteAction Route
| TimeAction Time
update :: Action -> State -> State
update action state =
case action of
ResizeAction dimensions ->
state { width = dimensions.w, height = dimensions.h }
RouteAction newRoute ->
state { route = newRoute }
TimeAction newTime ->
state { time = newTime }
-- ############
-- ### View ###
-- ############
view :: State -> Html Action
view state =
div []
[ div [] [ text ("Width: " <> show state.width) ]
, div [] [ text ("Height: " <> show state.height) ]
, div [] [ text ("Route: " <> show state.route) ]
, div [] [ text ("Time: " <> show state.time) ]
]
-- ############
-- ### Main ###
-- ############
main = do
routeSignal <- routeSignal'
windowDimensionsSignal <- windowDimensionsSignal'
app <- start
{ initialState : init { width : 0, height : 0 } "" 0.0
, update : fromSimple update
, view : view
, inputs : [ routeSignal, windowDimensionsSignal, timeSignal ]
}
renderToDOM "#app" app.html
If you run this example and visit "/login", you will notice that neither the window dimensions nor the route have been picked up.
Why is this? Looking at
Line 49 in d1e1dd5
inputs
array is reversed and the signals are merged with Signal.mergeMany
which calls Signal.merge
under the hood.
When two signals are merged, the initial value of the first signals wins. For the example above, this means that from the inputs
array [ routeSignal, windowDimensionsSignal, timeSignal ]
only the TimeAction
is processed.
I don't know why Elm
and subsequently purescript-signal
settled on this behaviour but I think we should document some workarounds for this issue here and maybe in the documentation.
React is loaded from a global variable. It would be nice if it would load using require if the global variable isn't available.
Does Pux need them? What would the API look like? Most importantly, what problem(s) do components solve?
A component is commonly understood as an encapsulation of model-view-update. Essentially, a Pux application can be seen as a single component.
The reason I opened this issue is that multiple people have asked me about components in Pux. Unfortunately, there's no clear definition of what people mean by components, and it's not clear what problems they're actually looking to solve with such an abstraction.
As I experiment with timers and animations, I find that I can't replicate a basic elm animation example.
https://github.com/stratospark/pux-elm-architecture/blob/master/ex8/src/SpinSquare.purs#L64
Essentially, I'm trying to use a timer to keep on dispatching Tick actions until an animation has completed. However, I'm only seeing renders at the end of each animation cycle, not a smooth animation based on the current angle in the State. If I check the Pux Devtool, I do see that the intermediate states were recorded, but none of them triggered a render.
Any ideas? Thanks!
@AppShipIt and @paf31 have asked why Pux isn't built ontop of purescript-react. The reason is that no functions from purescript-react are exposed in the Pux API. For example, Attribute a
is used instead of Props
, or Html a
instead of ReactElement
. When I wrote Pux, it was faster and less code to have Html a
be a foreign data type corresponding directly to React.createElement
.
One concern is that if Html a
translates to purescript-react's ReactElement
, that adds an extra layer of function calls in the render method. The only place where performance is a real concern is the render method, because it blocks the application. Function calls have very little overhead but it's still a concern. Renders should be as lightweight as possible.
Thoughts?
What is the equivalent to JavaScript's event.preventDefault() in Pux? My use case is a controlled textarea component which syncs with the model.
Hello โ,
I'd like to organize my application in a fractal manner.
To do so, I need to be able to declare routes locally with their corresponding component. I was able to do it in JS using react + react-router's route object.
Here is an example splitting the current page into components :
So we have this hierarchy of components for the current page https://github.com/alexmingoia/purescript-pux/issues/new
:
Application โ Repository โ Issues โ NewIssue
The idea here is to organize these components according to their relation Parent โ Child
:
โโโ Application
โย ย โโโ Repository
โย ย โย ย โโโ Issues
โย ย โย ย โย ย โโโ IssueList.purs
โย ย โย ย โย ย โโโ NewIssue.purs
โย ย โย ย โโโ Issues.purs
โย ย โโโ Repository.purs
โโโ Application.purs
We can identify "routable" components which display different children based on the current URI. If we imagine that each "routable" component consume a part of the URI as we go deep in the hierarchy we can say that :
Application
displays its child Repository
when the URI is :username/:projectname
Repository
displays its child Issues
when the URI is issues
Issues
displays its child NewIssue
when the URI is new
and its child IssueList
when the URI is /
or `` (this case can be considered as its index route)In that way, a "routable" component just needs to care about its own part of the URI, and know nothing outside of its direct children.
For the routes definition, we could add a Route
data type to each "routable" component definition in addition to the usual State, Action, init, update, view
.
-- Application.purs
data Route = Repository
-- Repository.purs
data Route = Issues
-- Issues.purs
data Route = IssueList | NewIssue
This is where I stopped, now I'm looking for a way to declare local match
functions, consume and pass the current URI to children so I can repeat the pattern down the hierarchy. ๐
See https://gitter.im/alexmingoia/purescript-pux?at=57682468feaf6cd222ad643b for more information
snabbdom was suggested to purescript-halogen. Thought I post it here too, in case you guys were not aware of it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.