purescript-halogen / purescript-halogen Goto Github PK
View Code? Open in Web Editor NEWA declarative, type-safe UI library for PureScript.
Home Page: https://purescript-halogen.github.io/purescript-halogen/
License: Apache License 2.0
A declarative, type-safe UI library for PureScript.
Home Page: https://purescript-halogen.github.io/purescript-halogen/
License: Apache License 2.0
Given two trivial views with different state types:
data Count = Inc | Dec
app1 :: PureView Count
app1 = render <$> stateful 0 update where
render count =
H.p_
[ H.text (show count)
, H.button (A.onclick (const $ pure Inc)) [ H.text "+" ]
, H.button (A.onclick (const $ pure Dec)) [ H.text "-" ]]
update count Inc = count + 1
update count Dec = count - 1
app2 :: PureView String
app2 = render <$> stateful "" (flip const) where
render val =
H.p_
[ H.input (A.type_ "text" <> A.value val <> A.onInput pure) []
, H.text val ]
I want to compose these together so they are shown one after another (so basically I want to <>
their HTML). These seems like something you could easily do with Profunctor and Apply (split the combined states, and then append the HTML) but the problem is that the SF/SF1 instances don't touch the event handlers, which would have to know about the new combined state. You can't rmap an additional map on to the HTML to modify the resulting handlers because you don't have access to the composite state to do an update. Also I think you'd have to continually pay for each map, which would likely be bad for app written from lots of smaller parts. What's the best way to go about something like this?
Still to be decided: keep SupportsErrors
or do something else?
There will be some users who will want to use things from the ContT _ Eff _
set of libraries. Since it's a thin veneer on top of Eff
, and we already import transformers
, it seems to make sense to add it.
Hey, I was wondering if there's a reason why virtual-dom
is not listed as explicit dependency. In order to build the examples, you currently have to run
npm install
npm install virtual-dom
gulp
Otherwise the build fails with a rather surprising
events.js:72
throw er; // Unhandled 'error' event
^
Error: module "virtual-dom/create-element" not found from "/Users/phartig/Projects/purescript/purescript-halogen/fake_3ed802b1.js"
at notFound (/Users/phartig/Projects/purescript/purescript-halogen/node_modules/gulp-browserify/node_modules/browserify/index.js:803:15)
at /Users/phartig/Projects/purescript/purescript-halogen/node_modules/gulp-browserify/node_modules/browserify/index.js:754:23
at /Users/phartig/Projects/purescript/purescript-halogen/node_modules/gulp-browserify/node_modules/browserify/node_modules/browser-resolve/index.js:185:24
at /Users/phartig/Projects/purescript/purescript-halogen/node_modules/gulp-browserify/node_modules/browserify/node_modules/resolve/lib/async.js:44:14
at process (/Users/phartig/Projects/purescript/purescript-halogen/node_modules/gulp-browserify/node_modules/browserify/node_modules/resolve/lib/async.js:113:43)
at /Users/phartig/Projects/purescript/purescript-halogen/node_modules/gulp-browserify/node_modules/browserify/node_modules/resolve/lib/async.js:122:21
at load (/Users/phartig/Projects/purescript/purescript-halogen/node_modules/gulp-browserify/node_modules/browserify/node_modules/resolve/lib/async.js:54:43)
at /Users/phartig/Projects/purescript/purescript-halogen/node_modules/gulp-browserify/node_modules/browserify/node_modules/resolve/lib/async.js:60:22
at /Users/phartig/Projects/purescript/purescript-halogen/node_modules/gulp-browserify/node_modules/browserify/node_modules/resolve/lib/async.js:16:47
at Object.oncomplete (fs.js:108:15)
As there a reason for this or is it an oversight? :)
could you please add shortcuts for javascript:void(0);
and add functions that get String
and [String]
to define classes, not ClassName
.
I realized that the SF
model gives us a neat way to talk about undo/redo:
data UndoRedo input = Undo | Redo | Other input
withUndo :: forall i o. SF i o -> SF (UndoRedo i) o
where the SF
on the right hides a stack of o
s.
@jdegoes You mentioned this as a use case at one point, right? Would you be interested in adding this as a module?
The following are missing from the example:
Suppose we have something that produce r
or i
in terms of runUIEff
over time.
How can this producer be integrated to runUIEff
? Could you please provide example of using global events which is not raised by user?
Sometimes it's necessary to prevent event or stop its propagation without returning any message.
Currently this is not supported by halogen.
@jdegoes I'm putting this issue here to track this, even though I checked in a Travis config already.
Since Attribute i
hides key-value relations it's impossible to make function that will preprocess HTML i
removing some props or modifying them.
has-success
, has-warning
etcpurescript-aff
provides a nice answer to the question of how to integrate things like AJAX calls into the UI. Right now, we use Eff
to represent impure signals. Maybe Aff
is a better option.
The docs mention Strong and Choice instance for both SF and SF1, but they only exist for SF.
{foo: true}
adds attribute foo
without value in virtual-dom. {foo: false}
removes it.
This behaviour is simple and very helpful with disabled
fields.
Things like undo/redo and error handling require the input to be a sum (Either Error
, UndoRedoInput
etc.)
Using type classes to represent these "input mixins" would be preferable to requiring specific types because otherwise, we have to use the profunctor
combinators to get the Either
s in the right order to pass to runUIAff
.
E.g.
class HasUndoRedo input where
undo :: input
redo :: input
toUndoRedo :: input -> Maybe UndoRedoInput
class HasError input where
error :: Error
toError :: input -> Maybe Error
The current example is functional but not very helpful for users trying to write practical applications.
Currently the effect/request handler is completely separate from the View machinery. While I can potentially work with the SF/SF1 instances to manipulate state and HTML, there's no story for composing views that need to make requests. Say I want to create a reusable typeahead component that makes AJAX requests. These requests exists purely within event handlers and there's no clear way to pass these requests to the request handler and have it map back to the correct nested state.
I'd ideally like to reimplement this using Placeholder
but I don't know if it's possible yet.
I don't like the current implementation at all, and if I can't figure out a better implementation, I think I'd prefer just removing it.
Any thoughts on this?
Halogen's quickly approaching the point where I think we should do a public release / announcement.
Here's some things I'd like to see before we do that:
Aff
in more places which do not require an immediate return value? Etc.I'm guessing this would be useful?
This could be implemented as a function forall a. Slamdown -> HTML a SlamdownEvent
which could be used to render reactive markdown documents.
Could you please make event handlers hooks not attributes, and make those hooks composable some way?
The main consideration of doing it:
VTree
rerender it adds nodes with handlers that are not hooks.@natefaubion reports:
widgetImpl
always creates a newWidget
class with uniqueinit
methods, which means that you’ll never get a call toupdate
E.g.
onValueChanged :: forall i. (String -> i) -> Attribute i
Running with a typeahead example, I'm wanting to wrap it up into its own component that I can reuse. It has a decent amount of state and event handlers (clicks, keypresses), but I'm wanting to be able to signal to the parent when the user makes a selection (so basically a custom onselect
event handler, which is not a DOM event). Communication is currently one way from parent to child, and there's no way for a child to notify a parent with the idioms mentioned in #44 (at least as far as I can tell).
The problem with the <$>
idiom is that it only, and always touches all DOM handlers. So if I do TAState <$> myTypeahead
, all results from event handlers will always be wrapped (and thus can't be reasonably intercepted by the parent).
It seems like you could do another level of wrapping in the handler and do something like listen TAEvent TAState <$> myTypeahead
where listen
say wraps with TAEvent
when given a Left
to signal the parent, or with TAState
when given a Right
if its not signalling the parent. And then the typeahead component would have to make sure to map a Right
over its inner components. The result given to TAEvent
would then naturally wrap a sum of possible events raised by the typeahead.
It would be nice to be able to use SF
to handle this somehow.
Ideally I would like to use an Eq s
instance to generate appropriate calls to thunk
.
@jdegoes Do you want to create this in a separate repo?
They're pretty big and users will probably only need one, if any.
and update the ace
example
For View
etc.
Once it's ready, of course. May depend on #24.
By using WriterT
. This will avoid the need for pure <<< pure
etc.
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.