Skip to content

Commit 934da24

Browse files
committed
Initial implementation.
0 parents  commit 934da24

File tree

9 files changed

+326
-0
lines changed

9 files changed

+326
-0
lines changed

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
elm-package.json
2+
dist
3+
elm-stuff

Diff for: config/development.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"key": "value"
3+
}

Diff for: elm-ui.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"version": "1.0.0",
3+
"summary": "Elm-UI Project",
4+
"repository": "https://github.com/user/project.git",
5+
"license": "BSD3",
6+
"native-modules": true,
7+
"source-directories": [
8+
"source"
9+
],
10+
"exposed-modules": [],
11+
"dependencies": {
12+
"circuithub/elm-array-extra" : "1.1.2 <= v < 2.0.0"
13+
},
14+
"elm-version": "0.16.0 <= v < 0.17.0"
15+
}

Diff for: source/Counter.elm

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module Counter where
2+
3+
import Html.Attributes exposing (class)
4+
import Html.Events exposing (onClick)
5+
import Html exposing (div, span, text, button)
6+
7+
import Global
8+
9+
type alias Model =
10+
{ counter: Int
11+
, globalAddress : Signal.Address Global.Action
12+
}
13+
14+
type Action
15+
= Increment
16+
| Decrement
17+
18+
init : Signal.Address Global.Action -> Model
19+
init globalAddress =
20+
{ counter = 0
21+
, globalAddress = globalAddress
22+
}
23+
24+
counterCount : Model -> Int
25+
counterCount model =
26+
1
27+
28+
update : Action -> Model -> Model
29+
update action model =
30+
case action of
31+
Increment ->
32+
{ model | counter = model.counter + 1 }
33+
34+
Decrement ->
35+
{ model | counter = model.counter - 1 }
36+
37+
view : Signal.Address Action -> Model -> Html.Html
38+
view address model =
39+
div [class "counter"]
40+
[ span [] [text (toString model.counter)]
41+
, button [onClick address Increment] [text "increment"]
42+
, button [onClick address Decrement] [text "decrement"]
43+
, button [onClick model.globalAddress Global.Increment] [text "global increment"]
44+
]

Diff for: source/CounterList.elm

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
module CounterList where
2+
3+
import Array exposing (Array)
4+
import Array.Extra
5+
import Signal exposing (forwardTo)
6+
7+
import Html.Attributes exposing (class)
8+
import Html.Events exposing (onClick)
9+
import Html exposing (div, span, strong, text, button)
10+
11+
import CounterPair
12+
import Global
13+
14+
type alias Model =
15+
{ counters : Array CounterPair.Model
16+
, globalAddress : Signal.Address Global.Action
17+
}
18+
19+
type Action
20+
= Counter Int CounterPair.Action
21+
| Add
22+
| Remove Int
23+
24+
init : Signal.Address Global.Action -> Model
25+
init globalAddress =
26+
{ counters = Array.fromList []
27+
, globalAddress = globalAddress
28+
}
29+
30+
counterCount : Model -> Int
31+
counterCount model =
32+
Array.map (\counters -> CounterPair.counterCount counters) model.counters
33+
|> Array.foldl (+) 0
34+
35+
updateCounter : Int -> CounterPair.Action -> Array CounterPair.Model -> Array CounterPair.Model
36+
updateCounter index action counters =
37+
let
38+
updatedCounter counterIndex counter =
39+
if counterIndex == index then
40+
CounterPair.update action counter
41+
else
42+
counter
43+
in
44+
Array.indexedMap updatedCounter counters
45+
46+
update : Action -> Model -> Model
47+
update action model =
48+
case action of
49+
Add ->
50+
{ model | counters = Array.push (CounterPair.init model.globalAddress) model.counters}
51+
Remove index ->
52+
{ model | counters = Array.Extra.removeAt index model.counters}
53+
Counter index act ->
54+
{ model | counters = updateCounter index act model.counters }
55+
56+
57+
view : Signal.Address Action -> Model -> Html.Html
58+
view address model =
59+
let
60+
counter index counter =
61+
div []
62+
[ CounterPair.view (forwardTo address (Counter index)) counter
63+
, button [onClick address (Remove index)] [text "-"]
64+
]
65+
66+
counters =
67+
Array.indexedMap counter model.counters
68+
|> Array.toList
69+
in
70+
div [class "counter-list"]
71+
[ button [onClick address Add] [text "Add Counter"]
72+
, div [] counters
73+
]

