upsiflu / less-ui

Write your views across several screen regions, and hide all Ui state in the Url.
https://package.elm-lang.org/packages/upsiflu/less-ui/latest
BSD 3-Clause "New" or "Revised" License
6 stars 1 forks source link

Only valid routes in links #12

Open upsiflu opened 1 year ago

upsiflu commented 1 year ago

A problem I foresee is that the author needs to organise a dict of names if they want to make sure all goTo and bounce links lead to valid destinations.

This could be alleviated if the model (the accordion, tree, list...) would itself output a list of path-fragment tuples, each of which would correspont to a parallel viewState of this model:

   Index: model -> List (Path, Fragment)
   Codec: (Path, Fragment) <-> model

In other words, the same Codec can construct a model out of a (Path, Fragment) tuple, or the latter out of the former.

In turn, an Index generates all possible Links. And a Codec implies a Codec <Link <-> model>.

A very heavy-handed approach would be to say, when drawing the internals of the Model, whenever we require a link, we use a the Codec to output a Link towards the destination, which we'd need to calculate in advance.

This means we are calculating all Models we link to.

Perhaps that's fine; they'll all stay in the CPU cache. Also, if we swap to Accordion = History, then all we do is push a GoTo to the History; we don't even build a treezipper.

Does this approach work for pages?

Pages can be represented by strings. Then the Codec is trivially identity.

All of this means, we still need to carry around a Codec, just not an author-designed one but a Ui standard index. We can enforce the use of the index by mandating that GoTo and Bounce need a Codec model (Path, Fragment) or so and cannot be constructed without providing a model and a Codec. The author cannot use the Codec themselves.

Is this feasible? It probably is.

Example: An Accordion consisting of Segments

   Segment.view : model -> (Codec Link model) -> config -> segment -> Ui

which can be shortened to

   Segment.view : ((model -> model) -> Link) -> config -> segment -> Ui
   Segment.view generateLink config segment Ui

In this case, since Segment cannot import Accordion, it must receive goUp through the config:

   Segment.view generateLink ({goUp : Accordion -> Accordion} as config) segment Ui

Alternatively (or additionally), it could create its own little Codec in order to spawn links that affect its own display state.

In Accordion.view, we can create the Codec, let it swallow the current state, and hand the resulting generator over to Segment.view