first commit
This commit is contained in:
commit
52bf643dea
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
elm-stuff/
|
||||
elm.js
|
||||
elm.min.js
|
||||
node_modules/
|
||||
package-lock.json
|
||||
package.json
|
10
Makefile
Normal file
10
Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
SRC_FILES := $(shell find src -name "*.elm")
|
||||
|
||||
all: elm.min.js
|
||||
|
||||
serve: all
|
||||
python3 -m http.server
|
||||
|
||||
elm.min.js: $(SRC_FILES)
|
||||
rm -f elm.min.js elm.js
|
||||
./optimize.sh src/Main.elm
|
27
README.md
Normal file
27
README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# About
|
||||
Example demonstrating how one might architect a single page application
|
||||
Elm app.
|
||||
|
||||
# Dependencies MacOS
|
||||
```bash
|
||||
brew install node elm
|
||||
npm install -g uglify-js@2.4.11
|
||||
```
|
||||
|
||||
# Building
|
||||
```
|
||||
make serve
|
||||
```
|
||||
|
||||
Now open `http://localhost:8000` in your browser.
|
||||
|
||||
# Viewing
|
||||
|
||||
Open index.html in your browser.
|
||||
|
||||
# TODO
|
||||
|
||||
- [x] Add Makefile
|
||||
- [ ] Refactor into router page
|
||||
- [ ] Handle back-navigation
|
||||
- [ ] Add `default.nix`
|
25
elm.json
Normal file
25
elm.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"type": "application",
|
||||
"source-directories": [
|
||||
"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.8"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/json": "1.1.3",
|
||||
"elm/time": "1.0.0",
|
||||
"elm/virtual-dom": "1.0.3"
|
||||
}
|
||||
},
|
||||
"test-dependencies": {
|
||||
"direct": {},
|
||||
"indirect": {}
|
||||
}
|
||||
}
|
16
index.html
Normal file
16
index.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Elm UI Website</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="elm"></div>
|
||||
<script src="elm.min.js"></script>
|
||||
<script>
|
||||
var app = Elm.Main.init({
|
||||
node: document.getElementById('elm')
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
14
optimize.sh
Executable file
14
optimize.sh
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
js="elm.js"
|
||||
min="elm.min.js"
|
||||
|
||||
elm make --optimize --output=$js "$@"
|
||||
|
||||
uglifyjs $js --compress 'pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle --output $min
|
||||
|
||||
echo "Compiled size:$(wc $js -c) bytes ($js)"
|
||||
echo "Minified size:$(wc $min -c) bytes ($min)"
|
||||
echo "Gzipped size: $(gzip $min -c | wc -c) bytes"
|
44
src/Header.elm
Normal file
44
src/Header.elm
Normal file
|
@ -0,0 +1,44 @@
|
|||
module Header exposing (Model, Msg(..), view, init)
|
||||
import Element exposing (Element)
|
||||
import Element.Events
|
||||
import Element.Border
|
||||
|
||||
type alias Model = {}
|
||||
type Msg
|
||||
= ClickedProducts
|
||||
| ClickedResources
|
||||
| ClickedAbout
|
||||
| ClickedContact
|
||||
|
||||
init : () -> Model
|
||||
init flags = {}
|
||||
|
||||
view : Model -> Element Msg
|
||||
view model =
|
||||
let
|
||||
dropShadow = Element.Border.shadow {
|
||||
offset = ( 0, 2 ),
|
||||
size = 1,
|
||||
blur = 5,
|
||||
color = Element.rgba 0 0 0 0.15
|
||||
}
|
||||
headerButton msg string =
|
||||
Element.el
|
||||
[Element.alignRight, Element.Events.onClick <| msg]
|
||||
(Element.text string)
|
||||
|
||||
products = headerButton ClickedProducts "Products"
|
||||
resources = headerButton ClickedResources "Resources"
|
||||
about = headerButton ClickedAbout "About"
|
||||
contact = headerButton ClickedContact "Contact"
|
||||
in
|
||||
Element.row [Element.width Element.fill,
|
||||
Element.spacing 15,
|
||||
Element.paddingXY 30 25,
|
||||
dropShadow]
|
||||
[ Element.el [Element.alignLeft] (Element.text "Elm Example App")
|
||||
, products
|
||||
, resources
|
||||
, about
|
||||
, contact
|
||||
]
|
122
src/Main.elm
Normal file
122
src/Main.elm
Normal file
|
@ -0,0 +1,122 @@
|
|||
module Main exposing (main)
|
||||
|
||||
import Browser
|
||||
import Url
|
||||
import Html exposing (Html)
|
||||
import Element exposing (Element, el, text, column)
|
||||
import String exposing (right)
|
||||
import Browser.Navigation
|
||||
|
||||
import Page.Landing
|
||||
import Header
|
||||
import Html exposing (header)
|
||||
|
||||
|
||||
-- MODEL
|
||||
type Page
|
||||
= Landing Page.Landing.Model
|
||||
| Products
|
||||
| Resources
|
||||
| About
|
||||
| Contact
|
||||
|
||||
type alias Model =
|
||||
{ key : Browser.Navigation.Key
|
||||
, url : Url.Url
|
||||
, page : Page
|
||||
, header : Header.Model}
|
||||
|
||||
init : () -> Url.Url -> Browser.Navigation.Key -> ( Model, Cmd Msg )
|
||||
init flags url key =
|
||||
let
|
||||
page = Landing (Page.Landing.init flags)
|
||||
header = Header.init flags
|
||||
model =
|
||||
{ key = key
|
||||
, url = url
|
||||
, page = page
|
||||
, header = header
|
||||
}
|
||||
in
|
||||
(model, Cmd.none)
|
||||
|
||||
toPage : Header.Msg -> Page
|
||||
toPage msg =
|
||||
case msg of
|
||||
Header.ClickedProducts -> Products
|
||||
Header.ClickedResources -> Resources
|
||||
Header.ClickedAbout -> About
|
||||
Header.ClickedContact -> Contact
|
||||
|
||||
-- TODO : move this function to Router.elm
|
||||
toUrl : Url.Url -> Header.Msg -> Url.Url
|
||||
toUrl baseUrl msg =
|
||||
case msg of
|
||||
Header.ClickedProducts -> {baseUrl | path = "/products"}
|
||||
Header.ClickedResources -> {baseUrl | path = "/resources"}
|
||||
Header.ClickedAbout -> {baseUrl | path = "/about"}
|
||||
Header.ClickedContact -> {baseUrl | path = "/contact"}
|
||||
|
||||
-- UPDATE
|
||||
type Msg
|
||||
= NoOp
|
||||
| Header Header.Msg
|
||||
| LandingPage Page.Landing.Msg
|
||||
| UrlChanged Url.Url
|
||||
| LinkedClicked Browser.UrlRequest
|
||||
|
||||
|
||||
update : Msg -> Model -> (Model, Cmd Msg)
|
||||
update msg model =
|
||||
case msg of
|
||||
Header headerMsg ->
|
||||
let
|
||||
newUrl = toUrl model.url headerMsg
|
||||
newModel = { model | page = toPage headerMsg }
|
||||
in
|
||||
(newModel, Browser.Navigation.pushUrl model.key (Url.toString newUrl))
|
||||
_ -> (model, Cmd.none)
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
viewBody : Model -> Element.Element Msg
|
||||
viewBody model =
|
||||
let
|
||||
content = case model.page of
|
||||
Landing m -> Page.Landing.view m |> Element.map LandingPage
|
||||
Products -> Element.text "Products"
|
||||
Resources -> Element.text "Resources"
|
||||
About -> Element.text "About"
|
||||
Contact -> Element.text "Contact"
|
||||
in
|
||||
Element.el [Element.centerY ,Element.centerX] content
|
||||
|
||||
-- VIEW
|
||||
|
||||
view : Model -> Browser.Document Msg
|
||||
view model =
|
||||
let
|
||||
page =
|
||||
Element.column
|
||||
[ Element.width Element.fill
|
||||
, Element.height Element.fill
|
||||
, Element.centerX]
|
||||
[ Header.view model.header |> Element.map Header
|
||||
, viewBody model]
|
||||
in
|
||||
{ title = "Example Spa Elm App"
|
||||
, body = [ Element.layout [] page ]}
|
||||
|
||||
-- MAIN
|
||||
|
||||
main =
|
||||
Browser.application {
|
||||
init = init
|
||||
,view = view
|
||||
,update = update
|
||||
,subscriptions = subscriptions
|
||||
,onUrlChange = UrlChanged
|
||||
,onUrlRequest = LinkedClicked
|
||||
}
|
13
src/Page/Landing.elm
Normal file
13
src/Page/Landing.elm
Normal file
|
@ -0,0 +1,13 @@
|
|||
module Page.Landing exposing (Model, Msg, view, init)
|
||||
import Element exposing (Element)
|
||||
|
||||
type alias Model = {}
|
||||
type alias Msg = {}
|
||||
|
||||
init : () -> Model
|
||||
init flags = {}
|
||||
|
||||
view : Model -> Element Msg
|
||||
view model =
|
||||
Element.el []
|
||||
<| Element.text "Landing"
|
Loading…
Reference in a new issue