diff --git a/example/src/Utils/Spa.elm b/example/src/Utils/Spa.elm index ae966ea..a418e29 100644 --- a/example/src/Utils/Spa.elm +++ b/example/src/Utils/Spa.elm @@ -14,12 +14,12 @@ import Element exposing (Element) import Global -type alias Page flags model msg layoutModel layoutMsg appMsg = - App.Types.Page flags model msg (Element msg) layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg) +type alias Page params model msg layoutModel layoutMsg appMsg = + App.Types.Page params model msg (Element msg) layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg) -type alias Recipe flags model msg layoutModel layoutMsg appMsg = - App.Types.Recipe flags model msg layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg) +type alias Recipe params model msg layoutModel layoutMsg appMsg = + App.Types.Recipe params model msg layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg) type alias Init model msg = diff --git a/src/App.elm b/src/App.elm index 2f4af5d..8d4d587 100644 --- a/src/App.elm +++ b/src/App.elm @@ -11,18 +11,22 @@ module App exposing `App.create` replaces [Browser.application](https://package.elm-lang.org/packages/elm/browser/latest/Browser#application) as the entrypoint to your app. - import App - import Generated.Pages as Pages - import Generated.Route as Route - import Global + module Main exposing (main) + import App + import Element + import Global + import Pages + import Routes + + main : App.Program Global.Flags Global.Model Global.Msg Pages.Model Pages.Msg main = App.create { ui = App.usingHtml , routing = - { routes = Route.routes - , toPath = Route.toPath - , notFound = Route.NotFound () + { routes = Routes.parsers + , toPath = Routes.toPath + , notFound = Routes.routes.notFound } , global = { init = Global.init @@ -35,23 +39,23 @@ as the entrypoint to your app. @docs Program, create -# Supports more than elm/html +# using elm-ui? -If you're a fan of [mdgriffith/elm-ui](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/), -it's important to support using `Element msg` instead of `Html msg` for your pages and components. +If you're a big fan of [mdgriffith/elm-ui](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/) (or not-so-big-fan of CSS), +this package supports using `Element msg` instead of `Html msg` for your pages and components. -Let `App.create` know about this by passing in your own `Options` like these: +Providing `App.create` with these `ui` options will do the trick! import Element - -- other imports - App.create - { ui = - { toHtml = Element.layout [] - , map = Element.map + main = + App.create + { ui = + { toHtml = Element.layout [] + , map = Element.map + } + , -- ... } - , -- ... the rest of your app - } @docs usingHtml @@ -78,7 +82,11 @@ type alias Program flags globalModel globalMsg layoutModel layoutMsg = {-| Pass this in when calling `App.create` -( It will work if your view returns the standard `Html msg` ) + main = + App.create + { ui = App.usingHtml + , -- ... + } -} usingHtml : @@ -86,7 +94,7 @@ usingHtml : (layoutMsg -> Msg globalMsg layoutMsg) -> Html layoutMsg -> Html (Msg globalMsg layoutMsg) - , toHtml : uiMsg -> uiMsg + , toHtml : ui_msg -> ui_msg } usingHtml = { toHtml = identity @@ -104,8 +112,8 @@ usingHtml = -} create : { ui : - { toHtml : uiMsg -> Html (Msg globalMsg layoutMsg) - , map : (layoutMsg -> Msg globalMsg layoutMsg) -> uiLayoutMsg -> uiMsg + { toHtml : ui_msg -> Html (Msg globalMsg layoutMsg) + , map : (layoutMsg -> Msg globalMsg layoutMsg) -> ui_layoutMsg -> ui_msg } , routing : { routes : List (Parser (route -> route) route) @@ -126,7 +134,7 @@ create : -> ( globalModel, Cmd globalMsg, Cmd (Msg globalMsg layoutMsg) ) , subscriptions : globalModel -> Sub globalMsg } - , page : Page.Page route layoutModel layoutMsg uiLayoutMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg (Msg globalMsg layoutMsg) uiMsg + , page : Page.Page route layoutModel layoutMsg ui_layoutMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg (Msg globalMsg layoutMsg) ui_msg } -> Program flags globalModel globalMsg layoutModel layoutMsg create config = @@ -358,10 +366,10 @@ navigate toPath url route = subscriptions : - { map : (layoutMsg -> Msg globalMsg layoutMsg) -> uiLayoutMsg -> uiMsg + { map : (layoutMsg -> Msg globalMsg layoutMsg) -> ui_layoutMsg -> ui_msg , bundle : layoutModel - -> Page.Bundle layoutMsg uiLayoutMsg globalModel globalMsg (Msg globalMsg layoutMsg) uiMsg + -> Page.Bundle layoutMsg ui_layoutMsg globalModel globalMsg (Msg globalMsg layoutMsg) ui_msg , global : globalModel -> Sub globalMsg } -> Model flags globalModel layoutModel @@ -385,11 +393,11 @@ subscriptions config model = view : - { map : (layoutMsg -> Msg globalMsg layoutMsg) -> uiLayoutMsg -> uiMsg - , toHtml : uiMsg -> Html (Msg globalMsg layoutMsg) + { map : (layoutMsg -> Msg globalMsg layoutMsg) -> ui_layoutMsg -> ui_msg + , toHtml : ui_msg -> Html (Msg globalMsg layoutMsg) , bundle : layoutModel - -> Page.Bundle layoutMsg uiLayoutMsg globalModel globalMsg (Msg globalMsg layoutMsg) uiMsg + -> Page.Bundle layoutMsg ui_layoutMsg globalModel globalMsg (Msg globalMsg layoutMsg) ui_msg } -> Model flags globalModel layoutModel -> Browser.Document (Msg globalMsg layoutMsg) diff --git a/src/App/Page.elm b/src/App/Page.elm index 9688ad7..f842344 100644 --- a/src/App/Page.elm +++ b/src/App/Page.elm @@ -10,76 +10,47 @@ module App.Page exposing {-| Each page can be as simple or complex as you need: -1. [Static](#static) - for rendering a simple view +1. [Static](#static) - a page without state -2. [Sandbox](#sandbox) - for maintaining state, without any side-effects +2. [Sandbox](#sandbox) - a page without side-effects -3. [Element](#element) - for maintaining state, **with** side-effects +3. [Element](#element) - a page _with_ side-effects -4. [Component](#component) - for a full-blown page, that can view and update global state +4. [Component](#component) - a page that can change the global state -## Static +## what's that `always` for? -For rendering a simple view. +You may notice the examples below use `always`. This is to **opt-out** each +function from reading the global model. - page = - Page.static - { title = title - , view = view - } +If you need access to `Global.Model` in your `title`, `init`, `update`, `view`, or +`subscriptions` functions, just remove the always. + +**It is recommended to include this to keep your pages as simple as possible!** + + +# static @docs static -## Sandbox - -For maintaining state, without any side-effects. - - page = - Page.sandbox - { title = title - , init = init - , update = update - , view = view - } +# sandbox @docs sandbox -## Element - -For maintaining state, **with** side-effects. - - page = - Page.element - { title = title - , init = init - , update = update - , view = view - , subscriptions = subscriptions - } +# element @docs element -## Component - -For a full-blown page, that can view and update global state. - - page = - Page.component - { title = title - , init = init - , update = update - , view = view - , subscriptions = subscriptions - } +# component @docs component, send -# Composing pages together +# composing pages together The rest of this module contains types and functions that can be generated with the [cli companion tool](https://github.com/ryannhg/elm-spa/tree/master/cli) @@ -88,7 +59,7 @@ If you're typing this stuff manually, you might need to know what these are for! -## Layout +## layout A page that is comprimised of smaller pages, that is able to share a common layout (maybe a something like a sidebar!) @@ -107,7 +78,7 @@ able to share a common layout (maybe a something like a sidebar!) @docs layout -## Recipe +## recipe Implementing the `init`, `update` and `bundle` functions is much easier when you turn a `Page` type into `Recipe`. @@ -120,16 +91,18 @@ A `Recipe` contains a record waiting for page specific data. - `bundle` (`view`/`subscriptions`) : just needs a `model` +@docs recipe -### What's a "bundle"? + +## what's a "bundle"? We can "bundle" the `view` and `subscriptions` functions together, -because they both only depend on the current `model`. That's why this -API exposes `bundle` instead of making you type this: +because they both only need the current `model`. - -- BEFORE - view model = - case model_ of +So _instead_ of typing out these: + + view bigModel = + case bigModel of FooModel model -> foo.view model @@ -139,8 +112,8 @@ API exposes `bundle` instead of making you type this: BazModel model -> baz.view model - subscriptions model = - case model_ of + subscriptions bigModel = + case bigModel of FooModel model -> foo.subscriptions model @@ -150,9 +123,10 @@ API exposes `bundle` instead of making you type this: BazModel model -> baz.subscriptions model - -- AFTER - bundle model = - case model_ of +You only need **one** case expression: (woohoo, less boilerplate!) + + bundle bigModel = + case bigModel of FooModel model -> foo.bundle model @@ -162,12 +136,8 @@ API exposes `bundle` instead of making you type this: BazModel model -> baz.bundle model -(Woohoo, less case expressions to type out!) -@docs recipe - - -## Update helper +## update helpers @docs keep @@ -177,47 +147,62 @@ import Internals.Page exposing (..) import Internals.Utils as Utils -type alias Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg = - Internals.Page.Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg +type alias Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg = + Internals.Page.Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg {-| Turns a page and some upgrade information into a recipe, for use in a layout's `init`, `update`, and `bundle` functions! - Page.recipe Homepage.page - { toModel = HomepageModel - , toMsg = HomepageMsg - , map = Element.map -- ( if using elm-ui ) + import Utils.Spa as Spa + + recipes : Recipes msg + recipes = + { top = + Spa.recipe + { page = Top.page + , toModel = TopModel + , toMsg = TopMsg + } + , counter = + Spa.recipe + { page = Counter.page + , toModel = CounterModel + , toMsg = CounterMsg + } + + -- ... } -} recipe : - { page : Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + { page : Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg , toModel : pageModel -> layoutModel , toMsg : pageMsg -> layoutMsg - , map : (pageMsg -> layoutMsg) -> uiPageMsg -> uiLayoutMsg + , map : (pageMsg -> layoutMsg) -> ui_pageMsg -> ui_layoutMsg } - -> Recipe pageRoute pageModel pageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + -> Recipe pageParams pageModel pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg recipe = Internals.Page.upgrade {-| In the event that our `case` expression in `update` receives a `msg` that doesn't -match it's `model`, we use this function to keep the model as-is. +match up with it's `model`, we use `keep` to leave the page as-is. - update msg_ model_ = - case ( msg_, model_ ) of - ( FooMsg msg, FooModel model ) -> - foo.update msg model + update : Msg -> Model -> Spa.Update Model Msg + update bigMsg bigModel = + case ( bigMsg, bigModel ) of + ( TopMsg msg, TopModel model ) -> + top.update msg model - ( BarMsg msg, BarModel model ) -> - bar.update msg model + ( CounterMsg msg, CounterModel model ) -> + counter.update msg model - ( BazMsg msg, BazModel model ) -> - baz.update msg model + ( NotFoundMsg msg, NotFoundModel model ) -> + notFound.update msg model _ -> - Page.keep model_ + Page.keep bigModel -} keep : @@ -227,17 +212,31 @@ keep model = always ( model, Cmd.none, Cmd.none ) - --- STATIC +{-| -{-| Create an `static` page from a record. [Here's an example](https://github.com/ryannhg/elm-spa/examples/html/src/Pages/Index.elm) +## an example + + page = + Page.static + { title = always title + , view = always view + } + + title : String + title = + "Example" + + view : Html Never + view = + h1 [ class "title" ] [ text "Example" ] + -} static : { title : { global : globalModel } -> String - , view : globalModel -> uiPageMsg + , view : globalModel -> ui_pageMsg } - -> Page pageRoute () Never uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + -> Page pageParams () Never ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg static page = Page (\{ toModel, toMsg, map } -> @@ -257,21 +256,65 @@ static page = -- SANDBOX -{-| Create an `sandbox` page from a record. [Here's an example](https://github.com/ryannhg/elm-spa/examples/html/src/Pages/Counter.elm) +{-| + + +## an example + + page = + Page.sandbox + { title = always title + , init = always init + , update = always update + , view = always view + } + + title : String + title = + "Counter" + + type alias Model = + Int + + init : Model + init = + 0 + + type Msg + = Increment + | Decrement + + update : Msg -> Model -> Model + update msg model = + case msg of + Increment -> + model + 1 + + Decrement -> + model - 1 + + view : Model -> Html Msg + view model = + div [] + [ button [ Events.onClick Increment ] [ text "+" ] + , text (String.fromInt model) + , button [ Events.onClick Decrement ] [ text "-" ] + ] + -} sandbox : { title : { global : globalModel, model : pageModel } -> String - , init : globalModel -> pageRoute -> pageModel + , init : globalModel -> pageParams -> pageModel , update : globalModel -> pageMsg -> pageModel -> pageModel - , view : globalModel -> pageModel -> uiPageMsg + , view : globalModel -> pageModel -> ui_pageMsg } - -> Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + -> Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg sandbox page = Page (\{ toModel, toMsg, map } -> { init = - \pageRoute context -> - ( toModel (page.init context.global pageRoute) + \pageParams context -> + ( toModel (page.init context.global pageParams) , Cmd.none , Cmd.none ) @@ -295,22 +338,55 @@ sandbox page = -- ELEMENT -{-| Create an `element` page from a record. [Here's an example](https://github.com/ryannhg/elm-spa/examples/html/src/Pages/Random.elm) +{-| + + +## an example + + page = + Page.element + { title = always title + , init = always init + , update = always update + , subscriptions = always subscriptions + , view = always view + } + + title : String + title = + "Cat Gifs" + + init : ( Model, Cmd.none ) + init = + -- ... + + update : Msg -> Model -> ( Model, Cmd Msg ) + update msg model = + -- ... + + subscriptions : Model -> Sub Msg + subscriptions model = + -- ... + + view : Model -> Html Msg + view model = + -- ... + -} element : { title : { global : globalModel, model : pageModel } -> String - , init : globalModel -> pageRoute -> ( pageModel, Cmd pageMsg ) + , init : globalModel -> pageParams -> ( pageModel, Cmd pageMsg ) , update : globalModel -> pageMsg -> pageModel -> ( pageModel, Cmd pageMsg ) - , view : globalModel -> pageModel -> uiPageMsg + , view : globalModel -> pageModel -> ui_pageMsg , subscriptions : globalModel -> pageModel -> Sub pageMsg } - -> Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + -> Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg element page = Page (\{ toModel, toMsg, map } -> { init = - \pageRoute context -> - page.init context.global pageRoute + \pageParams context -> + page.init context.global pageParams |> tuple toModel toMsg , update = \msg model context -> @@ -330,22 +406,58 @@ element page = -- COMPONENT -{-| Create an `component` page from a record. [Here's an example](https://github.com/ryannhg/elm-spa/examples/html/src/Pages/SignIn.elm) +{-| + + +## an example + + page = + Page.component + { title = always title + , init = always init + , update = always update + , subscriptions = always subscriptions + -- no always, so `view` gets `Global.Model` + , view = view + } + + title : String + title = + "Sign in" + + init : Params.SignIn -> ( Model, Cmd Msg, Cmd Global.Msg ) + init params = + -- ... + + update : Msg -> Model -> ( Model, Cmd Msg, Cmd Global.Msg ) + update msg model = + -- ... + + subscriptions : Model -> Sub Msg + subscriptions model = + -- ... + + view : Global.Model -> Model -> Html Msg + view global model = + case global.user of + SignedIn _ -> viewSignOutForm + SignedOut -> viewSignInForm + -} component : { title : { global : globalModel, model : pageModel } -> String - , init : globalModel -> pageRoute -> ( pageModel, Cmd pageMsg, Cmd globalMsg ) + , init : globalModel -> pageParams -> ( pageModel, Cmd pageMsg, Cmd globalMsg ) , update : globalModel -> pageMsg -> pageModel -> ( pageModel, Cmd pageMsg, Cmd globalMsg ) - , view : globalModel -> pageModel -> uiPageMsg + , view : globalModel -> pageModel -> ui_pageMsg , subscriptions : globalModel -> pageModel -> Sub pageMsg } - -> Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + -> Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg component page = Page (\{ toModel, toMsg, map } -> { init = - \pageRoute context -> - page.init context.global pageRoute + \pageParams context -> + page.init context.global pageParams |> truple toModel toMsg , update = \msg model context -> @@ -363,14 +475,12 @@ component page = {-| Useful for sending `Global.Msg` from a component. - update : Global.Model -> Msg -> Model -> ( Model, Cmd Msg, Cmd Global.Msg ) - update global msg model = - case msg of - SignIn -> - ( model - , Cmd.none - , Page.send Global.SignIn - ) + init : Params.SignIn -> ( Model, Cmd Msg, Cmd Global.Msg ) + init params = + ( model + , Cmd.none + , Page.send (Global.NavigateTo routes.dashboard) + ) -} send : msg -> Cmd msg @@ -382,39 +492,38 @@ send = -- LAYOUT -{-| These are used by top-level files like `src/Generated/Pages.elm` -to compose together pages and layouts. +{-| In practice, we wrap `layout` in `Utils/Spa.elm` so we only have to provide `Html.map` or `Element.map` once) -We'll get a better understanding of `init`, `update`, and `bundle` below! + import Utils.Spa as Spa - Page.layout - { map = Html.map - , layout = Layout.view - , pages = - { init = init - , update = update - , bundle = bundle + page = + Spa.layout + { layout = Layout.view + , pages = + { init = init + , update = update + , bundle = bundle + } } - } -} layout : - { map : (pageMsg -> msg) -> uiPageMsg -> uiMsg + { map : (pageMsg -> msg) -> ui_pageMsg -> ui_msg , view : - { page : uiMsg + { page : ui_msg , global : globalModel , toMsg : globalMsg -> msg } - -> uiMsg - , recipe : Recipe pageRoute pageModel pageMsg pageModel pageMsg uiPageMsg globalModel globalMsg msg uiMsg + -> ui_msg + , recipe : Recipe pageParams pageModel pageMsg pageModel pageMsg ui_pageMsg globalModel globalMsg msg ui_msg } - -> Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + -> Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg layout options = Page (\{ toModel, toMsg } -> { init = - \pageRoute global -> - options.recipe.init pageRoute global + \pageParams global -> + options.recipe.init pageParams global |> truple toModel toMsg , update = \msg model global -> @@ -423,7 +532,7 @@ layout options = , bundle = \model context -> let - bundle : { title : String, view : uiMsg, subscriptions : Sub msg } + bundle : { title : String, view : ui_msg, subscriptions : Sub msg } bundle = options.recipe.bundle model diff --git a/src/App/Types.elm b/src/App/Types.elm index 05cada3..fcc541e 100644 --- a/src/App/Types.elm +++ b/src/App/Types.elm @@ -1,118 +1,227 @@ module App.Types exposing - ( Page, Recipe - , Init, Update, Bundle + ( Page + , Recipe + , Init + , Update + , Bundle ) {-| -## Types so spooky, they got their own module! 👻 +## types so spooky, they got their own module! 👻 This module is all about exposing the types that `ryannhg/elm-app` uses under the hood. -Because so much of your app is defined outside of this package, we see -a **lot of generic types**. +At a glance, there are a **lot of generic types**. + +In practice, we can handle this with a single +[`Utils/Spa.elm`](https://github.com/ryannhg/elm-spa/blob/master/example/src/Utils/Spa.elm) file that +makes your types easier to understand! + +`elm-spa init` generates that file for you, but I've added examples below if you're +doing things by hand. -### Don't be spooked! +# page -In practice, we usually handle this with a `Utils/Page.elm` file that -creates less generic `type alias` for use in your app! +@docs Page - module Utils.Spa exposing - ( Bundle - , Init - , Page - , Recipe - , Update - , layout - , recipe - ) - import App.Page - import App.Types - import Element exposing (Element) - import Global +# recipe - type alias Page flags model msg layoutModel layoutMsg appMsg = - App.Types.Page flags model msg (Element msg) layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg) +@docs Recipe - type alias Recipe flags model msg layoutModel layoutMsg appMsg = - App.Types.Recipe flags model msg layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg) - type alias Init model msg = - App.Types.Init model msg Global.Model Global.Msg +# init - type alias Update model msg = - App.Types.Update model msg Global.Model Global.Msg +@docs Init - type alias Bundle msg appMsg = - App.Types.Bundle msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg) - layout config = - App.Page.layout - { map = Element.map - , view = config.view - , recipe = config.recipe - } +# update - recipe config = - App.Page.recipe - { map = Element.map - , page = config.page - , toModel = config.toModel - , toMsg = config.toMsg - } +@docs Update -@docs Page, Recipe -@docs Init, Update, Bundle +# bundle + +@docs Bundle -} import Internals.Page as Page -{-| This type alias should be used in all `src/Pages` files. +{-| - module Pages.Example exposing - ( page - , -- ... - ) + +## creating your alias + +**`src/Utils/Spa.elm`** + + -- if using mdgriffith/elm-ui + + import App.Types + import Element exposing (Element) + + type alias Page params model msg layoutModel layoutMsg appMsg = + App.Types.Page params model msg (Element msg) layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg) + + -- if using elm/html + + import App.Types + import Html exposing (Html) + + type alias Page params model msg layoutModel layoutMsg appMsg = + App.Types.Page params model msg (Html msg) layoutModel layoutMsg (Html layoutMsg) Global.Model Global.Msg appMsg (Html appMsg) + + +## using your alias + +**`src/Pages/Example.elm`** import Utils.Spa as Spa page : Spa.Page Params.Example Model Msg model msg appMsg page = - App.Page.static - - -- ... + App.Page.static { ... } -} -type alias Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg = - Page.Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg +type alias Page params pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg = + Page.Page params pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg -{-| Recipe +{-| + + +## creating your alias + +**`src/Utils/Spa.elm`** + + -- if using mdgriffith/elm-ui + + import App.Types + import Element exposing (Element) + + type alias Recipe params model msg layoutModel layoutMsg appMsg = + App.Types.Recipe params model msg layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg) + + -- if using elm/html + + import App.Types + import Html exposing (Html) + + type alias Recipe params model msg layoutModel layoutMsg appMsg = + App.Types.Recipe params model msg layoutModel layoutMsg (Html layoutMsg) Global.Model Global.Msg appMsg (Html appMsg) + + +## using your alias + +**`.elm-spa/Generated/Pages.elm`** + + import Utils.Spa as Spa + + type alias Recipes appMsg = + { top : Spa.Recipe Params.Top Top.Model Top.Msg Model Msg appMsg + , example : Spa.Recipe Params.Example Example.Model Example.Msg Model Msg appMsg + , notFound : Spa.Recipe Params.NotFound NotFound.Model NotFound.Msg Model Msg appMsg + } + -} -type alias Recipe pageRoute pageModel pageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg = - Page.Recipe pageRoute pageModel pageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg +type alias Recipe params pageModel pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg = + Page.Recipe params pageModel pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg -{-| Init +{-| + + +## creating your alias + +**`src/Utils/Spa.elm`** + + type alias Init model msg = + App.Types.Init model msg Global.Model Global.Msg + + +## using your alias + +**`.elm-spa/Generated/Pages.elm`** + + import Utils.Spa as Spa + + init : Route -> Spa.Init Model Msg + init route_ = + case route_ of + -- ... + -} type alias Init layoutModel layoutMsg globalModel globalMsg = Page.Init layoutModel layoutMsg globalModel globalMsg -{-| Update +{-| + + +## creating your alias + +**`src/Utils/Spa.elm`** + + type alias Update model msg = + App.Types.Update model msg Global.Model Global.Msg + + +## using your alias + +**`.elm-spa/Generated/Pages.elm`** + + import Utils.Spa as Spa + + update : Msg -> Model -> Spa.Update Model Msg + update msg_ model_ = + case ( msg_, model_ ) of + -- ... + -} type alias Update layoutModel layoutMsg globalModel globalMsg = Page.Update layoutModel layoutMsg globalModel globalMsg -{-| Bundle +{-| + + +## creating your alias + +**`src/Utils/Spa.elm`** + + -- if using mdgriffith/elm-ui + + import App.Types + import Element exposing (Element) + + type alias Bundle msg appMsg = + App.Types.Bundle msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg) + + -- if using elm/html + + import App.Types + import Html exposing (Html) + + type alias Bundle msg appMsg = + App.Types.Bundle msg (Html msg) Global.Model Global.Msg appMsg (Html appMsg) + + +## using your alias + +**`.elm-spa/Generated/Pages.elm`** + + import Utils.Spa as Spa + + bundle : Model -> Spa.Bundle Msg msg + bundle model_ = + case model_ of + -- ... + -} -type alias Bundle layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg = - Page.Bundle layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg +type alias Bundle layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg = + Page.Bundle layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg diff --git a/src/Internals/Page.elm b/src/Internals/Page.elm index bb48696..1aa19f1 100644 --- a/src/Internals/Page.elm +++ b/src/Internals/Page.elm @@ -11,34 +11,34 @@ module Internals.Page exposing -} -type Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg - = Page (Page_ pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg) +type Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg + = Page (Page_ pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg) -type alias Page_ pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg = +type alias Page_ pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg = { toModel : pageModel -> layoutModel , toMsg : pageMsg -> layoutMsg - , map : (pageMsg -> layoutMsg) -> uiPageMsg -> uiLayoutMsg + , map : (pageMsg -> layoutMsg) -> ui_pageMsg -> ui_layoutMsg } - -> Recipe pageRoute pageModel pageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + -> Recipe pageParams pageModel pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg {-| Recipe docs -} -type alias Recipe pageRoute pageModel pageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg = - { init : pageRoute -> Init layoutModel layoutMsg globalModel globalMsg +type alias Recipe pageParams pageModel pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg = + { init : pageParams -> Init layoutModel layoutMsg globalModel globalMsg , update : pageMsg -> pageModel -> Update layoutModel layoutMsg globalModel globalMsg - , bundle : pageModel -> Bundle layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + , bundle : pageModel -> Bundle layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg } upgrade : - { page : Page pageRoute pageModel pageMsg uiPageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + { page : Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg , toModel : pageModel -> layoutModel , toMsg : pageMsg -> layoutMsg - , map : (pageMsg -> layoutMsg) -> uiPageMsg -> uiLayoutMsg + , map : (pageMsg -> layoutMsg) -> ui_pageMsg -> ui_layoutMsg } - -> Recipe pageRoute pageModel pageMsg layoutModel layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg + -> Recipe pageParams pageModel pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg upgrade config = let (Page page) = @@ -67,14 +67,14 @@ type alias Update layoutModel layoutMsg globalModel globalMsg = {-| Bundle docs -} -type alias Bundle layoutMsg uiLayoutMsg globalModel globalMsg msg uiMsg = +type alias Bundle layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg = { global : globalModel , fromGlobalMsg : globalMsg -> msg , fromPageMsg : layoutMsg -> msg - , map : (layoutMsg -> msg) -> uiLayoutMsg -> uiMsg + , map : (layoutMsg -> msg) -> ui_layoutMsg -> ui_msg } -> { title : String - , view : uiMsg + , view : ui_msg , subscriptions : Sub msg }