@@ -10,4 +10,111 @@ Available on [Pursuit](https://pursuit.purescript.org/packages/purescript-react-
1010
1111``` purescript
1212module 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'
13120```
0 commit comments