Coder Social home page Coder Social logo

purescript-halogen / purescript-halogen Goto Github PK

View Code? Open in Web Editor NEW
1.5K 1.5K 217.0 4.01 MB

A declarative, type-safe UI library for PureScript.

Home Page: https://purescript-halogen.github.io/purescript-halogen/

License: Apache License 2.0

PureScript 98.57% Shell 0.34% Dhall 1.09%
purescript ui web

purescript-halogen's Introduction

Halogen

Latest release CI

Halogen is a type-safe library for building user interfaces in PureScript.

  • Declarative Write simple views for each state in your application, and Halogen will efficiently and intelligently update the right components and re-render your user interface.
  • Component Architecture Write encapsulated components which manage their own state, and compose them together to build complex user interfaces. Or, use a single component to implement an Elm-like architecture.
  • Entirely PureScript Halogen and its virtual DOM implementation are written in PureScript. Halogen's performance and bundle sizes are roughly equivalent to popular JavaScript UI libraries like React and Angular.

Read the documentation to learn how to use Halogen in your own projects.

Installation

Install Halogen with Spago:

spago install halogen

Or create a new Halogen app from a template.

Documentation

You can find the Halogen documentation on the documentation site or in the docs folder. Documentation is divided into several categories:

We also recommend these community resources for learning how to use Halogen in your applications:

There are several ways to get help if you get stuck using Halogen:

Examples

This repository contains several self-contained examples, ranging from a basic button to controlling external components.

You may also want to review the Real World Halogen example application, which demonstrates routing, state management, authentication, making requests, and other real world examples with commented explanations.

Contributing

The main purpose of this repository is to continue evolving Halogen, making it faster and easier to use. Halogen is developed in the open on GitHub and we're grateful for community-contributed bugfixes and improvements.

You can take part in improving Halogen by opening or participating in issues, opening pull requests to add new features, documentation, or tests, and by helping other Halogen users on Discord and Discourse.

License & Credits

Halogen is licensed under the Apache License 2.0. The Halogen logo was designed by Matthew Park.

purescript-halogen's People

Contributors

acple avatar beckyconning avatar berdario avatar brandonhamilton avatar cryogenian avatar deamme avatar eskimor avatar fisx avatar garyb avatar jacereda avatar jdegoes avatar jonsterling avatar kaneroot avatar kritzcreek avatar milesfrain avatar monoidmusician avatar natefaubion avatar paf31 avatar passy avatar puffnfresh avatar raptazure avatar rightfold avatar safareli avatar savuori avatar srghma avatar th-awake avatar themoritz avatar thomashoneyman avatar toastal avatar zudov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

purescript-halogen's Issues

Access to attributes

Since Attribute i hides key-value relations it's impossible to make function that will preprocess HTML i removing some props or modifying them.

Child to parent event signalling

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.

Composing Views that rely on effects is problematic

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.

Slamdown integration

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.

Boolean attributes

{foo: true} adds attribute foo without value in virtual-dom. {foo: false} removes it.
This behaviour is simple and very helpful with disabled fields.

ClassName and javascript:void

could you please add shortcuts for javascript:void(0); and add functions that get String and [String] to define classes, not ClassName.

Remove "Hashed"?

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?

virtual-dom not listed as dependency

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? :)

Use type classes for input summands

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 Eithers 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

Use purescript-aff

purescript-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.

Wrap Bootstrap

  • Forms:
    • input groups
    • buttons
    • triggering disabling/enabling, has-success, has-warning etc
  • navbars
  • list groups
  • breadcrumbs.

Add ContT helper function

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.

Polish halogen for public release

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:

  1. Increase type-safety. Newtypes, phantom types, type classes, etc., wherever applicable.
  2. Documentation. Per method, per module, etc., so newbies can get up to speed.
  3. Generalize & Parameterize. For example, can we extract out the HTML tags so they can be used to generate HTML strings, etc., similar to blaze (without the monadic sugar, maybe using finally tagless)? Can we use Aff in more places which do not require an immediate return value? Etc.
  4. Beef Up Example. A good example, I think, is Pursuit, which uses Ajax and the hash string. Could we do that using Halogen?

Composing two Views is somewhat problematic due to event handlers

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?

Support 'thunk' from virtual-dom

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.

Hooks

Could you please make event handlers hooks not attributes, and make those hooks composable some way?
The main consideration of doing it:

  • Everytime VTree rerender it adds nodes with handlers that are not hooks.
  • Adding such handler will remove any other handler one has added to this node.

External signal

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?

preventDefault

Sometimes it's necessary to prevent event or stop its propagation without returning any message.
Currently this is not supported by halogen.

Undo/redo mixin

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 os.

@jdegoes You mentioned this as a use case at one point, right? Would you be interested in adding this as a module?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.