How to do progressive enhancement with PureScript?

Do you use PS for progressive enhancement (small widgets like tabs and expanding or collapsing details , form submitting, reloading small pieces of page etc.)?
How do you approach this problem - using some framework or directly DOM API?

What is your definition of “progressive enhancement”? Sounds like it’s just any additional behavior added to static HTML using JavaScript.

If so, if that HTML page is rendered using React, then that JS is included in the React components you’re using. If it’s a simple HTML string, then you’ll need to include JS which attaches its event listeners to the appropriate elements when the document is loaded.

@chexxor I have static pages generated on the server side and I want to add to it additional behavior. Can I use react (through thermite, pux or any other lib) to build separate widgets on the same page?

You are right - I should be more precise. I’m going to rephrase the question and add more info about my requirements. I just wanted to ask about general experience in that area first…

EDIT: I think that I will go with spork for my small widgets which is I think easier to comprehend than the whole react ecosystem.

To give some ideas, here’s how I would approach it:

-- public/index.html
<html>
...
<script src="./Index.js">
...
<!-- Identify the elements which you want to embellish with JS/PS. -->
<div data-ps-widget="ABC"/>

Will probably need to bundle “public/index.js”.

// public/index.js

// Now import and activate all the widgets that appear on "index.html"
var ABC = require("../ps-output/Widget.ABC/index.js");

document.on("load", function() {
  document.querySelectorAll('[data-ps-widget]')
    .forEach(function(el) {
        if (el.getAttribute('data-foo') == "ABC") {
          ABC.render(el);
        }
        if (el.getAttribute('data-foo') == "DEF") {
          // Activate multiple widgets on one page if you'd like.
          // DEF.render(el);
        }
    });
});
-- module Widget.ABC where

-- This is a common interface for a component.
// render :: HTMLElement -> Effect Unit
render el = do
  -- Activate the component.
  -- For example, a spork app.
  -- Copied from https://github.com/natefaubion/purescript-spork/blob/master/examples/todo-mvc/src/Main.purs
  storedModel ← ...
  inst ←
    App.make
      (liftNat runEffect `merge` never)
      (app storedModel)
      el
  inst.run

  void $ hashes \oldHash newHash →
    F.for_ (routeAction newHash) \i → do
      inst.push i
      inst.run
  where
    app ∷ Maybe StoredModel → App.App Effect (Const Void) Model Action
    app storedModel = ...

If Widget.ABC renders a data-ps-widget="DEF" element, this won’t activate it. :frowning: This is intended to inspire you with one way to do this. To do that, I think you’ll need to have Widget.ABC execute some code which is like that “public/index.js” file whenever it wants to render a child Spork app, which seems complicated in my mind. Another way would be to use a UI library which supports child components, like Halogen, as I would guess that would be more simple.

Thanks for suggestion! I’m going to use yours (or really similar) approach to initiate my widgets.

Hey Paluh! We do a bit of this for the documentation for halogen-select:

Similar to what Alex suggested, we traverse the HTML looking for a particular selector (data-component) and mount Halogen components at each one.

Hi Thomas!
Thanks for real world example and report!
I have some simple prototype of image gallery structured like you suggested above but built with spork. I’m adding some input data (in json) to into extra data-* attribute, so I don’t have to parse any HTML.