Since a restricted application has no access to the Url, we need to provide a lever, for example extending the Link type to construct these patterns.
Discussion
Perhaps this will make the whole library too complex. All these things can be implemented inside the app if we can do without altering the Url. Storing this state in the Url only has three advantages:
The Ui state is hidden from the app
It can be replicated in other tabs and computers
It can be edited directly by the user in the Url bar
Antipatterns
When does the Url state lose its utility?
When the Url becomes too long (7 parameters?)
When parameters become too unwieldy or a string serialization is just not straightforward (Drag&Drop; Base64; Json; Forms)
When the Url changes too frequently (Hover states, Toasts, frequent new data)
Patterns
Global tabs should be in the Url.
Any type of Search or Filter should be in the Url, and should affect corresponding data-fetchers: not merely filtering views, but actually setting bounds for the data that is kept in memory, i.e. the model.
Hotkeys: A limited version is accesskeys which requires ⌘⌥ to be pressed at the same time. But global hotkeys for toggling would be amazing. For example, ESC should always remove the last flag. (Research needed!)
Viewport manipulation:
(a) Fragment + offset=x,y, as viewport definition
(b) Independent fragment and viewport
Research needed: What is the relation between focus, fragment and viewport? Which practical applications are there?
Implementation approaches
(a) The layout module (in our case, Html) maps any user-provided Html msg to an Html (Msg msg)
(b) The Ui consists of a mix of html and htmlWithMsg.
singleton can only provide html
layout needs to perform the mapping to Msg on each view.
Which one is better?
Api difference: In (a), singleton is in the Html module, next to the Wrapper and link functions and the Ui type alias. You'd only import Ui if you want at. In (b), singleton is in Ui besides at. So you'd have to import both modules. Another difference is that in (a), you could theoretically add Msg to your Html yourself.
Code niceness: In (a), we have ugly types in the Html module but nice types in Ui. In (b), we get additional type parameters for the already quite overloaded layout.
Problem with b: As we wrap the Uis, we are renderingUi htmltohtmlWithMsg`. Then, we need to wrap that. Let's see.
Nest
{ regions : List region
, narrowLayout : Layout region narrowHtml narrowHtml narrowWrapper narrowWrapper
, combine : { makeInnerHtml : Ui region narrowHtml narrowWrapper -> Maybe narrowHtml } -> html
}
becomes
Nest
{ regions : List region
, narrowLayout : Layout region narrowHtml narrowHtml narrowWrapper narrowWrapper
, combine : { makeInnerHtml : Ui region narrowHtml narrowWrapper -> Maybe narrowHtmlWithMsg } -> htmlWithMsg
}
so we have multiplied the html types from 2 to 4 👎 which means Ui.Wrapper needs 2 additional type parameters which means Ui.Layout also needs those, and now has 7 instead of 5. This was why we didn't implement (a).
35
8
33
34
[x] Implementated (a): 1c8fb7c
Motivation
Some state transition patterns cannot be implemented with only the
href
attribute (which circumvents the message loop):href
- Hotkey
when in same tab;
From initial state to "active" when in new tab
Link.Toggle
,Link.Bounce
href
- Hotkey
Link.GoTo
href
Link.Share
- Hotkey
category=
valuesLink.Assign
q=category=
search termsLink.Filter
Link.Assign
Link.Assign
Link.Assign
Since a
restricted
application has no access to the Url, we need to provide a lever, for example extending theLink
type to construct these patterns.Discussion
Perhaps this will make the whole library too complex. All these things can be implemented inside the app if we can do without altering the Url. Storing this state in the Url only has three advantages:
Antipatterns When does the Url state lose its utility?
Patterns
accesskeys
which requires ⌘⌥ to be pressed at the same time. But global hotkeys for toggling would be amazing. For example, ESC should always remove the last flag. (Research needed!)offset=x,y,
as viewport definitionImplementation approaches
(a) The layout module (in our case, Html) maps any user-provided
Html msg
to anHtml (Msg msg)
(b) The Ui consists of a mix ofhtml
andhtmlWithMsg
.singleton
can only providehtml
layout
needs to perform the mapping toMsg
on eachview
.Which one is better?
Api difference: In (a),
singleton
is in theHtml
module, next to theWrapper
and link functions and theUi
type alias. You'd only importUi
if you wantat
. In (b),singleton
is inUi
besidesat
. So you'd have to import both modules. Another difference is that in (a), you could theoretically addMsg
to your Html yourself.Code niceness: In (a), we have ugly types in the
Html
module but nice types inUi
. In (b), we get additional type parameters for the already quite overloadedlayout
.Problem with b: As we wrap the Ui
s, we are rendering
Ui htmlto
htmlWithMsg`. Then, we need to wrap that. Let's see.becomes
so we have multiplied the html types from 2 to 4 👎 which means
Ui.Wrapper
needs 2 additional type parameters which meansUi.Layout
also needs those, and now has 7 instead of 5. This was why we didn't implement (a).