Skip to content

Instantly share code, notes, and snippets.

@kyasu1
Created January 23, 2020 01:56
Show Gist options
  • Select an option

  • Save kyasu1/d1e7192b5ae59726277ba6a1fb688898 to your computer and use it in GitHub Desktop.

Select an option

Save kyasu1/d1e7192b5ae59726277ba6a1fb688898 to your computer and use it in GitHub Desktop.
Elm navigation with Browser.Element and History API
port module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Json.Decode as D
import Url
-- MAIN
main : Program String Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{ url : Maybe Url.Url
}
init : String -> ( Model, Cmd Msg )
init locationHref =
( Model (locationHrefToRoute locationHref), Cmd.none )
-- UPDATE
type Msg
= LinkClicked String
| UrlChanged (Maybe Url.Url)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
LinkClicked url ->
( model, pushUrl url )
UrlChanged url ->
( { model | url = url }
, Cmd.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions _ =
onUrlChange (locationHrefToRoute >> UrlChanged)
-- VIEW
view : Model -> Html Msg
view model =
div []
[ text "The current URL is: "
, b [] [ text (Maybe.map Url.toString model.url |> Maybe.withDefault "NOT FOUND") ]
, ul []
[ viewLink "/home"
, viewLink "/profile"
, viewLink "/reviews/the-century-of-the-self"
, viewLink "/reviews/public-opinion"
, viewLink "/reviews/shah-of-shahs"
]
]
viewLink : String -> Html Msg
viewLink path =
li [] [ link (LinkClicked path) [ href path ] [ text path ] ]
port onUrlChange : (String -> msg) -> Sub msg
port pushUrl : String -> Cmd msg
link : msg -> List (Attribute msg) -> List (Html msg) -> Html msg
link href attrs children =
a (preventDefaultOn "click" (D.succeed ( href, True )) :: attrs) children
locationHrefToRoute : String -> Maybe Url.Url
locationHrefToRoute locationHref =
Url.fromString locationHref
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment