@@ -10,4 +10,111 @@ Available on [Pursuit](https://pursuit.purescript.org/packages/purescript-react-
10
10
11
11
``` purescript
12
12
module Example where
13
+
14
+ import Prelude
15
+
16
+ import Data.Array ((!!), drop, mapWithIndex, take)
17
+ import Data.Foldable (for_)
18
+ import Data.Maybe (Maybe(Nothing), fromMaybe, maybe)
19
+ import React.Basic (ReactComponent, createElement, fragment, react)
20
+ import React.Basic.DOM as R
21
+ import React.Basic.DOM.Events (targetChecked)
22
+ import React.Basic.Events as Events
23
+ import React.Basic.ReactDND (DragDrop, DragDropContextProps, DragDropItemType(..), createDragDrop, createDragDropContext)
24
+ import React.Basic.ReactDND.Backends.HTML5Backend (html5Backend)
25
+
26
+ dndContext :: ReactComponent DragDropContextProps
27
+ dndContext = createDragDropContext html5Backend
28
+
29
+ dnd :: DragDrop { itemId :: String, index :: Int }
30
+ dnd = createDragDrop (DragDropItemType "TODO_ITEM")
31
+
32
+ component :: ReactComponent {}
33
+ component = react { displayName: "BasicExample", initialState, receiveProps, render }
34
+ where
35
+ initialState =
36
+ { todos:
37
+ [ { id: "a", text: "PureScript", done: true }
38
+ , { id: "b", text: "React-Basic", done: true }
39
+ , { id: "c", text: "React-DND-Basic", done: false }
40
+ ]
41
+ }
42
+
43
+ receiveProps _ _ _ =
44
+ pure unit
45
+
46
+ render _ state setState =
47
+ createElement dndContext
48
+ { child:
49
+ fragment
50
+ [ R.h1_ [ R.text "Todos" ]
51
+ , R.p_ [ R.text "Drag to reorder the list:" ]
52
+ , R.section_ (mapWithIndex renderTodo state.todos)
53
+ ]
54
+ }
55
+
56
+ where
57
+ renderTodo index todo =
58
+ createElement dnd.dragSource
59
+ { beginDrag: \_ -> pure
60
+ { itemId: todo.id
61
+ , index
62
+ }
63
+ , endDrag: const (pure unit)
64
+ , canDrag: const (pure true)
65
+ , isDragging: \{ item: draggingItem } ->
66
+ pure $ maybe false (\i -> i.itemId == todo.id) draggingItem
67
+ , render: \{ connectDragSource, isDragging } ->
68
+ createElement dnd.dropTarget
69
+ { drop: \{ item: dragItem } -> do
70
+ for_ (_.index <$> dragItem) \dragItemIndex ->
71
+ setState \s -> s
72
+ { todos = moveItem dragItemIndex index s.todos
73
+ }
74
+ pure Nothing
75
+ , hover: const (pure unit)
76
+ , canDrop: const (pure true)
77
+ , render: \{ connectDropTarget, isOver, item: maybeDragItem } ->
78
+ connectDragSource $ connectDropTarget $
79
+ R.div
80
+ { style: R.css
81
+ { padding: "0.3rem 0.8rem"
82
+ , alignItems: "center"
83
+ , borderTop:
84
+ if isOver && (fromMaybe false ((\dragItem -> dragItem.index > index) <$> maybeDragItem))
85
+ then "0.2rem solid #0044e4"
86
+ else "0.2rem solid transparent"
87
+ , borderBottom:
88
+ if isOver && (fromMaybe false ((\dragItem -> dragItem.index < index) <$> maybeDragItem))
89
+ then "0.2rem solid #0044e4"
90
+ else "0.2rem solid transparent"
91
+ , opacity: if isDragging then 0.1 else 1.0
92
+ }
93
+ , children:
94
+ [ R.input
95
+ { "type": "checkbox"
96
+ , checked: todo.done
97
+ , onChange: Events.handler targetChecked \checked -> do
98
+ setState \s -> s
99
+ { todos = s.todos <#> \t ->
100
+ if t.id == todo.id
101
+ then t { done = fromMaybe false checked }
102
+ else t
103
+ }
104
+ }
105
+ , R.text todo.text
106
+ ]
107
+ }
108
+ }
109
+ }
110
+
111
+ moveItem :: forall a. Int -> Int -> Array a -> Array a
112
+ moveItem fromIndex toIndex items =
113
+ let
114
+ item = items !! fromIndex
115
+ items' = take fromIndex items <> drop (fromIndex + 1) items
116
+ in
117
+ take toIndex items'
118
+ <> maybe [] pure item
119
+ <> drop toIndex items'
13
120
```
0 commit comments