├── tests ├── .gitignore ├── Main.elm ├── Tests.elm └── elm-package.json ├── .gitignore ├── src ├── Initialize.elm ├── Subscriptions.elm ├── Utils.elm ├── Model.elm ├── Main.elm ├── Update.elm ├── AppStyles.elm └── View.elm ├── index.html ├── package.json ├── elm-package.json └── README.md /tests/.gitignore: -------------------------------------------------------------------------------- 1 | /elm-stuff/ 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | elm-stuff 2 | node_modules 3 | dist/* 4 | -------------------------------------------------------------------------------- /src/Initialize.elm: -------------------------------------------------------------------------------- 1 | module Initialize exposing (init) 2 | 3 | import Model exposing (..) 4 | 5 | 6 | init : ( Model, Cmd Msg ) 7 | init = 8 | { screenSize = Desktop } ! [] 9 | -------------------------------------------------------------------------------- /src/Subscriptions.elm: -------------------------------------------------------------------------------- 1 | module Subscriptions exposing (subscriptions) 2 | 3 | import Window exposing (resizes) 4 | import Model exposing (..) 5 | 6 | 7 | subscriptions : Model -> Sub Msg 8 | subscriptions model = 9 | Sub.batch [ Window.resizes SetScreenSize ] 10 | -------------------------------------------------------------------------------- /tests/Main.elm: -------------------------------------------------------------------------------- 1 | port module Main exposing (..) 2 | 3 | import Tests 4 | import Test.Runner.Node exposing (run) 5 | import Json.Encode exposing (Value) 6 | 7 | 8 | main : Test.Runner.Node.TestProgram 9 | main = 10 | run emit Tests.all 11 | 12 | 13 | port emit : ( String, Value ) -> Cmd msg 14 | -------------------------------------------------------------------------------- /src/Utils.elm: -------------------------------------------------------------------------------- 1 | module Utils exposing (..) 2 | 3 | import String 4 | 5 | 6 | capitalize : String -> String 7 | capitalize name = 8 | let 9 | first = 10 | String.left 1 name |> String.toUpper 11 | 12 | rest = 13 | String.dropLeft 1 name 14 | in 15 | first ++ rest 16 | -------------------------------------------------------------------------------- /src/Model.elm: -------------------------------------------------------------------------------- 1 | module Model exposing (..) 2 | 3 | import Window 4 | 5 | 6 | type ScreenSize 7 | = Phone 8 | | Tablet 9 | | Desktop 10 | | BigDesktop 11 | 12 | 13 | type alias Model = 14 | { screenSize : ScreenSize 15 | } 16 | 17 | 18 | type Msg 19 | = NoOp 20 | | SetScreenSize Window.Size 21 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtools-elm", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "watch": "elm-live src/*.elm --open --pushstate --output dist/bundle.js --debug", 8 | "test": "elm-test" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "elm": "^0.18.0", 14 | "elm-live": "^2.6.0", 15 | "elm-test": "^0.17.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Main.elm: -------------------------------------------------------------------------------- 1 | module Main exposing (..) 2 | 3 | import Html exposing (..) 4 | import Model exposing (..) 5 | import Update 6 | import View 7 | import Initialize 8 | import Subscriptions 9 | 10 | 11 | main : Program Never Model Msg 12 | main = 13 | Html.program 14 | { init = Initialize.init 15 | , view = View.view 16 | , update = Update.update 17 | , subscriptions = Subscriptions.subscriptions 18 | } 19 | -------------------------------------------------------------------------------- /tests/Tests.elm: -------------------------------------------------------------------------------- 1 | module Tests exposing (..) 2 | 3 | import Test exposing (..) 4 | import Expect 5 | import String 6 | import Utils 7 | 8 | 9 | all : Test 10 | all = 11 | describe "A Test Suite" 12 | [ test "Capitalizes a lower case word" <| 13 | \() -> 14 | Expect.equal (Utils.capitalize "john") "John" 15 | , test "Does not change an already capitalized word" <| 16 | \() -> 17 | Expect.equal (Utils.capitalize "John") "John" 18 | ] 19 | -------------------------------------------------------------------------------- /src/Update.elm: -------------------------------------------------------------------------------- 1 | module Update exposing (update) 2 | 3 | import Model exposing (..) 4 | 5 | 6 | update : Msg -> Model -> ( Model, Cmd Msg ) 7 | update msg model = 8 | case msg of 9 | NoOp -> 10 | model ! [] 11 | 12 | SetScreenSize size -> 13 | { model | screenSize = getScreenSize size } ! [] 14 | 15 | 16 | getScreenSize size = 17 | if size.width <= 600 then 18 | Phone 19 | else if size.width <= 1200 then 20 | Tablet 21 | else if size.width <= 1800 then 22 | Desktop 23 | else 24 | BigDesktop 25 | -------------------------------------------------------------------------------- /elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "src" 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-lang/core": "5.0.0 <= v < 6.0.0", 12 | "elm-lang/html": "2.0.0 <= v < 3.0.0", 13 | "elm-lang/window": "1.0.1 <= v < 2.0.0", 14 | "mdgriffith/style-elements": "4.2.1 <= v < 5.0.0" 15 | }, 16 | "elm-version": "0.18.0 <= v < 0.19.0" 17 | } 18 | -------------------------------------------------------------------------------- /tests/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "Sample Elm Test", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD-3-Clause", 6 | "source-directories": [ 7 | ".", 8 | "../src" 9 | ], 10 | "exposed-modules": [], 11 | "dependencies": { 12 | "elm-community/elm-test": "3.0.0 <= v < 4.0.0", 13 | "rtfeldman/node-test-runner": "3.0.0 <= v < 4.0.0", 14 | "elm-lang/core": "5.0.0 <= v < 6.0.0", 15 | "elm-lang/html": "2.0.0 <= v < 3.0.0" 16 | }, 17 | "elm-version": "0.18.0 <= v < 0.19.0" 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Elm Quickstart 2 | This is a repository that can be cloned or copied in order to start a new basic 3 | Elm application. It sets up the following: 4 | 5 | * Basic HTML application with model, update, view and subscriptions. 6 | * Small utility module used to demonstrate testing. 7 | * npm setup to run build or tests. 8 | 9 | To use this repository, you should follow these steps. 10 | 11 | 1. npm install -g elm 12 | 13 | 2. npm install -g elm-live 14 | 15 | 3. npm install -g elm-test 16 | 17 | 4. npm install 18 | 19 | 5. npm run test 20 | 21 | 6. npm run watch 22 | 23 | The *watch* step will run the elm-live build process and launch the browser. 24 | Future code changes will automatically trigger a rebuild and the browser will 25 | live reload with your changes. 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/AppStyles.elm: -------------------------------------------------------------------------------- 1 | module AppStyles exposing (..) 2 | 3 | import Style exposing (..) 4 | import Style.Font as Font 5 | import Style.Color as Color 6 | import Color exposing (..) 7 | 8 | 9 | type MyStyles 10 | = BlockStyle 11 | | BodyStyle 12 | | PageStyle 13 | | ContentStyle 14 | | HeaderStyle 15 | | FooterStyle 16 | | SidebarStyle 17 | 18 | 19 | sansSerif = 20 | Font.typeface [ Font.font "Helvetica" ] 21 | 22 | 23 | stylesheet : StyleSheet MyStyles variation 24 | stylesheet = 25 | Style.styleSheet 26 | [ Style.style BodyStyle 27 | [ Color.background grey 28 | ] 29 | , Style.style BlockStyle 30 | [ sansSerif 31 | , Color.text black 32 | , Color.background yellow 33 | , Font.size 50 34 | ] 35 | , Style.style HeaderStyle 36 | [ sansSerif 37 | , Font.size 50 38 | , Color.background darkGrey 39 | ] 40 | , Style.style FooterStyle 41 | [ sansSerif 42 | , Font.size 50 43 | , Color.background darkGrey 44 | ] 45 | , Style.style SidebarStyle 46 | [ sansSerif 47 | , Font.size 20 48 | , Color.background grey 49 | ] 50 | , Style.style PageStyle [] 51 | , Style.style ContentStyle [] 52 | ] 53 | -------------------------------------------------------------------------------- /src/View.elm: -------------------------------------------------------------------------------- 1 | module View exposing (view) 2 | 3 | import Model exposing (..) 4 | import Html exposing (..) 5 | import Element exposing (..) 6 | import Element.Attributes exposing (..) 7 | import AppStyles 8 | 9 | 10 | blockAttributes : ScreenSize -> List (Element.Internal.Model.Attribute variation msg) 11 | blockAttributes screenSize = 12 | case screenSize of 13 | Phone -> 14 | [ width (percent 100), height (px 100) ] 15 | 16 | Tablet -> 17 | [ width (percent 50), height (px 100) ] 18 | 19 | Desktop -> 20 | [ width (percent 33), height (px 100) ] 21 | 22 | BigDesktop -> 23 | [ width (percent 25), height (px 100) ] 24 | 25 | 26 | wrapper : Model -> Element AppStyles.MyStyles variation Msg 27 | wrapper model = 28 | Element.row AppStyles.PageStyle 29 | [ padding 20 30 | , paddingTop 0 31 | , paddingBottom 0 32 | ] 33 | [ pageArea model ] 34 | 35 | 36 | pageArea : Model -> Element AppStyles.MyStyles variation Msg 37 | pageArea model = 38 | Element.column AppStyles.PageStyle 39 | [ width (percent 100) ] 40 | [ headerArea 41 | , contentArea model 42 | , footerArea 43 | ] 44 | 45 | 46 | headerArea : Element AppStyles.MyStyles variation msg 47 | headerArea = 48 | el AppStyles.HeaderStyle 49 | [] 50 | (Element.text "Header") 51 | 52 | 53 | footerArea : Element AppStyles.MyStyles variation msg 54 | footerArea = 55 | el AppStyles.FooterStyle 56 | [] 57 | (Element.text "Footer") 58 | 59 | 60 | sidebarArea : Model -> Element AppStyles.MyStyles variation Msg 61 | sidebarArea model = 62 | if model.screenSize == Phone then 63 | Element.empty 64 | else 65 | Element.column AppStyles.SidebarStyle 66 | [ paddingLeft 20 67 | , paddingTop 50 68 | , width (percent 20) 69 | ] 70 | [ Element.text "Sidebar" 71 | , Element.text "Sidebar" 72 | , Element.text "Sidebar" 73 | , Element.text "Sidebar" 74 | , Element.text "Sidebar" 75 | ] 76 | 77 | 78 | contentArea : Model -> Element AppStyles.MyStyles variation Msg 79 | contentArea model = 80 | Element.row AppStyles.ContentStyle 81 | [] 82 | [ sidebarArea model 83 | , mainContentArea model 84 | ] 85 | 86 | 87 | 88 | --bodyWidth : ScreenSize -> Element.Internal.Model.Attribute variation msg 89 | 90 | 91 | bodyWidth screenSize = 92 | if screenSize == Phone then 93 | width (percent 100) 94 | else 95 | width (percent 80) 96 | 97 | 98 | blocks : Model -> List (Element AppStyles.MyStyles variation Msg) 99 | blocks model = 100 | List.map (\elem -> (singleBlock model elem)) 101 | [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ] 102 | 103 | 104 | singleBlock : Model -> String -> Element AppStyles.MyStyles variation Msg 105 | singleBlock model value = 106 | el AppStyles.BlockStyle 107 | (blockAttributes model.screenSize) 108 | (Element.text value) 109 | 110 | 111 | mainContentArea : Model -> Element AppStyles.MyStyles variation Msg 112 | mainContentArea model = 113 | Element.wrappedRow AppStyles.BodyStyle 114 | [ padding 10, spacing 7, (bodyWidth model.screenSize) ] 115 | (blocks model) 116 | 117 | 118 | view : Model -> Html Msg 119 | view model = 120 | Element.layout AppStyles.stylesheet <| 121 | wrapper model 122 | --------------------------------------------------------------------------------