Diff for: source/CounterPair.elm

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module CounterPair where
2+
3+
import Html.Attributes exposing (class)
4+
import Html.Events exposing (onClick)
5+
import Html exposing (div, text, button)
6+
import Signal exposing (forwardTo)
7+
8+
import Counter
9+
10+
import Global
11+
12+
type alias Model =
13+
{ counter1: Counter.Model
14+
, counter2: Counter.Model
15+
, globalAddress : Signal.Address Global.Action
16+
}
17+
18+
type Action
19+
= Counter1 Counter.Action
20+
| Counter2 Counter.Action
21+
22+
init : Signal.Address Global.Action -> Model
23+
init globalAddress =
24+
{ counter1 = Counter.init globalAddress
25+
, counter2 = Counter.init globalAddress
26+
, globalAddress = globalAddress
27+
}
28+
29+
counterCount : Model -> Int
30+
counterCount model =
31+
2
32+
33+
update : Action -> Model -> Model
34+
update action model =
35+
case action of
36+
Counter1 act ->
37+
{ model | counter1 = Counter.update act model.counter1 }
38+
Counter2 act ->
39+
{ model | counter2 = Counter.update act model.counter2 }
40+
41+
view : Signal.Address Action -> Model -> Html.Html
42+
view address model =
43+
div [class "counter-pair"]
44+
[ div []
45+
[ Counter.view (forwardTo address Counter1) model.counter1
46+
, Counter.view (forwardTo address Counter2) model.counter2
47+
]
48+
]

Diff for: source/Global.elm

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Global where
2+
3+
type Action
4+
= Increment

Diff for: source/Main.elm

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
module Main where
2+
3+
import Signal exposing (forwardTo)
4+
import StartApp
5+
import Effects
6+
import Task
7+
8+
import Html.Attributes exposing (class)
9+
import Html exposing (div, span, strong, text, h1)
10+
11+
import Global
12+
import Counter
13+
import CounterPair
14+
import CounterList
15+
16+
import Ui.App
17+
18+
type alias Model =
19+
{ app : Ui.App.Model
20+
, comp1 : Counter.Model
21+
, comp2 : CounterPair.Model
22+
, comp3 : CounterList.Model
23+
, counter : Int
24+
}
25+
26+
type Action
27+
= Global Global.Action
28+
| Counter Counter.Action
29+
| CounterPair CounterPair.Action
30+
| CounterList CounterList.Action
31+
| App Ui.App.Action
32+
33+
global : Signal.Mailbox Global.Action
34+
global =
35+
Signal.mailbox Global.Increment
36+
37+
init : Model
38+
init =
39+
{ comp1 = Counter.init global.address
40+
, comp2 = CounterPair.init global.address
41+
, comp3 = CounterList.init global.address
42+
, app = Ui.App.init "Counters"
43+
, counter = 0
44+
}
45+
46+
update : Action -> Model -> (Model, Effects.Effects Action)
47+
update action model =
48+
case action of
49+
App act ->
50+
let
51+
(app, effect) = Ui.App.update act model.app
52+
in
53+
({ model | app = app }, Effects.map App effect)
54+
55+
Counter act ->
56+
({ model | comp1 = Counter.update act model.comp1 }, Effects.none)
57+
58+
CounterPair act ->
59+
({ model | comp2 = CounterPair.update act model.comp2 }, Effects.none)
60+
61+
CounterList act ->
62+
({ model | comp3 = CounterList.update act model.comp3 }, Effects.none)
63+
64+
Global act ->
65+
case act of
66+
Global.Increment ->
67+
let
68+
by = if (counterCount model) > 10 then 2 else 1
69+
in
70+
({ model | counter = model.counter + by }, Effects.none)
71+
72+
counterCount model =
73+
(Counter.counterCount model.comp1) +
74+
(CounterPair.counterCount model.comp2) +
75+
(CounterList.counterCount model.comp3)
76+
77+
view : Signal.Address Action -> Model -> Html.Html
78+
view address model =
79+
Ui.App.view (forwardTo address App) model.app
80+
[ div []
81+
[ div []
82+
[ h1 [] [text "Global Counter"]
83+
, h1 [] [text (toString model.counter)]
84+
, h1 [] [text "Counter Count"]
85+
, h1 [] [text (toString (counterCount model))]
86+
]
87+
, div [class "counters"]
88+
[ Counter.view (forwardTo address Counter) model.comp1
89+
, CounterPair.view (forwardTo address CounterPair) model.comp2
90+
, CounterList.view (forwardTo address CounterList) model.comp3
91+
]
92+
]
93+
]
94+
95+
app =
96+
StartApp.start { init = (init, Effects.none)
97+
, update = update
98+
, view = view
99+
, inputs = [Signal.map Global global.signal]
100+
}
101+
102+
main =
103+
app.html
104+
105+
port tasks : Signal (Task.Task Effects.Never ())
106+
port tasks =
107+
app.tasks

Diff for: stylesheets/main.scss

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.counter {
2+
> * + * {
3+
margin-left: 10px;
4+
}
5+
}
6+
7+
.counter-pair, .counter, .counter-list {
8+
padding: 10px;
9+
border: 1px solid #CCC;
10+
margin: 5px;
11+
}
12+
13+
button {
14+
text-transform: uppercase;
15+
}
16+
17+
ui-app {
18+
overflow: auto;
19+
height: 100vh;
20+
display: block;
21+
}
22+
23+
.counters {
24+
display: flex;
25+
26+
> * {
27+
flex: 1;
28+
}
29+
}

0 commit comments

Comments
 (0)