/
core.cljs
88 lines (76 loc) · 2.48 KB
/
core.cljs
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
(ns example.core
(:require [reagent.core :as r]
[reagent.dom :as rdom]
[react-sortable-hoc :as sort]
[goog.object :as gobj]))
;; Adapted from https://github.com/clauderic/react-sortable-hoc/blob/master/examples/drag-handle.js#L10
(def DragHandle
(sort/SortableHandle.
;; Alternative to r/reactify-component, which doens't convert props and hiccup,
;; is to just provide fn as component and use as-element or create-element
;; to return React elements from the component.
(fn []
(r/as-element [:span "::"]))))
(def SortableItem
(sort/SortableElement.
(r/reactify-component
(fn [{:keys [value]}]
[:li
[:> DragHandle]
value]))))
;; Alternative without reactify-component
;; props is JS object here
#_
(def SortableItem
(sort/SortableElement.
(fn [props]
(r/as-element
[:li
[:> DragHandle]
(.-value props)]))))
(def SortableList
(sort/SortableContainer.
(r/reactify-component
(fn [{:keys [items]}]
[:ul
(for [[value index] (map vector items (range))]
;; No :> or adapt-react-class here because that would convert value to JS
(r/create-element
SortableItem
#js {:key (str "item-" index)
:index index
:value value}))]))))
;; Or using new :r> shortcut, which doesn't do props conversion
#_
(def SortableList
(sort/SortableContainer.
(r/reactify-component
(fn [{:keys [items]}]
[:ul
(for [[value index] (map vector items (range))]
[:r> SortableItem
#js {:key (str "item-" index)
:index index
:value value}])]))))
(defn vector-move [coll prev-index new-index]
(let [items (into (subvec coll 0 prev-index)
(subvec coll (inc prev-index)))]
(-> (subvec items 0 new-index)
(conj (get coll prev-index))
(into (subvec items new-index)))))
(comment
(= [0 2 3 4 1 5] (vector-move [0 1 2 3 4 5] 1 4)))
(defn sortable-component []
(let [items (r/atom (vec (map (fn [i] (str "Item " i)) (range 6))))]
(fn []
(r/create-element
SortableList
#js {:items @items
:onSortEnd (fn [event]
(swap! items vector-move (.-oldIndex event) (.-newIndex event)))
:useDragHandle true}))))
(defn main []
[sortable-component])
(defn start []
(rdom/render [main] (js/document.getElementById "app")))
(start)