create more examples

This commit is contained in:
Ryan Haskell-Glatz 2020-03-29 20:50:31 -05:00
parent 3f036dbe2a
commit 2cc0bbfaea
35 changed files with 2468 additions and 1 deletions

7
examples/README.md Normal file
View File

@ -0,0 +1,7 @@
# examples
a few example projects using elm-spa.
1. [examples/html](./html)
1. [examples/elm-ui](./elm-ui)
1. [examples/transitions](./transitions)

6
examples/elm-ui/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.DS_Store
dist
elm-stuff
node_modules
src/Generated

18
examples/elm-ui/README.md Normal file
View File

@ -0,0 +1,18 @@
# examples/elm-ui
```
npm start
```
## how i upgraded to elm-ui
```
npm install -g elm-spa
elm-spa init my-project
cd my-project
elm install mdgriffith/elm-ui
```
Checkout the `src/Page.elm` and `src/Document.elm` files, they allow us to create pages with `Element msg` and `Html msg`
From there, I just replaced `Html` with `Element` in the `src/Pages/*.elm` files.

27
examples/elm-ui/elm.json Normal file
View File

@ -0,0 +1,27 @@
{
"type": "application",
"source-directories": [
"src",
"../../src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm/url": "1.0.0",
"mdgriffith/elm-ui": "1.1.5",
"ryannhg/elm-spa": "4.0.0"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

1846
examples/elm-ui/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
{
"name": "elm-spa-app",
"version": "1.0.0",
"description": "my new elm-spa application",
"main": "public/index.html",
"scripts": {
"start": "npm install && npm run build && npm run dev",
"build": "npm run build:elm-spa && npm run build:elm",
"build:elm-spa": "elm-spa build .",
"build:elm": "elm make src/Main.elm --optimize --output public/dist/elm.js",
"dev": "concurrently --raw --kill-others \"npm run dev:elm-spa\" \"npm run dev:elm\"",
"dev:elm-spa": "chokidar src/Pages -c \"npm run build:elm-spa\"",
"dev:elm": "elm-live src/Main.elm -u -d public -- --debug --output public/dist/elm.js"
},
"keywords": [
"elm",
"spa"
],
"author": "",
"license": "ISC",
"devDependencies": {
"chokidar-cli": "2.1.0",
"concurrently": "5.0.0",
"elm": "0.19.1-3",
"elm-live": "4.0.2",
"elm-spa": "4.0.5"
}
}

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>elm-spa</title>
</head>
<body>
<script src="/dist/elm.js"></script>
<script>
Elm.Main.init()
</script>
</body>
</html>

View File

@ -0,0 +1,86 @@
module Components exposing (layout)
import Document exposing (Document)
import Element exposing (..)
import Element.Background as Background
import Element.Border as Border
import Element.Font as Font
import Generated.Route as Route exposing (Route)
layout : { page : Document msg } -> Document msg
layout { page } =
{ title = page.title
, body =
[ column [ spacing 32, padding 20, width (fill |> maximum 780), height fill, centerX ]
[ navbar
, column [ height fill ] page.body
, footer
]
]
}
navbar : Element msg
navbar =
row [ width fill ]
[ el [ Font.size 24, Font.bold ] <| link ( "home", Route.Top )
, row [ alignRight, spacing 20 ]
[ link ( "docs", Route.Docs )
, link ( "a broken link", Route.NotFound )
, externalButtonLink ( "tweet about it", "https://twitter.com/intent/tweet?text=elm-spa is ez pz" )
]
]
link : ( String, Route ) -> Element msg
link ( label, route ) =
Element.link styles.link
{ label = text label
, url = Route.toHref route
}
externalButtonLink : ( String, String ) -> Element msg
externalButtonLink ( label, url ) =
Element.newTabLink styles.button
{ label = text label
, url = url
}
footer : Element msg
footer =
row [] [ text "built with elm " ]
-- STYLES
colors : { blue : Color, white : Color, red : Color }
colors =
{ white = rgb 1 1 1
, red = rgb255 204 85 68
, blue = rgb255 50 100 150
}
styles :
{ link : List (Element.Attribute msg)
, button : List (Element.Attribute msg)
}
styles =
{ link =
[ Font.underline
, Font.color colors.blue
, mouseOver [ alpha 0.6 ]
]
, button =
[ Font.color colors.white
, Background.color colors.red
, Border.rounded 4
, paddingXY 24 10
, mouseOver [ alpha 0.6 ]
]
}

View File

@ -0,0 +1,32 @@
module Document exposing
( Document
, map
, toBrowserDocument
)
import Browser
import Element exposing (..)
import Element.Font as Font
type alias Document msg =
{ title : String
, body : List (Element msg)
}
map : (msg1 -> msg2) -> Document msg1 -> Document msg2
map fn doc =
{ title = doc.title
, body = List.map (Element.map fn) doc.body
}
toBrowserDocument : Document msg -> Browser.Document msg
toBrowserDocument doc =
{ title = doc.title
, body =
[ Element.layout [ Font.size 16 ] <|
column [ width fill, height fill ] doc.body
]
}

View File

@ -0,0 +1,98 @@
module Global exposing
( Flags
, Model
, Msg
, init
, navigate
, subscriptions
, update
, view
)
import Browser.Navigation as Nav
import Components
import Document exposing (Document)
import Generated.Route as Route exposing (Route)
import Task
import Url exposing (Url)
-- INIT
type alias Flags =
()
type alias Model =
{ flags : Flags
, url : Url
, key : Nav.Key
}
init : Flags -> Url -> Nav.Key -> ( Model, Cmd Msg )
init flags url key =
( Model
flags
url
key
, Cmd.none
)
-- UPDATE
type Msg
= Navigate Route
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Navigate route ->
( model
, Nav.pushUrl model.key (Route.toHref route)
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view :
{ page : Document msg
, global : Model
, toMsg : Msg -> msg
}
-> Document msg
view { page, global, toMsg } =
Components.layout
{ page = page
}
-- COMMANDS
send : msg -> Cmd msg
send =
Task.succeed >> Task.perform identity
navigate : Route -> Cmd Msg
navigate route =
send (Navigate route)

View File

@ -0,0 +1,133 @@
module Main exposing (main)
import Browser
import Browser.Navigation as Nav exposing (Key)
import Document exposing (Document)
import Element
import Generated.Pages as Pages
import Generated.Route as Route exposing (Route)
import Global
import Url exposing (Url)
main : Program Flags Model Msg
main =
Browser.application
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
, onUrlRequest = LinkClicked
, onUrlChange = UrlChanged
}
-- INIT
type alias Flags =
()
type alias Model =
{ key : Key
, url : Url
, global : Global.Model
, page : Pages.Model
}
init : Flags -> Url -> Key -> ( Model, Cmd Msg )
init flags url key =
let
( global, globalCmd ) =
Global.init flags url key
( page, pageCmd, pageGlobalCmd ) =
Pages.init (fromUrl url) global
in
( Model key url global page
, Cmd.batch
[ Cmd.map Global globalCmd
, Cmd.map Global pageGlobalCmd
, Cmd.map Page pageCmd
]
)
type Msg
= LinkClicked Browser.UrlRequest
| UrlChanged Url
| Global Global.Msg
| Page Pages.Msg
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
LinkClicked (Browser.Internal url) ->
( model, Nav.pushUrl model.key (Url.toString url) )
LinkClicked (Browser.External href) ->
( model, Nav.load href )
UrlChanged url ->
let
( page, pageCmd, globalCmd ) =
Pages.init (fromUrl url) model.global
in
( { model | url = url, page = page }
, Cmd.batch
[ Cmd.map Page pageCmd
, Cmd.map Global globalCmd
]
)
Global globalMsg ->
let
( global, globalCmd ) =
Global.update globalMsg model.global
in
( { model | global = global }
, Cmd.map Global globalCmd
)
Page pageMsg ->
let
( page, pageCmd, globalCmd ) =
Pages.update pageMsg model.page model.global
in
( { model | page = page }
, Cmd.batch
[ Cmd.map Page pageCmd
, Cmd.map Global globalCmd
]
)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ model.global
|> Global.subscriptions
|> Sub.map Global
, model.page
|> (\page -> Pages.subscriptions page model.global)
|> Sub.map Page
]
view : Model -> Browser.Document Msg
view model =
Document.toBrowserDocument <|
Global.view
{ page = Pages.view model.page model.global |> Document.map Page
, global = model.global
, toMsg = Global
}
fromUrl : Url -> Route
fromUrl =
Route.fromUrl >> Maybe.withDefault Route.NotFound

View File

@ -0,0 +1,82 @@
module Page exposing
( Page, Document, Bundle
, upgrade
, static, sandbox, element, component
)
{-|
@docs Page, Document, Bundle
@docs upgrade
@docs static, sandbox, element, component
-}
import Browser
import Document
import Global
import Spa.Advanced as Spa
type alias Document msg =
Document.Document msg
type alias Page flags model msg =
Spa.Page flags model msg Global.Model Global.Msg (Document msg)
type alias Bundle msg =
Spa.Bundle msg (Document msg)
upgrade :
(pageModel -> model)
-> (pageMsg -> msg)
-> Page pageFlags pageModel pageMsg
->
{ init : pageFlags -> Global.Model -> ( model, Cmd msg, Cmd Global.Msg )
, update : pageMsg -> pageModel -> Global.Model -> ( model, Cmd msg, Cmd Global.Msg )
, bundle : pageModel -> Global.Model -> Bundle msg
}
upgrade =
Spa.upgrade Document.map
static : { view : Document msg } -> Page flags () msg
static =
Spa.static
sandbox :
{ init : model
, update : msg -> model -> model
, view : model -> Document msg
}
-> Page flags model msg
sandbox =
Spa.sandbox
element :
{ init : flags -> ( model, Cmd msg )
, update : msg -> model -> ( model, Cmd msg )
, subscriptions : model -> Sub msg
, view : model -> Document msg
}
-> Page flags model msg
element =
Spa.element
component :
{ init : Global.Model -> flags -> ( model, Cmd msg, Cmd Global.Msg )
, update : Global.Model -> msg -> model -> ( model, Cmd msg, Cmd Global.Msg )
, subscriptions : Global.Model -> model -> Sub msg
, view : Global.Model -> model -> Document msg
}
-> Page flags model msg
component =
Spa.component

View File

@ -0,0 +1,30 @@
module Pages.Docs exposing (Flags, Model, Msg, page)
import Element
import Page exposing (Document, Page)
type alias Flags =
()
type alias Model =
()
type alias Msg =
Never
page : Page Flags Model Msg
page =
Page.static
{ view = view
}
view : Document Msg
view =
{ title = "Docs"
, body = [ Element.text "Docs" ]
}

View File

@ -0,0 +1,30 @@
module Pages.NotFound exposing (Flags, Model, Msg, page)
import Element
import Page exposing (Document, Page)
type alias Flags =
()
type alias Model =
()
type alias Msg =
Never
page : Page Flags Model Msg
page =
Page.static
{ view = view
}
view : Document Msg
view =
{ title = "NotFound"
, body = [ Element.text "NotFound" ]
}

View File

@ -0,0 +1,30 @@
module Pages.Top exposing (Flags, Model, Msg, page)
import Element
import Page exposing (Document, Page)
type alias Flags =
()
type alias Model =
()
type alias Msg =
Never
page : Page Flags Model Msg
page =
Page.static
{ view = view
}
view : Document Msg
view =
{ title = "Top"
, body = [ Element.text "Top" ]
}

View File

@ -2,7 +2,7 @@
"type": "application",
"source-directories": [
"src",
"../src"
"../../src"
],
"elm-version": "0.19.1",
"dependencies": {