upsiflu / less-ui / Less.Link


type Link
    = GoTo ParsedLocation
    | Toggle Flag
    | Bounce ({ there : ParsedLocation, here : ParsedLocation })
    | Filter ({ category : Category, searchTerm : SearchTerm })

Relative changes to the Url are only applied when a link opens in the same tab. Otherwise, absolute changes are applied by the Elm runtime.

Example:

The user clicks a menu (implemented as a Toggle) to open it, then clicks again to close it.

(a) They decide to share the menu, so they right-click on the toggle and choose 'copy link'. Their friend opens the link and the handle is activated. Otherwise, the friend's Ui is at the default state. A toggle's href always points to the open state.

(b) They copy the Url and paste it in another tab or browser or device. The app loads and restores exactly the same Ui state as in the original tab.

Create

fromUrl : Url -> Link

This happens when a Link is clicked. We want to apply the relative change here.

TODO: What if several links are encoded in the Url?

Deconstruct

toHref : Link -> String

Use with Html.Attributes.href. Will not include the current state. Toggle and Bounce will produce an extra flag enabling switchy changes.

apply : Link -> State -> ( { pushHistoryState : Basics.Bool }, State )

Think update in TEA.

getStateSearchTerms : Category -> Url -> List SearchTerm

Note that a Category may contain "=":

import Url

Url.fromString "http://test/?a=b=c"
    |> Maybe.map (getStateSearchTerms "a")
    --> Just ["b=c"]

Url.fromString "http://test/?a=b=c"
    |> Maybe.map (getStateSearchTerms "a=")
    --> Just []

Url.fromString "http://test/?a=b=c"
    |> Maybe.map (getStateSearchTerms "a=b")
    --> Just ["c"]

Attention: Categories "toggle" and "bounce" are interpreted as redirect directives in relative links (-> Link).

getSpaceSeparatedSearchTerms : Category -> Url -> List SearchTerm

Space-separate, then intersect, all assignments to category.

Map

mapLocation : (Location -> Location) -> State -> State

Re-route the Url before the Ui is rendered.

Use cases:

Mutations


type Mutation
    = StateEntered String
    | StateInside String
    | StateLeft String
    | StateOutside String
    | SwitchedOn
    | StillOn
    | SwitchedOff
    | StillOff

Marks the delta from the previous to the current state. A String can describe the Aria-"set" (such as "page") that the link refers to.

mutationFromTwoStates : { current : State, previous : Maybe State } -> Link -> Maybe String -> Mutation

Probe the delta between two states against a Link and, with an optional Aria set name such as "page", generate a Mutation.

Msg


type Msg modelMsg
    = UrlChanged Url
    | LinkClicked Browser.UrlRequest
    | AppMsg modelMsg
    | UrlCmd Link
    | NoOp

Handles your message type (modelMsg) as well as changes to the Ui state (Url).

State


type alias State =
Url


type alias Location =
String

(/)<Path>(#``<Fragment>)

parseLocation : Location -> ParsedLocation

parseLocation ""
    -> OnlyPath ""

parseLocation "/"
    -> OnlyPath ""

parseLocation "#"
    -> OnlyFragment ""

parseLocation "/#"
    -> PathAndFragment "" ""


type alias Flag =
String

Progressive disclosure: Turning off a Flag renders all corresponding bits of Ui invisible. Example: Ui.Html#toggle.

Parametric search: Assignments such as ?a=b may represent currently active Tabs or a search string. Example: Ui.Html#search.


type alias Category =
String

Distinguish parallel search inputs on a screen.

sanitize : Url -> State

Internal function to remove magical assignments ("toggle" and "bounce").