-
-
Notifications
You must be signed in to change notification settings - Fork 147
/
tour.cljs
95 lines (79 loc) · 3.11 KB
/
tour.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
89
90
91
92
93
94
95
(ns re-com.tour
(:require-macros [re-com.core :refer [handler-fn]])
(:require [reagent.core :as reagent]
[re-com.box :refer [flex-child-style]]
[re-com.buttons :refer [button]]))
;;--------------------------------------------------------------------------------------------------
;; Component: tour
;;
;; Strings together
;;--------------------------------------------------------------------------------------------------
(defn make-tour
"Returns a map containing
- A reagent atom for each tour step controlling popover show/hide (boolean)
- A standard atom holding the current step (integer)
- A copy of the steps parameter passed in, to determine the order for prev/next functions
It sets the first step atom to true so that it will be initially shown
Sample return value:
{:steps [:step1 :step2 :step3]
:current-step (atom 0)
:step1 (reagent/atom true)
:step2 (reagent/atom false)
:step3 (reagent/atom false)}"
[tour-spec]
(let [tour-map {:current-step (atom 0) :steps tour-spec}] ;; Only need normal atom
(reduce #(assoc %1 %2 (reagent/atom false)) tour-map tour-spec))) ;; Old way: (merge {} (map #(hash-map % (reagent/atom false)) tour-spec))
(defn- initialise-tour
"Resets all poover atoms to false"
[tour]
(doall (for [step (:steps tour)] (reset! (step tour) false))))
(defn start-tour
"Sets the first popover atom in the tour to true"
[tour]
(initialise-tour tour)
(reset! (:current-step tour) 0)
(reset! ((first (:steps tour)) tour) true))
(defn finish-tour
"Closes all tour popovers"
[tour]
(initialise-tour tour))
(defn- next-tour-step
[tour]
(let [steps (:steps tour)
old-step @(:current-step tour)
new-step (inc old-step)]
(when (< new-step (count (:steps tour)))
(reset! (:current-step tour) new-step)
(reset! ((nth steps old-step) tour) false)
(reset! ((nth steps new-step) tour) true))))
(defn- prev-tour-step
[tour]
(let [steps (:steps tour)
old-step @(:current-step tour)
new-step (dec old-step)]
(when (>= new-step 0)
(reset! (:current-step tour) new-step)
(reset! ((nth steps old-step) tour) false)
(reset! ((nth steps new-step) tour) true))))
(defn make-tour-nav
"Generate the hr and previous/next buttons markup.
If first button in tour, don't generate a Previous button.
If last button in tour, change Next button to a Finish button"
[tour]
(let [on-first-button (= @(:current-step tour) 0)
on-last-button (= @(:current-step tour) (dec (count (:steps tour))))]
[:div
[:hr {:style (merge (flex-child-style "none")
{:margin "10px 0px 10px"})}]
(when-not on-first-button
[button
:label "Previous"
:on-click (handler-fn (prev-tour-step tour))
:style {:margin-right "15px"}
:class "btn-default"])
[button
:label (if on-last-button "Finish" "Next")
:on-click (handler-fn (if on-last-button
(finish-tour tour)
(next-tour-step tour)))
:class "btn-default"]]))