Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathBasic.purs
More file actions
Latest commit
139 lines (130 loc) · 4.21 KB
/
Copy pathBasic.purs
File metadata and controls
139 lines (130 loc) · 4.21 KB
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
moduleExample.Basicwhere
importPrelude
importData.Array ((!!), drop, mapWithIndex, take)
importData.Foldable (traverse_)
importData.IntasInt
importData.Maybe (fromMaybe, maybe, Maybe(..))
importEffect (Effect)
importEffect.Class.ConsoleasConsole
importEffect.Exception (throw)
importReact.Basic.DOM (render)
importReact.Basic.DOMasR
importReact.Basic.DOM.Events (targetChecked)
importReact.Basic.EventsasEvents
importReact.Basic.Hooks (Component, component, fragment, mkReducer, useReducer, (/\))
importReact.Basic.HooksasReact
importReact.Basic.ReactDND (dndProvider, mergeTargets, useDrag, useDrop)
importReact.Basic.ReactDND.Backends.HTML5Backend (html5Backend)
importWeb.DOM.NonElementParentNode (getElementById)
importWeb.HTML (window)
importWeb.HTML.HTMLDocument (toNonElementParentNode)
importWeb.HTML.Window (document)
dataAction
= Move{from::Int, to::Int}
|SetDoneStringBoolean
typeTodo={id::String, text::String, done::Boolean}
mkTodoExample::ComponentUnit
mkTodoExample = do
todo <- mkTodo
reducer <- mkReducer update
React.component "TodoExample" \_ ->React.do
state /\ dispatch <- useReducer initialState reducer
pure
$ dndProvider html5Backend
$ fragment
[ R.h1_ [ R.text "Todos" ]
, R.p_ [ R.text "Drag to reorder the list:" ]
, R.section_
$ state.todos
# mapWithIndex \index t -> todo { index, todo: t, dispatch }
]
where
initialState =
{ todos:
[ { id: "a", text: "PureScript", done: true }
, { id: "b", text: "React Basic", done: true }
, { id: "c", text: "React Basic DND", done: false }
]
}
update state = case _ of
Move { from, to } ->
state
{ todos = moveItem from to state.todos
}
SetDone id done ->
state
{ todos =
state.todos
<#> \t ->
if t.id == id then
t { done = done }
else
t
}
mkTodo
::Component
{index::Int
, todo::Todo
, dispatch::Action->EffectUnit
}
mkTodo = do
let
todoDND = "todo-dnd"
component "Todo" \{ index, todo, dispatch } ->React.do
{ isDragging, connectDrag } <- useDrag { type: todoDND, id: show index }
{ id: maybeDragItem, isOver, connectDrop } <-
useDrop
{ accept: todoDND
, onDrop: Int.fromString >>> traverse_ \id -> dispatch $ Move { from: id, to: index }
}
pure
$ R.label
{ ref: mergeTargets connectDrag connectDrop
, style:
R.css
{ display: "block"
, padding: "0.3rem 0.8rem"
, alignItems: "center"
, borderTop:
if isOver && maybe false ((_ > show index)) maybeDragItem then
"0.2rem solid #0044e4"
else
"0.2rem solid transparent"
, borderBottom:
if isOver && maybe false ((_ < show index)) maybeDragItem then
"0.2rem solid #0044e4"
else
"0.2rem solid transparent"
, opacity: if isDragging then0.1else1.0
}
, children:
[ R.input
{ type: "checkbox"
, checked: todo.done
, onChange:
Events.handler targetChecked \checked ->do
dispatch $ SetDone todo.id $ fromMaybe false checked
}
, R.text todo.text
]
}
moveItem::foralla. Int->Int->Arraya->Arraya
moveItem fromIndex toIndex items =
let
item = items !! fromIndex
items' = take fromIndex items <> drop (fromIndex + 1) items
in
take toIndex items'
<> maybe [] pure item
<> drop toIndex items'
main::EffectUnit
main = do
maybeContainer <- window
>>= document
>>= toNonElementParentNode
>>> getElementById "container"
case maybeContainer of
Nothing-> throw "Container element not found."
Just container ->do
todoExample <- mkTodoExample
render (todoExample unit) container