-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathClient.fs
164 lines (146 loc) · 5.21 KB
/
Client.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// $begin{copyright}
//
// This file is part of WebSharper
//
// Copyright (c) 2008-2018 IntelliFactory
//
// Licensed under the Apache License, Version 2.0 (the "License"); you
// may not use this file except in compliance with the License. You may
// obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
//
// $end{copyright}
namespace WebSharper.MaterialUI.Tests
open WebSharper
open WebSharper.JavaScript
open WebSharper.React.Bindings
open WebSharper.React
open WebSharper.React.Html
open WebSharper.MaterialUI
[<JavaScript>]
module Client =
type Task =
{
Name : string
State : bool
}
static member Toggle task _ =
{ task with
State = not task.State }
type State =
{
Input : string
Tasks : Task list
}
static member Default =
{
Input = ""
Tasks =
[
{ Name = "buy milk"; State = false }
]
}
type Main(props) as this =
inherit React.Component<MUI.Styles, State>(props)
do this.SetInitialState State.Default
member private this.SetInput(ev: SyntheticEvent) =
this.SetState { this.State with Input = ev.Target?value }
member private this.AddTask() =
if this.State.Input.Length > 0 && not (List.exists (fun task -> task.Name = this.State.Input) this.State.Tasks) then
{ this.State with
Input = ""
Tasks =
{ Name = this.State.Input; State = false } :: this.State.Tasks }
|> this.SetState
member private this.ClearCompleted() =
{ this.State with
Tasks =
this.State.Tasks
|> List.filter (fun task -> not task.State) }
|> this.SetState
member private this.ToggleTask(task) =
{ this.State with
Tasks =
this.State.Tasks
|> List.map (fun x ->
if x.Name = task.Name then
{ task with State = not task.State }
else
x
) }
|> this.SetState
override this.Render() =
MUI.Paper [attr.className this.Props.Classes.["root"]] [
MUI.Button [
attr.variant MUI.ButtonVariant.Contained
attr.fullWidth true
attr.color MUI.Color.Secondary
on.click (fun _ -> this.ClearCompleted())
] [text "Clear completed tasks"]
MUI.List [
attr.className this.Props.Classes.["list"]
attr.subheader (MUI.ListSubheader [] [text "MyTasks"])
] [
for task in this.State.Tasks ->
MUI.ListItem [
attr.``component`` MUI.ButtonBase
attr.button true
on.click (fun _ -> this.ToggleTask(task))
] [
MUI.Checkbox ["checked" => task.State] []
MUI.ListItemText [] [text task.Name]
]
]
MUI.TextField [
attr.fullWidth true
attr.margin MUI.Margin.Normal
attr.autoFocus true
attr.value this.State.Input
attr.placeholder "What needs to be done?"
on.change this.SetInput
] []
MUI.Button [
attr.variant MUI.ButtonVariant.Contained
attr.fullWidth true
attr.color MUI.Color.Primary
on.click (fun _ -> this.AddTask())
] [text "Add"]
]
let MyTheme =
MUI.Theme(
Palette = MUI.Palette(
Primary = MUI.Colors.Green,
Type = MUI.Dark
)
)
let MyStyles (theme: MUI.Theme) =
New [
"root" => New [
"marginTop" => theme.Spacing.Unit
"marginBottom" => theme.Spacing.Unit
"marginLeft" => theme.Spacing.Unit
"marginRight" => theme.Spacing.Unit
"flex" => 1
"display" => "flex"
"flexDirection" => "column"
]
"list" => New [
"flex" => 1
"overflowY" => "auto"
]
]
[<SPAEntryPoint>]
let Main() =
let theme = MUI.CreateTheme MyTheme
MUI.ThemeProvider theme [
MUI.CssBaseline()
MUI.WithStyles MyStyles Main
]
|> React.Mount JS.Document.Body