-
-
Notifications
You must be signed in to change notification settings - Fork 147
/
alert.cljs
120 lines (114 loc) · 8.51 KB
/
alert.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
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
(ns re-com.alert
(:require-macros [re-com.core :refer [handler-fn]])
(:require [re-com.util :refer [deref-or-value]]
[re-com.buttons :refer [button]]
[re-com.close-button :refer [close-button]]
[re-com.box :refer [h-box v-box box scroller border flex-child-style]]
[re-com.validate :refer [string-or-hiccup? alert-type? alert-types-list
vector-of-maps? css-style? html-attr?] :refer-macros [validate-args-macro]]))
;;--------------------------------------------------------------------------------------------------
;; Component: alert
;;--------------------------------------------------------------------------------------------------
(def alert-box-args-desc
[{:name :id :required false :type "anything" :description [:span "a unique identifier, usually an integer or string."]}
{:name :alert-type :required false :default :info :type "keyword" :validate-fn alert-type? :description [:span "one of " alert-types-list]}
{:name :heading :required false :type "string | hiccup" :validate-fn string-or-hiccup? :description [:span "displayed as a larger heading. One of " [:code ":heading"] " or " [:code ":body"] " should be provided"]}
{:name :body :required false :type "string | hiccup" :validate-fn string-or-hiccup? :description "displayed within the body of the alert"}
{:name :padding :required false :default "15px" :type "string" :validate-fn string? :description "padding surounding the alert"}
{:name :closeable? :required false :default false :type "boolean" :description [:span "if true, render a close button. " [:code ":on-close"] " should be supplied"]}
{:name :on-close :required false :type ":id -> nil" :validate-fn fn? :description [:span "called when the user clicks the close 'X' button. Passed the " [:code ":id"] " of the alert to close"]}
{:name :class :required false :type "string" :validate-fn string? :description "CSS class names, space separated (applies to the outer container)"}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override (applies to the outer container)"}
{:name :attr :required false :type "HTML attr map" :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed (applies to the outer container)"]}])
(defn alert-box
"Displays one alert box. A close button allows the message to be removed"
[& {:keys [id alert-type heading body padding closeable? on-close class style attr]
:or {alert-type :info}
:as args}]
{:pre [(validate-args-macro alert-box-args-desc args "alert-box")]}
(let [close-alert [close-button
:on-click #(on-close id)
:div-size 20
:font-size 20]
alert-class (alert-type {:none ""
:info "alert-success"
:warning "alert-warning"
:danger "alert-danger"})]
[:div
(merge {:class (str "rc-alert alert fade in " alert-class " " class)
:style (merge (flex-child-style "none")
{:padding padding}
style)}
attr)
(when heading
[h-box
:justify :between
:align :center
:style {:margin-bottom (if body "10px" "0px")}
:children [[:h4
{:style {:margin-bottom "0px"}} ;; Override h4
heading]
(when (and closeable? on-close)
close-alert)]])
(when body
[h-box
:justify :between
:align :center
:children [[:div body]
(when (and (not heading) closeable? on-close)
close-alert)]])]))
;;--------------------------------------------------------------------------------------------------
;; Component: alert-list
;;--------------------------------------------------------------------------------------------------
(def alert-list-args-desc
[{:name :alerts :required true :type "vector of maps | atom" :validate-fn vector-of-maps? :description "alerts to render (in the order supplied). Can also be a list of maps"}
{:name :on-close :required true :type ":id -> nil" :validate-fn fn? :description [:span "called when the user clicks the close 'X' button. Passed the alert's " [:code ":id"]]}
{:name :max-height :required false :type "string" :validate-fn string? :description "CSS style for maximum list height. By default, it grows forever"}
{:name :padding :required false :default "4px" :type "string" :validate-fn string? :description "CSS padding within the alert"}
{:name :border-style :required false :default "1px solid lightgrey" :type "string" :validate-fn string? :description "CSS border style surrounding the list"}
{:name :alert-class :required false :type "string" :validate-fn string? :description "CSS class names, space separated (applies to each alert-box component)"}
{:name :alert-style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles (applies to each alert-box component)"}
{:name :class :required false :type "string" :validate-fn string? :description "CSS class names, space separated (applies to the outer container)"}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override (applies to the outer container)"}
{:name :attr :required false :type "HTML attr map" :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed (applies to the outer container)"]}])
(defn alert-list
"Displays a list of alert-box components in a v-box. Sample alerts object:
[{:id 2
:alert-type :warning
:heading \"Heading\"
:body \"Body\"
:padding \"8px\"
:closeable? true}
{:id 1
:alert-type :info
:heading \"Heading\"
:body \"Body\"}]"
[& {:keys [alerts on-close max-height padding border-style alert-class alert-style class style attr]
:or {padding "4px"}
:as args}]
{:pre [(validate-args-macro alert-list-args-desc args "alert-list")]}
(let [alerts (deref-or-value alerts)]
[box
:child [border
:class (str "rc-alert-list " class)
:style style
:attr attr
:padding padding
:border border-style
:child [scroller
:v-scroll :auto
:style {:max-height max-height}
:child [v-box
:size "auto"
:children [(for [alert alerts]
(let [{:keys [id alert-type heading body padding closeable?]} alert]
^{:key id} [alert-box
:id id
:alert-type alert-type
:heading heading
:body body
:padding padding
:closeable? closeable?
:on-close on-close
:class alert-class
:style alert-style]))]]]]]))