diff --git a/README.md b/README.md index 10022f6..b55ca8d 100644 --- a/README.md +++ b/README.md @@ -2,38 +2,131 @@ [![Build Status](https://travis-ci.org/ryannhg/elm-spa.svg?branch=master)](https://travis-ci.org/ryannhg/elm-spa) -single page apps made easy +## single page apps made easy -### try it out +When you create an app with the [elm/browser](https://package.elm-lang.org/packages/elm/browser/latest) package, you can build anything from a static `Html msg` page to a fully-fledged web `Browser.application`. -``` -npx elm-spa init new-project +__elm-spa__ uses that design at the page-level, so you can quickly add new pages to your Elm application! + +Make your page as simple as you need: + +```elm +module Pages.Home exposing (page) + +-- can render a static page +page = + Spa.static + { view = view + } ``` -### or just install the elm package +```elm +module Pages.About exposing (page) + +-- can keep track of page state +page = + Spa.sandbox + { init = init + , update = update + , view = view + } +``` + +```elm +module Pages.Posts exposing (page) + +-- can perform side effects +page = + Spa.element + { init = init + , update = update + , subscriptions = subscriptions + , view = view + } +``` + +```elm +module Pages.SignIn exposing (page) + +-- can read and update global state +page = + Spa.component + { init = init + , update = update + , subscriptions = subscriptions + , view = view + } +``` + +### putting your pages together is super easy! + +```elm +init : Route -> Global.Model -> ( Model, Cmd Msg, Cmd Global.Msg ) +init route = + case route of + Route.Home -> pages.home.init () + Route.About -> pages.about.init () + Route.Posts slug -> pages.posts.init slug + Route.SignIn -> pages.signIn.init () +``` + +```elm +update : Msg -> Model -> Global.Model -> ( Model, Cmd Msg, Cmd Global.Msg ) +update bigMsg bigModel = + case ( bigMsg, bigModel ) of + ( Home_Msg msg, Home_Model model ) -> + pages.home.update msg model + + ( About_Msg msg, About_Model model ) -> + pages.about.update msg model + + ( Posts_Msg msg, Posts_Model model ) -> + pages.posts.update msg model + + ( SignIn_Msg msg, SignIn_Model model ) -> + pages.signIn.update msg model + + _ -> + always ( bigModel, Cmd.none, Cmd.none ) +``` + +```elm +-- handle view and subscriptions in one case expression! +bundle : Model -> Global.Model -> { view : Document Msg, subscriptions : Sub Msg } +bundle bigModel = + case route of + Home_Model model -> pages.home.bundle model + About_Model model -> pages.about.bundle model + Posts_Model model -> pages.posts.bundle model + SignIn_Model model -> pages.signIn.bundle model +``` + +### install the npm package + +The [cli tool](https://www.npmjs.com/package/elm-spa) has commands like `elm-spa init`, `elm-spa add`, and `elm-spa build` for +generating your routes and pages for you! + +``` +npm install -g elm-spa +elm-spa init new-project +``` + +### install the elm package + +If you'd rather define routes and pages by hand, +you can add [the elm package](https://package.elm-lang.org/packages/ryannhg/elm-spa/latest/Spa) to your project: ``` elm install ryannhg/elm-spa ``` -### or run the example +### rather see an example? + +This repo comes with an example project that you can +play around with. add in some pages and see how it works! ``` -cd example && npm start +git clone https://github.com/ryannhg/elm-spa +cd example +npm start ``` - -### overview - -When you create an app with the [elm/browser](https://package.elm-lang.org/packages/elm/browser/latest) package, you can build anything from a static `Html msg` page to a fully-fledged web `Browser.application`. - -`elm-spa` uses that design at the page-level, so you can quickly add new pages to your Elm application! - -## the four kinds of pages: - -1. __static__ – a page that only renders HTML. -2. __sandbox__ – a page with state. -3. __element__ – a page with side-effects. -4. __component__ – a page with global state. - -Check out [the package docs](https://package.elm-lang.org/packages/ryannhg/elm-spa/latest/Spa) to learn more! -