├── .gitignore
├── .nrepl-port
├── README.md
├── cljs-react-bootstrap.iml
├── project.clj
├── resources
└── public
│ ├── css
│ └── site.css
│ └── index.html
├── script
└── repl.clj
└── src
├── clj
└── cljs-react-bootstrap
│ └── core.clj
└── cljs
└── cljs-react-bootstrap
├── components
├── bootstrap_page.cljs
├── example.cljs
└── site.cljs
├── config.cljs
├── core.cljs
├── db.cljs
├── handlers.cljs
├── layout.cljs
├── react-bootstrap
├── core.cljs
├── dropdown.cljs
├── input.cljs
├── modal.cljs
├── navbar.cljs
└── split-button.cljs
├── subs.cljs
└── views.cljs
/.gitignore:
--------------------------------------------------------------------------------
1 | /*.log
2 | /target
3 | /*-init.clj
4 | /resources/public/js/compiled
5 | out
6 | /.idea
--------------------------------------------------------------------------------
/.nrepl-port:
--------------------------------------------------------------------------------
1 | 50918
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cljs-react-bootstrap
2 |
3 | > A single-page application with [ClojureScript][cljs-url], [React][react-url] and [Bootstrap][bootstrap-url]
4 |
5 | This is an example of a [Bootstrap][bootstrap-url]-powered single-page application in [ClojureScript][cljs-url] using [reagent][reagent-url], [re-frame][reframe-url] and [cljsjs][cljsjs-url]-packaged [React-Bootstrap][react-bootstrap-url], kickstarted with the [Leiningen][lein-url] [re-frame template][re-frame-template-url].
6 |
7 | ## Developing
8 |
9 | ### Run application:
10 |
11 | ```sh
12 | $ lein clean
13 | $ lein figwheel dev
14 | ```
15 |
16 | Figwheel will automatically push cljs changes to the browser.
17 |
18 | Wait a bit, then browse to [http://localhost:3449](http://localhost:3449).
19 |
20 | ## Building
21 |
22 | ```sh
23 | $ lein clean
24 | $ lein cljsbuild once min
25 | ```
26 |
27 | [cljs-url]: https://github.com/clojure/clojurescript
28 | [react-url]: https://facebook.github.io/react/
29 | [bootstrap-url]: https://getbootstrap.com/
30 | [reagent-url]: https://reagent-project.github.io/
31 | [reframe-url]: https://github.com/Day8/re-frame
32 | [cljsjs-url]: https://github.com/cljsjs/packages
33 | [react-bootstrap-url]: https://react-bootstrap.github.io
34 | [lein-url]: https://leiningen.org/
35 | [re-frame-template-url]: https://github.com/Day8/re-frame-template
--------------------------------------------------------------------------------
/cljs-react-bootstrap.iml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/project.clj:
--------------------------------------------------------------------------------
1 | (defproject cljs-react-bootstrap "0.1.0-SNAPSHOT"
2 | :dependencies [[org.clojure/clojure "1.7.0"]
3 | [org.clojure/clojurescript "1.7.170"]
4 | [reagent "0.5.1"]
5 | [reagent-utils "0.1.7"]
6 | [cljsjs/react-bootstrap "0.28.1-1"]
7 | [re-frame "0.6.0"]
8 | [secretary "1.2.3"]
9 | [venantius/accountant "0.1.6"
10 | :exclusions [org.clojure/tools.reader]]
11 | [figwheel-sidecar "0.5.0-6"]]
12 |
13 | :min-lein-version "2.5.3"
14 |
15 | :source-paths ["src/clj", "script"]
16 |
17 | :plugins [[lein-cljsbuild "1.1.1"]
18 | [lein-figwheel "0.5.0-1"]]
19 |
20 | :profiles {:dev {:dependencies [[com.cemerick/piggieback "0.2.1"]
21 | [org.clojure/tools.nrepl "0.2.10"]]
22 | :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}}
23 |
24 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"]
25 |
26 | :figwheel {:css-dirs ["resources/public/css"]}
27 |
28 | :cljsbuild {:builds [{:id "dev"
29 | :source-paths ["src/cljs"]
30 | :figwheel {:on-jsload "cljs-react-bootstrap.core/mount-root"}
31 | :compiler {:main cljs-react-bootstrap.core
32 | :output-to "resources/public/js/compiled/app.js"
33 | :output-dir "resources/public/js/compiled/out"
34 | :asset-path "js/compiled/out"
35 | :source-map-timestamp true}}
36 |
37 | {:id "min"
38 | :source-paths ["src/cljs"]
39 | :compiler {:main cljs-react-bootstrap.core
40 | :output-to "resources/public/js/compiled/app.js"
41 | :optimizations :whitespace
42 | :closure-defines {goog.DEBUG false}
43 | :pretty-print false}}]})
44 |
--------------------------------------------------------------------------------
/resources/public/css/site.css:
--------------------------------------------------------------------------------
1 | .static-menu .dropdown-menu{
2 | display: block;
3 | position: relative;
4 | }
5 |
6 | .static-modal .modal {
7 | position: relative;
8 | top: auto;
9 | right: auto;
10 | left: auto;
11 | bottom: auto;
12 | z-index: 1;
13 | display: block;
14 | }
15 |
16 | .tooltip-static .tooltip {
17 | position: relative;
18 | display: inline-block;
19 | margin: 5px 10px;
20 | }
21 |
22 | .static-popover {
23 | height: 200px;
24 | }
25 |
26 | .static-popover .popover {
27 | position: relative;
28 | left: 0;
29 | right: 0;
30 | }
31 |
32 | .show-grid {
33 | margin-bottom: 15px;
34 | }
35 |
36 | .show-grid div {
37 | border: 1px solid #df691a;
38 | padding: 8px;
39 | }
40 |
41 | .page-header-contained {
42 | border: 1px solid #df691a;
43 | padding: 15px 30px;
44 | }
--------------------------------------------------------------------------------
/resources/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/script/repl.clj:
--------------------------------------------------------------------------------
1 | (use 'figwheel-sidecar.repl-api)
2 | (start-figwheel!) ;; <-- fetches configuration
3 | (cljs-repl)
--------------------------------------------------------------------------------
/src/clj/cljs-react-bootstrap/core.clj:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.core)
2 |
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/components/bootstrap_page.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.components.bootstrap-page
2 | (:require [cljs-react-bootstrap.react-bootstrap.core :as rbs]
3 | [cljs-react-bootstrap.react-bootstrap.dropdown :as rbs-dropdown]
4 | [cljs-react-bootstrap.react-bootstrap.modal :as rbs-modal]
5 | [cljs-react-bootstrap.react-bootstrap.navbar :as rbs-navbar]
6 | [re-frame.core :as re-frame]))
7 |
8 | (defn button-examples
9 | "Bootstrap button component examples"
10 | []
11 | [:div
12 | [rbs/page-header
13 | "Buttons "
14 | [:small
15 | [:code "button"]]]
16 | [:h3 "Options"]
17 | [rbs/button-toolbar
18 | [rbs/button "Default"]
19 | [rbs/button {:bs-style "primary"} "Primary"]
20 | [rbs/button {:bs-style "success"} "Success"]
21 | [rbs/button {:bs-style "info"} "Info"]
22 | [rbs/button {:bs-style "warning"} "Warning"]
23 | [rbs/button {:bs-style "danger"} "Danger"]
24 | [rbs/button {:bs-style "link"} "Link"]]
25 | [:h3 "Sizes"]
26 | [rbs/button-toolbar
27 | [rbs/button {:bs-style "primary"
28 | :bs-size "large"} "Large button"]
29 | [rbs/button {:bs-size "large"} "Large button"]]
30 | [rbs/button-toolbar
31 | [rbs/button {:bs-style "primary"} "Default button"]
32 | [rbs/button "Default button"]]
33 | [rbs/button-toolbar
34 | [rbs/button {:bs-style "primary"
35 | :bs-size "small"} "Small button"]
36 | [rbs/button {:bs-size "small"} "Small button"]]
37 | [rbs/button-toolbar
38 | [rbs/button {:bs-style "primary"
39 | :bs-size "xsmall"} "Extra small button"]
40 | [rbs/button {:bs-size "xsmall"} "Extra small button"]]
41 | [:h3 "Block-level"]
42 | [rbs/well
43 | [rbs/button {:bs-style "primary"
44 | :bs-size "large"
45 | :block true} "Block level button"]
46 | [rbs/button {:bs-size "large"
47 | :block true} "Block level button"]]
48 | [:h3 "Active state"]
49 | [rbs/button-toolbar
50 | [rbs/button {:bs-style "primary"
51 | :bs-size "large"
52 | :active true} "Primary button"]
53 | [rbs/button {:bs-size "large"
54 | :active true} "button"]]
55 | [:h3 "Disabled state"]
56 | [rbs/button-toolbar
57 | [rbs/button {:bs-style "primary"
58 | :bs-size "large"
59 | :disabled true} "Primary button"]
60 | [rbs/button {:bs-size "large"
61 | :disabled true} "button"]]
62 | [:h3 "Button tags"]
63 | [rbs/button-toolbar
64 | [rbs/button {:href "#"} "Link"]
65 | [rbs/button "Button"]]])
66 |
67 |
68 | (defn button-groups-examples
69 | "Boostrap button group component examples"
70 | []
71 | [:div
72 | [rbs/page-header "Button Groups " [:small [:code "button-group"] " " [:code "button-toolbar"]]]
73 | [:h3 "Basic example"]
74 | [rbs/button-group
75 | [rbs/button "Left"]
76 | [rbs/button "Middle"]
77 | [rbs/button "Right"]]
78 | [:h3 "Basic toolbar"]
79 | [rbs/button-toolbar
80 | [rbs/button-group [rbs/button "1"] [rbs/button "2"] [rbs/button "3"] [rbs/button "4"]]
81 | [rbs/button-group [rbs/button "5"] [rbs/button "6"] [rbs/button "7"]]
82 | [rbs/button-group [rbs/button "8"]]]
83 | [:h3 "Sizing"]
84 | [rbs/button-toolbar
85 | [rbs/button-group {:bs-size "large"}
86 | [rbs/button "Left"] [rbs/button "Middle"] [rbs/button "Right"]]]
87 | [rbs/button-toolbar
88 | [rbs/button-group
89 | [rbs/button "Left"] [rbs/button "Middle"] [rbs/button "Right"]]]
90 | [rbs/button-toolbar
91 | [rbs/button-group {:bs-size "small"}
92 | [rbs/button "Left"] [rbs/button "Middle"] [rbs/button "Right"]]]
93 | [rbs/button-toolbar
94 | [rbs/button-group {:bs-size "xsmall"}
95 | [rbs/button "Left"] [rbs/button "Middle"] [rbs/button "Right"]]]
96 | [:h3 "Nesting"]
97 | [rbs/button-group
98 | [rbs/button "1"]
99 | [rbs/button "2"]
100 | [rbs/dropdown-button {:title "Dropdown"}
101 | [rbs/menu-item {:event-key "1"} "Dropdown link 1"]
102 | [rbs/menu-item {:event-key "2"} "Dropdown link 2"]]]
103 | [:h3 "Vertical variation"]
104 | [rbs/button-group {:vertical true}
105 | [rbs/button "Button"]
106 | [rbs/button "Button"]
107 | [rbs/dropdown-button {:title "Dropdown"}
108 | [rbs/menu-item {:event-key "1"} "Dropdown link 1"]
109 | [rbs/menu-item {:event-key "2"} "Dropdown link 2"]]
110 | [rbs/button "Button"]
111 | [rbs/button "Button"]
112 | [rbs/dropdown-button {:title "Dropdown"}
113 | [rbs/menu-item {:event-key "1"} "Dropdown link 1"]
114 | [rbs/menu-item {:event-key "2"} "Dropdown link 2"]]
115 | [rbs/dropdown-button {:title "Dropdown"}
116 | [rbs/menu-item {:event-key "1"} "Dropdown link 1"]
117 | [rbs/menu-item {:event-key "2"} "Dropdown link 2"]]]
118 | [rbs/button-group {:vertical true
119 | :block true}
120 | [rbs/button "Full width button"]
121 | [rbs/button "Full width button"]]
122 | [:h3 "Justified"]
123 | [rbs/button-group
124 | [rbs/button {:href "#"} "Left"]
125 | [rbs/button {:href "#"} "Middle"]
126 | [rbs/dropdown-button {:title "Dropdown"}
127 | [rbs/menu-item {:event-key "1"} "Dropdown link 1"]
128 | [rbs/menu-item {:event-key "2"} "Dropdown link 2"]]]])
129 |
130 |
131 | (defn dropdown-examples
132 | "Bootstrap dropdown component examples"
133 | []
134 | [:div
135 | [rbs/page-header "Dropdowns " [:small [:code "dropdown"]]]
136 | [:h3 "Single button dropdowns"]
137 | (for [val (map-indexed vector ["Default" "Primary" "Success" "Info" "Warning" "Danger" "Link"])]
138 | (let [index (first val)
139 | title (last val)
140 | style (clojure.string/lower-case (last val))]
141 | [rbs/dropdown-button {:bs-style style
142 | :title title
143 | :key index
144 | :id (clojure.string/join ["dropdown-basic-$" (str index)])}
145 | [rbs/menu-item {:event-key 1} "Action 1"]
146 | [rbs/menu-item {:event-key 2
147 | :active true} "Action 2 (active)"]
148 | [rbs/menu-item {:dvider true}]
149 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]))
150 | [:h3 "Split button dropdowns"]
151 | [rbs/button-toolbar
152 | (for [val (map-indexed vector ["Default" "Primary" "Success" "Info" "Warning" "Danger" "Link"])]
153 | (let [index (first val)
154 | title (last val)
155 | style (clojure.string/lower-case (last val))]
156 | [rbs/split-button {:bs-style style
157 | :title title
158 | :key index
159 | :id (clojure.string/join ["split-button-basic-$" (str index)])}
160 | [rbs/menu-item {:event-key 1} "Action 1"]
161 | [rbs/menu-item {:event-key 2
162 | :active true} "Action 2 (active)"]
163 | [rbs/menu-item {:dvider true}]
164 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]))]
165 | [:h3 "Sizing"]
166 | [rbs/button-toolbar
167 | [rbs/dropdown-button {:bs-size "large"
168 | :title "Large button"}
169 | [rbs/menu-item {:event-key 1} "Action 1"]
170 | [rbs/menu-item {:event-key 2
171 | :active true} "Action 2 (active)"]
172 | [rbs/menu-item {:dvider true}]
173 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]
174 | [rbs/button-toolbar
175 | [rbs/dropdown-button {:title "Default button"}
176 | [rbs/menu-item {:event-key 1} "Action 1"]
177 | [rbs/menu-item {:event-key 2
178 | :active true} "Action 2 (active)"]
179 | [rbs/menu-item {:dvider true}]
180 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]
181 | [rbs/button-toolbar
182 | [rbs/dropdown-button {:bs-size "small"
183 | :title "Small button"}
184 | [rbs/menu-item {:event-key 1} "Action 1"]
185 | [rbs/menu-item {:event-key 2
186 | :active true} "Action 2 (active)"]
187 | [rbs/menu-item {:dvider true}]
188 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]
189 | [rbs/button-toolbar
190 | [rbs/dropdown-button {:bs-size "xsmall"
191 | :title "Extra small button"}
192 | [rbs/menu-item {:event-key 1} "Action 1"]
193 | [rbs/menu-item {:event-key 2
194 | :active true} "Action 2 (active)"]
195 | [rbs/menu-item {:dvider true}]
196 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]
197 | [:h3 "No caret variation"]
198 | [rbs/button-toolbar
199 | [rbs/dropdown-button {:title "No caret"
200 | :no-caret true}
201 | [rbs/menu-item {:event-key 1} "Action 1"]
202 | [rbs/menu-item {:event-key 2
203 | :active true} "Action 2 (active)"]
204 | [rbs/menu-item {:dvider true}]
205 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]
206 | [:h3 "Dropup variation"]
207 | [rbs/button-toolbar
208 | [rbs/split-button {:title "Dropup"
209 | :dropup true}
210 | [rbs/menu-item {:event-key 1} "Action 1"]
211 | [rbs/menu-item {:event-key 2
212 | :active true} "Action 2 (active)"]
213 | [rbs/menu-item {:dvider true}]
214 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]
215 | [rbs/button-toolbar
216 | [rbs/split-button {:bs-style "primary"
217 | :title "Right dropup"
218 | :dropup true
219 | :pull-right true}
220 | [rbs/menu-item {:event-key 1} "Action 1"]
221 | [rbs/menu-item {:event-key 2
222 | :active true} "Action 2 (active)"]
223 | [rbs/menu-item {:dvider true}]
224 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]
225 | [:h3 "Dropdown right variation"]
226 | [rbs/button-toolbar
227 | [rbs/split-button {:title "Dropdown right"
228 | :pull-right true}
229 | [rbs/menu-item {:event-key 1} "Action 1"]
230 | [rbs/menu-item {:event-key 2
231 | :active true} "Action 2 (active)"]
232 | [rbs/menu-item {:dvider true}]
233 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]
234 | [:h3 "Dropdown customization"]
235 | [rbs/button-toolbar
236 | [rbs/dropdown
237 | [rbs-dropdown/toggle
238 | [rbs/glyphicon {:glyph "star"}]
239 | "Pow! Zoom!"]
240 | [rbs-dropdown/menu
241 | [rbs/menu-item {:event-key 1} "Action 1"]
242 | [rbs/menu-item {:event-key 2
243 | :active true} "Action 2 (active)"]
244 | [rbs/menu-item {:dvider true}]
245 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]]
246 | [rbs/button-toolbar
247 | [rbs/dropdown
248 | [rbs/button {:bs-style "info"} "mix it up style-wise"]
249 | [rbs-dropdown/toggle {:bs-style "success"}]
250 | [rbs-dropdown/menu
251 | [rbs/menu-item {:event-key 1} "Action 1"]
252 | [rbs/menu-item {:event-key 2
253 | :active true} "Action 2 (active)"]
254 | [rbs/menu-item {:dvider true}]
255 | [rbs/menu-item {:event-key 3} "Seperated Action 3"]]]]])
256 |
257 |
258 | (defn menu-items-examples
259 | "Bootstrap menu items component examples"
260 | []
261 | [:div
262 | [rbs/page-header "Menu items " [:small [:code "menu-item"]]]
263 | [:div {:class "static-menu"}
264 | [:ul {:class "dropdown-menu opened"}
265 | [rbs/menu-item {:header true} "Header"]
266 | [rbs/menu-item "Link"]
267 | [rbs/menu-item {:divider true}]
268 | [rbs/menu-item {:header true} "Header"]
269 | [rbs/menu-item "Link"]
270 | [rbs/menu-item {:disabled true} "Disabled"]
271 | [rbs/menu-item {:title "See? I have a title."} "link with title"]]
272 | [:div {:class "clearfix"}]]])
273 |
274 |
275 | (defn modal-examples
276 | "Bootstrap modal component examples"
277 | [basic-modal-visible]
278 | [:div
279 | [rbs/page-header "Modals " [:small [:code "modal"]]]
280 | [:h3 "Static Markup"]
281 | [:div {:class "static-modal"}
282 | [rbs-modal/dialog
283 | [rbs-modal/header
284 | [rbs-modal/title "Modal title"]]
285 | [rbs-modal/body
286 | [:p "One fine body..."]]
287 | [rbs-modal/footer
288 | [rbs/button "Close"]
289 | [rbs/button {:bs-style "primary"} "Save changes"]]]]
290 | [:h3 "Basic example"]
291 | [rbs/button {:bs-style "primary"
292 | :on-click #(re-frame/dispatch [:toggle-bootstrap-basic-modal])} "Launch demo modal"]
293 | (if (= basic-modal-visible true)
294 | [rbs-modal/dialog
295 | [rbs-modal/header
296 | [rbs/glyphicon {:glyph "user"}]
297 | [:span " Sign In"]]
298 | [rbs-modal/body
299 | [:form
300 | [rbs/input
301 | {:type "email"
302 | :label "Email Address"
303 | :placeholder "Enter email"}]
304 | [rbs/input
305 | {:type "password"
306 | :label "Password"}]]]
307 | [rbs-modal/footer
308 | [rbs/button {:type "button"
309 | :bs-style "default"
310 | :on-click #(re-frame/dispatch [:toggle-bootstrap-basic-modal])} "Cancel"]
311 | [rbs/button {:type "button"
312 | :bs-style "primary"
313 | :on-click #(re-frame/dispatch [:toggle-bootstrap-basic-modal])} "Sign In"]]])])
314 |
315 |
316 | (defn tooltip-examples
317 | "Bootstrap tooltip component examples"
318 | []
319 | [:div
320 | [rbs/page-header "Tooltip " [:small [:code "tooltip"]]]
321 | [:div {:class "tooltip-static"}
322 | [rbs/tooltip {:placement "right"
323 | :class "in"} "Tooltip right"]
324 | [rbs/tooltip {:placement "top"
325 | :class "in"} "Tooltip top"]
326 | [rbs/tooltip {:placement "left"
327 | :class "in"} "Tooltip left"]
328 | [rbs/tooltip {:placement "bottom"
329 | :class "in"} "Tooltip bottom"]]
330 | #_[:h3 "With overlay trigger"]
331 | #_[rbs/button-toolbar
332 | [rbs/overlay-trigger {:placement "left"
333 | :overlay (tooltip-test)}
334 | [rbs/button "Holy guacamole!"]]]])
335 |
336 |
337 | (defn popover-examples
338 | "Bootstrap popover component examples"
339 | []
340 | [:div
341 | [rbs/page-header "Popovers " [:small [:code "popover"]]]
342 | [:h3 "Static example"]
343 | [:div {:class "static-popover"}
344 | [rbs/popover {:placement "right"
345 | :position-left 200
346 | :position-top 50
347 | :title "Popover right"}
348 | "And here's some "
349 | [:strong "amazing"]
350 | " content. It's very engaging. Right?"]]
351 | #_[:h3 "With Overlay Trigger"]])
352 |
353 |
354 | (defn nav-examples
355 | "Bootstrap navbar component examples"
356 | [nav-basic-key nav-dropdown-key nav-stacked-key nav-justified-key]
357 | [:div
358 | [rbs/page-header "Nav " [:small [:code "nav"]]]
359 | [:h3 "Navs"]
360 | [rbs/nav {:bs-style "pills"
361 | :active-key nav-basic-key
362 | :on-select #(re-frame/dispatch [:set-bootstrap-nav-basic %])}
363 | [rbs/nav-item {:event-key 1
364 | :href "#"} "NavItem 1 content"]
365 | [rbs/nav-item {:event-key 2
366 | :title "Item"} "NavItem 2 content"]
367 | [rbs/nav-item {:event-key 3
368 | :disabled true} "NavItem 3 content"]]
369 | [:h4 "Dropdown"]
370 | [rbs/nav {:bs-style "tabs"
371 | :active-key nav-dropdown-key
372 | :on-select #(re-frame/dispatch [:set-bootstrap-nav-dropdown %])}
373 | [rbs/nav-item {:event-key 1
374 | :href "#"} "NavItem 1 content"]
375 | [rbs/nav-item {:event-key 2
376 | :title "Item"} "NavItem 2 content"]
377 | [rbs/nav-item {:event-key 3
378 | :disabled true} "NavItem 3 content"]
379 | [rbs/nav-dropdown {:event-key 4
380 | :title "Dropdown"}
381 | [rbs/menu-item {:event-key 4.1} "Action 1"]
382 | [rbs/menu-item {:event-key 4.2} "Action 2"]
383 | [rbs/menu-item {:dvider true}]
384 | [rbs/menu-item {:event-key 4.3} "Seperated Action 3"]]]
385 | [:h4 "Stacked"]
386 | [rbs/nav {:bs-style "pills"
387 | :stacked true
388 | :active-key nav-stacked-key
389 | :on-select #(re-frame/dispatch [:set-bootstrap-nav-stacked %])}
390 | [rbs/nav-item {:event-key 1
391 | :href "#"} "NavItem 1 content"]
392 | [rbs/nav-item {:event-key 2
393 | :title "Item"} "NavItem 2 content"]
394 | [rbs/nav-item {:event-key 3
395 | :disabled true} "NavItem 3 content"]]
396 | [:h4 "Justified"]
397 | [rbs/nav {:bs-style "tabs"
398 | :justified true
399 | :active-key nav-justified-key
400 | :on-select #(re-frame/dispatch [:set-bootstrap-nav-justified %])}
401 | [rbs/nav-item {:event-key 1
402 | :href "#"} "NavItem 1 content"]
403 | [rbs/nav-item {:event-key 2
404 | :title "Item"} "NavItem 2 content"]
405 | [rbs/nav-item {:event-key 3
406 | :disabled true} "NavItem 3 content"]]
407 | [rbs/nav {:bs-style "pills"
408 | :justified true
409 | :active-key nav-justified-key
410 | :on-select #(re-frame/dispatch [:set-bootstrap-nav-justified %])}
411 | [rbs/nav-item {:event-key 4
412 | :href "#"} "NavItem 1 content"]
413 | [rbs/nav-item {:event-key 5
414 | :title "Item"} "NavItem 2 content"]
415 | [rbs/nav-item {:event-key 6
416 | :disabled true} "NavItem 3 content"]]])
417 |
418 | (defn navbar-examples
419 | "Bootstrap navbar component examples"
420 | [navbar-basic-key navbar-responsive-key]
421 | [:div
422 | [rbs/page-header "Navbar " [:small [:code "navbar"]]]
423 | [:h3 "Basic example"]
424 | [rbs/navbar
425 | [rbs-navbar/header
426 | [rbs-navbar/brand
427 | [:a {:href "#"} "CLJS React Bootstrap"]]]
428 | [rbs/nav {:className "navbar-nav"
429 | :active-key navbar-basic-key
430 | :on-select #(re-frame/dispatch [:set-bootstrap-navbar-basic %])}
431 | [rbs/nav-item {:event-key 1
432 | :href "#"} "Link 1"]
433 | [rbs/nav-item {:event-key 2
434 | :href "#"} "Link 2"]
435 | [rbs/nav-dropdown {:event-key 3
436 | :title "Dropdown"
437 | :id "basic-nav-dropdown"}
438 | [rbs/menu-item {:event-key 3.1} "Action 1"]
439 | [rbs/menu-item {:event-key 3.2} "Action 2"]
440 | [rbs/menu-item {:dvider true}]
441 | [rbs/menu-item {:event-key 3.3} "Seperated Action 3"]]]]
442 | [:h3 "Responsive navbar"]
443 | [rbs/navbar {:inverse true}
444 | [rbs-navbar/header
445 | [rbs-navbar/toggle]
446 | [rbs-navbar/brand
447 | [:a {:href "#"} "CLJS React Bootstrap"]]]
448 | [rbs-navbar/collapse
449 | [rbs/nav {:className "navbar-nav"
450 | :active-key navbar-responsive-key
451 | :on-select #(re-frame/dispatch [:set-bootstrap-navbar-responsive %])}
452 | [rbs/nav-item {:event-key 1
453 | :href "#"} "Link 1"]
454 | [rbs/nav-item {:event-key 2
455 | :href "#"} "Link 2"]
456 | [rbs/nav-dropdown {:event-key 3
457 | :title "Dropdown"
458 | :id "basic-nav-dropdown"}
459 | [rbs/menu-item {:event-key 3.1} "Action 1"]
460 | [rbs/menu-item {:event-key 3.2} "Action 2"]
461 | [rbs/menu-item {:dvider true}]
462 | [rbs/menu-item {:event-key 3.3} "Seperated Action 3"]]]
463 | [rbs/nav {:className "navbar-nav"
464 | :active-key navbar-responsive-key
465 | :on-select #(re-frame/dispatch [:set-bootstrap-navbar-responsive %])
466 | :pull-right true}
467 | [rbs/nav-item {:event-key 4
468 | :href "#"} "Link Right 4"]
469 | [rbs/nav-item {:event-key 5
470 | :href "#"} "Link Right 5"]]]]
471 | #_[:h3 "Text and non-nav links"]
472 | #_[rbs/navbar {:inverse true}
473 | [rbs-navbar/header
474 | [rbs-navbar/brand
475 | [:a {:href "#"} "CLJS React Bootstrap"]]]
476 | [rbs-navbar/collapse
477 | [rbs-navbar/text
478 | [:span "Sign in as: "]
479 | [rbs-navbar/link {:href "#"} "Mark Otto"]]
480 | [rbs-navbar/text {:pull-right true} "Have a great day!"]]]])
481 |
482 |
483 | (defn breadcrumb-examples
484 | "Bootstrap breadcrumb examples"
485 | []
486 | [:div
487 | [rbs/page-header "Breadcrumbs " [:small [:code "breadcrumb"]]]
488 | [:h3 "Breadcrumbs example"]
489 | [rbs/breadcrumb
490 | [rbs/breadcrumb-item {:href "#"} "Home"]
491 | [rbs/breadcrumb-item {:href "#"} "Library"]
492 | [rbs/breadcrumb-item {:active true} "Data"]]])
493 |
494 |
495 | (defn tabs-examples
496 | "Bootstrap tab component examples"
497 | [controlled-key no-animation-key left-tabs-key pills-key left-pills-key]
498 | [:div
499 | [rbs/page-header "Togglable tabs " [:small [:code "tabs"] [:code "tab"]]]
500 | [:h3 "Controlled"]
501 | [rbs/tabs {:active-key controlled-key
502 | :on-select #(re-frame/dispatch [:set-bootstrap-tabs-controlled %])}
503 | [rbs/tab {:event-key 1
504 | :title "Tab 1"
505 | :disabled false} [rbs/well "Tab 1 content"]]
506 | [rbs/tab {:event-key 2
507 | :title "Tab 2"
508 | :disabled true} [rbs/well "Tab 2 content"]]
509 | [rbs/tab {:event-key 3
510 | :title "Tab 3"
511 | :disabled false} [rbs/well "Tab 3 content"]]]
512 | [:h3 "No animation"]
513 | [rbs/tabs {:active-key no-animation-key
514 | :on-select #(re-frame/dispatch [:set-bootstrap-tabs-no-animation %])
515 | :animation false}
516 | [rbs/tab {:event-key 1
517 | :title "Tab 1"
518 | :disabled false} [rbs/well "Tab 1 content"]]
519 | [rbs/tab {:event-key 2
520 | :title "Tab 2"
521 | :disabled false} [rbs/well "Tab 2 content"]]
522 | [rbs/tab {:event-key 3
523 | :title "Tab 3"
524 | :disabled true} [rbs/well "Tab 3 content"]]]
525 | [:h3 "Left tabs"]
526 | [rbs/tabs {:active-key left-tabs-key
527 | :on-select #(re-frame/dispatch [:set-bootstrap-tabs-left-tabs %])
528 | :position "left"
529 | :bs-style "tabs"}
530 | [rbs/tab {:event-key 1
531 | :title "Tab 1"
532 | :disabled false} [rbs/well "Tab 1 content"]]
533 | [rbs/tab {:event-key 2
534 | :title "Tab 2"
535 | :disabled false} [rbs/well "Tab 2 content"]]
536 | [rbs/tab {:event-key 3
537 | :title "Tab 3"
538 | :disabled true} [rbs/well "Tab 3 content"]]]
539 | [:h3 "Pills"]
540 | [rbs/tabs {:active-key pills-key
541 | :on-select #(re-frame/dispatch [:set-bootstrap-tabs-pills %])
542 | :bs-style "pills"}
543 | [rbs/tab {:event-key 1
544 | :title "Tab 1"
545 | :disabled false} [rbs/well "Tab 1 content"]]
546 | [rbs/tab {:event-key 2
547 | :title "Tab 2"
548 | :disabled false} [rbs/well "Tab 2 content"]]
549 | [rbs/tab {:event-key 3
550 | :title "Tab 3"
551 | :disabled true} [rbs/well "Tab 3 content"]]]
552 | [:h3 "Left Pills"]
553 | [rbs/tabs {:active-key left-pills-key
554 | :on-select #(re-frame/dispatch [:set-bootstrap-tabs-left-pills %])
555 | :position "left"
556 | :bs-style "pills"}
557 | [rbs/tab {:event-key 1
558 | :title "Tab 1"
559 | :disabled false} [rbs/well "Tab 1 content"]]
560 | [rbs/tab {:event-key 2
561 | :title "Tab 2"
562 | :disabled false} [rbs/well "Tab 2 content"]]
563 | [rbs/tab {:event-key 3
564 | :title "Tab 3"
565 | :disabled true} [rbs/well "Tab 3 content"]]]])
566 |
567 |
568 | (defn pagination-examples
569 | "Bootstrap pagination component examples"
570 | [basic-key smart-key]
571 | [:div
572 | [rbs/page-header "Pagination " [:small [:code "pagination"]]]
573 | [:h3 "Basic example"]
574 | (for [val (map-indexed vector ["large" "medium" "small"])]
575 | (let [size (last val)]
576 | [:div
577 | [rbs/pagination {:bs-size size
578 | :items 10
579 | :active-page basic-key
580 | :on-select #(re-frame/dispatch [:set-bootstrap-pagination-basic (aget %2 "eventKey")])}]]))
581 | [:h3 "Smart example"]
582 | (for [val (map-indexed vector ["large" "medium" "small"])]
583 | (let [size (last val)]
584 | [:div
585 | [rbs/pagination {:bs-size size
586 | :prev true
587 | :next true
588 | :first true
589 | :last true
590 | :ellipsis true
591 | :boundary-links true
592 | :items 20
593 | :max-buttons 5
594 | :active-page smart-key
595 | :on-select #(re-frame/dispatch [:set-bootstrap-pagination-smart (aget %2 "eventKey")])}]]))])
596 |
597 |
598 | (defn pager-examples
599 | "Bootstrap pager component examples"
600 | [wired-key]
601 | [:div
602 | [rbs/page-header "Pager " [:small [:code "pager"]]]
603 | [:h3 "Centers by default"]
604 | [rbs/pager
605 | [rbs/page-item {:href "#"} "Previous"]
606 | [rbs/page-item {:href "#"} "Next"]]
607 | [:h3 "Previous and next"]
608 | [rbs/pager
609 | [rbs/page-item {:href "#"
610 | :previous true} "Previous"]
611 | [rbs/page-item {:href "#"
612 | :next true} "Next"]]
613 | [:h3 "Disabled"]
614 | [rbs/pager
615 | [rbs/page-item {:href "#"
616 | :previous true
617 | :disabled true} "Previous"]
618 | [rbs/page-item {:href "#"
619 | :next true
620 | :disabled true} "Next"]]
621 | [:h3 "Wired"]
622 | (if (= wired-key 1)
623 | [rbs/well [:p "First page content"]]
624 | [rbs/well [:p "Second page content"]])
625 | [rbs/pager {:on-select #(re-frame/dispatch [:set-bootstrap-pager-wired %])}
626 | [rbs/page-item {:href "#"
627 | :event-key 1
628 | :previous true
629 | :disabled (= wired-key 1)} "Previous"]
630 | [rbs/page-item {:href "#"
631 | :event-key 2
632 | :next true
633 | :disabled (= wired-key 2)} "Next"]]])
634 |
635 |
636 | (defn grid-examples
637 | "Bootstrap grid component examples"
638 | []
639 | [:div
640 | [rbs/page-header "Grid " [:small [:code "grid"] [:code "row"] [:code "col"]]]
641 | [:h3 "Grid example"]
642 | [rbs/grid
643 | [rbs/row {:class "show-grid"}
644 | [rbs/col {:xs 12 :md 8} "{:xs 12 :md 8}"]
645 | [rbs/col {:xs 6 :md 4} "{:xs 6 :md 4}"]]
646 | [rbs/row {:class "show-grid"}
647 | [rbs/col {:xs 6 :md 4} "{:xs 6 :md 4}"]
648 | [rbs/col {:xs 6 :md 4} "{:xs 6 :md 4}"]
649 | [rbs/col {:xs-hidden true :md 4} "{:xs-hidden true :md 4}"]]
650 | [rbs/row {:class "show-grid"}
651 | [rbs/col {:xs 6 :xs-offset 6} "{:xs 6 :xs-offset 6}"]]
652 | [rbs/row {:class "show-grid"}
653 | [rbs/col {:md 6 :md-push 6} "{:md 6 :md-push 6}"]
654 | [rbs/col {:md 6 :md-pull 6} "{:md 6 :md-pull 6}"]]]])
655 |
656 |
657 | (defn jumbotron-examples
658 | "Bootstrap jumbotron component examples"
659 | []
660 | [:div
661 | [rbs/page-header "Jumbotron " [:small [:code "jumbotron"]]]
662 | [rbs/jumbotron
663 | [:h1 "Hello, CLJS!"]
664 | [:p "This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information."]
665 | [rbs/button {:bs-style "primary"} "Learn more"]]])
666 |
667 |
668 | (defn page-header-examples
669 | "Bootstrap page header component examples"
670 | []
671 | [:div
672 | [rbs/page-header "Page header " [:small [:code "page-header"]]]
673 | [:div {:class "page-header-contained"}
674 | [rbs/page-header "Example page header " [:small "Subtext for header"]]]])
675 |
676 |
677 | (defn list-group-examples
678 | "Bootstrap list group component examples"
679 | []
680 | [:div
681 | [rbs/page-header "List group " [:small [:code "list-group"]]]
682 | [:h3 "Centers by default"]
683 | [rbs/list-group
684 | [rbs/list-group-item {:href "#"} "Link 1"]
685 | [rbs/list-group-item {:href "#"} "Link 2"]]
686 | [:h3 "Linked"]
687 | [rbs/list-group
688 | [rbs/list-group-item {:href "/home"} "Home link"]
689 | [rbs/list-group-item {:on-click #(js/alert "Hello from CLJS!")} "Alert link"]]
690 | [:h3 "Styling by state"]
691 | [rbs/list-group
692 | [rbs/list-group-item {:href "#"
693 | :active true} "Link 1"]
694 | [rbs/list-group-item {:href "#"} "Link 2"]
695 | [rbs/list-group-item {:href "#"
696 | :disabled true} "Link 3"]]
697 | [:h3 "Styling by color"]
698 | [rbs/list-group
699 | (for [val (map-indexed vector ["success" "info" "warning" "danger"])]
700 | (let [style (last val)
701 | name (clojure.string/capitalize (last val))]
702 | [rbs/list-group-item {:href "#"
703 | :bs-style style} (clojure.string/join [name " link"])]))]
704 | [:h3 "With header"]
705 | [rbs/list-group
706 | [rbs/list-group-item {:href "#"
707 | :header "Header 1"
708 | :active true} "Link 1"]
709 | [rbs/list-group-item {:href "#"
710 | :header "Header 2"} "Link 2"]
711 | [rbs/list-group-item {:href "#"
712 | :header "Header 3"
713 | :disabled true} "Link 3"]]
714 | [:h3 "With custom component children"]
715 | [rbs/list-group
716 | (for [index (range 1 4)]
717 | (let [name (clojure.string/join ["Component name " index])
718 | message (clojure.string/join ["Hello from " name])]
719 | [rbs/list-group-item
720 | [(fn []
721 | [rbs/button {:on-click #(js/alert message)} name])]]))]])
722 |
723 |
724 | (defn tables-examples
725 | "Bootstrap tables component examples"
726 | []
727 | [:div
728 | [rbs/page-header "Tables " [:small [:code "table"]]]
729 | [:h3 "Common example"]
730 | [rbs/table {:striped true
731 | :bordered true
732 | :condensed true
733 | :hover true}
734 | [:thead
735 | [:tr
736 | [:th "#"]
737 | [:th "First Name"]
738 | [:th "Last Name"]
739 | [:th "Username"]]]
740 | [:tbody
741 | [:tr
742 | [:td "1"]
743 | [:td "Justin"]
744 | [:td "Firth"]
745 | [:td "@justinfirth"]]
746 | [:tr
747 | [:td "2"]
748 | [:td "John"]
749 | [:td "Doe"]
750 | [:td "@johndoe"]]
751 | [:tr
752 | [:td "3"]
753 | [:td {:col-span 2} "Frank the Tank"]
754 | [:td "@frankthetank"]]]]
755 | [:h3 "Responsive example"]
756 | [rbs/table {:responsive true}
757 | [:thead
758 | [:tr
759 | [:th "#"]
760 | [:th "Table heading"]
761 | [:th "Table heading"]
762 | [:th "Table heading"]
763 | [:th "Table heading"]
764 | [:th "Table heading"]
765 | [:th "Table heading"]]]
766 | [:tbody
767 | (for [index (range 1 6)]
768 | [:tr
769 | [:td index]
770 | [:td "Table cell"]
771 | [:td "Table cell"]
772 | [:td "Table cell"]
773 | [:td "Table cell"]
774 | [:td "Table cell"]
775 | [:td "Table cell"]])]]])
776 |
777 |
778 | (defn panels-examples
779 | "Bootstrap panels component examples"
780 | []
781 | [:div
782 | [rbs/page-header "Panels " [:small [:code "panel"]]]])
783 |
784 |
785 | (defn wells-examples
786 | "Bootstrap well component examples"
787 | []
788 | [:div
789 | [rbs/page-header "Wells " [:small [:code "well"]]]])
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/components/example.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.components.example
2 | (:require [reagent.core :as reagent]
3 | [re-frame.core :as re-frame]))
4 |
5 | ;; -------------------------
6 | ;; Counter component examples
7 |
8 |
9 | ;;; an example of a full React counter component using
10 | ;;; normal life-cycle methods
11 | (defn counter-class [count]
12 | (reagent/create-class
13 | {:display-name "counter-class"
14 | :component-will-mount #(do
15 | (print "counter-class: will mount")
16 | #_(re-frame/dispatch [:reset-counter]))
17 | :component-did-mount #(print "counter-class: did mount")
18 | :reagent-render
19 | (fn [count]
20 | [:div.counter
21 | [:div count]
22 | [:button.btn.btn-default
23 | {:type "button"
24 | :on-click #(re-frame/dispatch [:reset-counter])}
25 | "Reset"]
26 | [:button.btn.btn-default
27 | {:type "button"
28 | :on-click #(re-frame/dispatch [:increment-counter])}
29 | "Increment"]
30 | [:button.btn.btn-default
31 | {:type "button"
32 | :on-click #(re-frame/dispatch [:decrement-counter])}
33 | "Decrement"]])}))
34 |
35 |
36 |
37 | ;;; a presentation example of a counter component
38 | (defn base-counter [count]
39 | [:div.counter
40 | [:div count]
41 | [:button.btn.btn-default
42 | {:type "button"
43 | :on-click #(re-frame/dispatch [:reset-counter])}
44 | "Reset"]
45 | [:button.btn.btn-default
46 | {:type "button"
47 | :on-click #(re-frame/dispatch [:increment-counter])}
48 | "Increment"]
49 | [:button.btn.btn-default
50 | {:type "button"
51 | :on-click #(re-frame/dispatch [:decrement-counter])}
52 | "Decrement"]])
53 |
54 |
55 | ;;; extending presentation example with life cycle methods
56 | (def resetting-counter
57 | (with-meta base-counter
58 | {:component-will-mount #(do
59 | (print "counter-class: will mount")
60 | #_(re-frame/dispatch [:reset-counter]))
61 | :component-did-mount #(print "resetting-counter: did mount")}))
62 |
63 |
64 | ;; -------------------------
65 | ;; Timer component
66 |
67 | ;; (defn timer-component []
68 | ;; (let [seconds-elapsed 0]
69 | ;; (fn []
70 | ;; (js/setTimeout #(swap! seconds-elapsed inc) 1000)
71 | ;; [:div "Seconds Elapsed: " @seconds-elapsed])))
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/components/site.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.components.site
2 | (:require [cljs-react-bootstrap.react-bootstrap.core :as rbs]
3 | [cljs-react-bootstrap.react-bootstrap.navbar :as rbs-navbar]
4 | [cljs-react-bootstrap.react-bootstrap.modal :as rbs-modal]
5 | [re-frame.core :as re-frame]))
6 |
7 |
8 | (defn navbar
9 | "Site navigation component"
10 | [brand links]
11 | [rbs/navbar {:static-top true
12 | :fluid true}
13 | [rbs-navbar/toggle]
14 | [rbs-navbar/brand [:a {:href "/"} brand]]
15 | [rbs-navbar/collapse
16 | [rbs/nav {:className "navbar-nav"}
17 | (for [link links]
18 | [rbs/nav-item {:href (link :url)} (link :name)])]
19 | [rbs/nav {:className "navbar-nav" :pull-right true}
20 | [rbs/nav-item {:href "#"
21 | :on-click #(re-frame/dispatch [:toggle-login])}
22 | [rbs/glyphicon {:glyph "user"}]]
23 | [rbs/nav-item {:href "#"
24 | :on-click #(re-frame/dispatch [:toggle-sidebar])}
25 | [rbs/glyphicon {:glyph "align-justify"}]]]]])
26 |
27 |
28 | (defn header
29 | "Site header component"
30 | []
31 | (let [brand "CLJS"
32 | links [{:name "About" :url "/about"}
33 | {:name "Bootstrap" :url "/bootstrap"}
34 | {:name "Example" :url "/example"}
35 | {:name "Test" :url "/test"}]]
36 | [navbar brand links]))
37 |
38 |
39 | ;; TODO: possibly turn into page-specific sidebar instead
40 | (defn sidebar
41 | "Site sidebar component"
42 | []
43 | [:div.sidebar
44 | [:div.sidebar-section
45 | [:h4 "Section"]
46 | [:ul
47 | [:li "One"]
48 | [:li "Two"]
49 | [:li "Three"]]]])
50 |
51 |
52 | (defn sign-in
53 | "Site sign-in modal component"
54 | []
55 | [rbs-modal/dialog {:bs-size "small"}
56 | [rbs-modal/header
57 | [rbs/glyphicon {:glyph "user"}]
58 | [:span " Sign In"]]
59 | [rbs-modal/body
60 | [:form
61 | [rbs/input
62 | {:type "email"
63 | :label "Email Address"
64 | :placeholder "Enter email"}]
65 | [rbs/input
66 | {:type "password"
67 | :label "Password"}]]]
68 | [rbs-modal/footer
69 | [rbs/button {:type "button"
70 | :bs-style "default"
71 | :on-click #(re-frame/dispatch [:toggle-login])} "Cancel"]
72 | [rbs/button {:type "button"
73 | :bs-style "primary"
74 | :on-click #(re-frame/dispatch [:toggle-login])} "Sign In"]]])
75 |
76 |
77 | (defn footer
78 | "Site footer component"
79 | []
80 | [:footer
81 | [:div.text-center "Copyright © 2016, Software Engineer."]])
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/config.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.config)
2 |
3 | (def debug?
4 | ^boolean js/goog.DEBUG)
5 |
6 | (when debug?
7 | (enable-console-print!))
8 |
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/core.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.core
2 | (:require [reagent.core :as reagent]
3 | [reagent.session :as session]
4 | [re-frame.core :as re-frame]
5 | [secretary.core :as secretary :include-macros true]
6 | [accountant.core :as accountant]
7 | [cljsjs.react-bootstrap]
8 | [cljs-react-bootstrap.handlers]
9 | [cljs-react-bootstrap.subs]
10 | [cljs-react-bootstrap.views :as views]
11 | [cljs-react-bootstrap.config :as config]
12 | [cljs-react-bootstrap.layout :as layout]))
13 |
14 |
15 | (when config/debug?
16 | (println "dev mode"))
17 |
18 |
19 | ;; -------------------------
20 | ;; Session
21 |
22 |
23 | (defn current-page []
24 | [(session/get :current-page) (session/get :params)])
25 |
26 |
27 | ;; (defn current-page []
28 | ;; [:div [(session/get :current-page)]])
29 |
30 |
31 | ;; -------------------------
32 | ;; Routes
33 |
34 |
35 | (secretary/defroute "/" []
36 | (session/put! :current-page #'views/home-page))
37 |
38 |
39 | (secretary/defroute "/about" []
40 | (session/put! :current-page #'views/about-page))
41 |
42 |
43 | (secretary/defroute "/bootstrap" []
44 | (session/put! :current-page #'views/bootstrap-page))
45 |
46 |
47 | (secretary/defroute "/example" []
48 | (session/put! :current-page #'views/example-page))
49 |
50 |
51 | (secretary/defroute "/test" []
52 | (session/put! :current-page #'views/test-page))
53 |
54 |
55 | ;; -------------------------
56 | ;; Bootstrap
57 |
58 |
59 | (defn mount-root []
60 | (reagent/render
61 | [layout/main-layout [current-page]]
62 | (.getElementById js/document "app")))
63 |
64 |
65 | (defn ^:export init []
66 | (re-frame/dispatch-sync [:initialize-db])
67 | (accountant/configure-navigation!)
68 | (accountant/dispatch-current!)
69 | (mount-root))
70 |
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/db.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.db)
2 |
3 |
4 | (def default-db
5 | ;; https://github.com/Day8/re-frame
6 | ;; The Big Ratom
7 | {:show-sidebar false
8 | :show-login false
9 |
10 | ;; home page state
11 | :home-page {}
12 |
13 | ;; about page state
14 | :about-page {}
15 |
16 | ;; bootstrap page state
17 | :bootstrap-page
18 | {:show-basic-modal false
19 | :nav-basic-key 1
20 | :nav-dropdown-key 1
21 | :nav-stacked-key 1
22 | :nav-justified-key 1
23 | :navbar-basic-key 1
24 | :navbar-responsive-key 1
25 | :tabs-controlled-key 1
26 | :tabs-no-animation-key 1
27 | :tabs-left-tabs-key 1
28 | :tabs-pills-key 1
29 | :tabs-left-pills-key 1
30 | :pagination-basic-key 1
31 | :pagination-smart-key 1
32 | :pager-wired-key 1}
33 |
34 | ;; example page state
35 | :example-page {}
36 |
37 | ;; test page state
38 | :test-page
39 | {:timer {:seconds-elapsed 0}
40 | :input ""}})
41 |
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/handlers.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.handlers
2 | (:require [re-frame.core :as re-frame]
3 | [cljs-react-bootstrap.db :as db]))
4 |
5 |
6 | (re-frame/register-handler
7 | :initialize-db
8 | (fn [_ _]
9 | db/default-db))
10 |
11 |
12 | (re-frame/register-handler
13 | :toggle-sidebar
14 | (fn [db]
15 | (update-in db [:show-sidebar] not)))
16 |
17 |
18 | (re-frame/register-handler
19 | :toggle-login
20 | (fn [db]
21 | (update-in db [:show-login] not)))
22 |
23 |
24 | (re-frame/register-handler
25 | :toggle-bootstrap-basic-modal
26 | (fn [db]
27 | (update-in db [:bootstrap-page :basic-modal-visible] not)))
28 |
29 |
30 | (re-frame/register-handler
31 | :set-bootstrap-nav-basic
32 | (fn [db [_ val]]
33 | (update-in db [:bootstrap-page :nav-basic-key] (fn [] val))))
34 |
35 |
36 | (re-frame/register-handler
37 | :set-bootstrap-nav-dropdown
38 | (fn [db [_ val]]
39 | (update-in db [:bootstrap-page :nav-dropdown-key] (fn [] val))))
40 |
41 |
42 | (re-frame/register-handler
43 | :set-bootstrap-nav-stacked
44 | (fn [db [_ val]]
45 | (update-in db [:bootstrap-page :nav-stacked-key] (fn [] val))))
46 |
47 |
48 | (re-frame/register-handler
49 | :set-bootstrap-nav-justified
50 | (fn [db [_ val]]
51 | (update-in db [:bootstrap-page :nav-justified-key] (fn [] val))))
52 |
53 |
54 | (re-frame/register-handler
55 | :set-bootstrap-navbar-basic
56 | (fn [db [_ val]]
57 | (update-in db [:bootstrap-page :navbar-basic-key] (fn [] val))))
58 |
59 |
60 | (re-frame/register-handler
61 | :set-bootstrap-navbar-responsive
62 | (fn [db [_ val]]
63 | (update-in db [:bootstrap-page :navbar-responsive-key] (fn [] val))))
64 |
65 |
66 | (re-frame/register-handler
67 | :set-bootstrap-tabs-controlled
68 | (fn [db [_ val]]
69 | (update-in db [:bootstrap-page :tabs-controlled-key] (fn [] val))))
70 |
71 |
72 | (re-frame/register-handler
73 | :set-bootstrap-tabs-no-animation
74 | (fn [db [_ val]]
75 | (update-in db [:bootstrap-page :tabs-no-animation-key] (fn [] val))))
76 |
77 |
78 | (re-frame/register-handler
79 | :set-bootstrap-tabs-left-tabs
80 | (fn [db [_ val]]
81 | (update-in db [:bootstrap-page :tabs-left-tabs-key] (fn [] val))))
82 |
83 |
84 | (re-frame/register-handler
85 | :set-bootstrap-tabs-pills
86 | (fn [db [_ val]]
87 | (update-in db [:bootstrap-page :tabs-pills-key] (fn [] val))))
88 |
89 |
90 | (re-frame/register-handler
91 | :set-bootstrap-tabs-left-pills
92 | (fn [db [_ val]]
93 | (update-in db [:bootstrap-page :tabs-left-pills-key] (fn [] val))))
94 |
95 |
96 | (re-frame/register-handler
97 | :set-bootstrap-pagination-basic
98 | (fn [db [_ val]]
99 | (update-in db [:bootstrap-page :pagination-basic-key] (fn [] val))))
100 |
101 |
102 | (re-frame/register-handler
103 | :set-bootstrap-pagination-smart
104 | (fn [db [_ val]]
105 | (update-in db [:bootstrap-page :pagination-smart-key] (fn [] val))))
106 |
107 |
108 | (re-frame/register-handler
109 | :set-bootstrap-pager-wired
110 | (fn [db [_ val]]
111 | (update-in db [:bootstrap-page :pager-wired-key] (fn [] val))))
112 |
113 |
114 | ;(re-frame/register-handler
115 | ; :reset-counter
116 | ; (fn [db]
117 | ; (update-in db [:counter-page :counter] (fn [_] 0))))
118 | ;
119 | ;(re-frame/register-handler
120 | ; :increment-counter
121 | ; (fn [db]
122 | ; (update-in db [:counter-page :counter] inc)))
123 | ;
124 | ;(re-frame/register-handler
125 | ; :decrement-counter
126 | ; (fn [db]
127 | ; (update-in db [:counter-page :counter] dec)))
128 |
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/layout.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.layout
2 | (:require [re-frame.core :as re-frame]
3 | [cljs-react-bootstrap.react-bootstrap.core :as rbs]
4 | [cljs-react-bootstrap.components.site :as site]))
5 |
6 |
7 | (defn full-layout [view]
8 | [rbs/row
9 | [rbs/col {:xs 12} view]])
10 |
11 |
12 | (defn sidebar-layout [view sidebar]
13 | [rbs/row
14 | [rbs/col {:xs 8} view]
15 | [rbs/col {:xs 3 :xs-offset 1} [sidebar]]])
16 |
17 |
18 | (defn main-layout [view]
19 | (let [show-sidebar (re-frame/subscribe [:show-sidebar])
20 | show-login (re-frame/subscribe [:show-login])]
21 | (fn []
22 | [:div
23 | [site/header]
24 | (if (= @show-login true)
25 | [site/sign-in])
26 | [rbs/grid
27 | (if (= @show-sidebar false)
28 | [full-layout view]
29 | [sidebar-layout view site/sidebar])]
30 | [site/footer]])))
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/react-bootstrap/core.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.react-bootstrap.core
2 | (:require [cljsjs.react-bootstrap]
3 | [reagent.core :as reagent]))
4 |
5 | (def accordion (reagent/adapt-react-class (aget js/ReactBootstrap "Accordion")))
6 | (def alert (reagent/adapt-react-class (aget js/ReactBootstrap "Alert")))
7 | (def badge (reagent/adapt-react-class (aget js/ReactBootstrap "Badge")))
8 | (def breadcrumb (reagent/adapt-react-class (aget js/ReactBootstrap "Breadcrumb")))
9 | (def breadcrumb-item (reagent/adapt-react-class (aget js/ReactBootstrap "BreadcrumbItem")))
10 | (def button (reagent/adapt-react-class (aget js/ReactBootstrap "Button")))
11 | (def button-group (reagent/adapt-react-class (aget js/ReactBootstrap "ButtonGroup")))
12 | (def button-input (reagent/adapt-react-class (aget js/ReactBootstrap "ButtonInput")))
13 | (def button-toolbar (reagent/adapt-react-class (aget js/ReactBootstrap "ButtonToolbar")))
14 | (def carousel (reagent/adapt-react-class (aget js/ReactBootstrap "Carousel")))
15 | (def carousel-item (reagent/adapt-react-class (aget js/ReactBootstrap "CarouselItem")))
16 | (def col (reagent/adapt-react-class (aget js/ReactBootstrap "Col")))
17 | (def collapsible-nav (reagent/adapt-react-class (aget js/ReactBootstrap "CollapsibleNav")))
18 | (def dropdown (reagent/adapt-react-class (aget js/ReactBootstrap "Dropdown")))
19 | (def dropdown-button (reagent/adapt-react-class (aget js/ReactBootstrap "DropdownButton")))
20 | (def glyphicon (reagent/adapt-react-class (aget js/ReactBootstrap "Glyphicon")))
21 | (def grid (reagent/adapt-react-class (aget js/ReactBootstrap "Grid")))
22 | (def image (reagent/adapt-react-class (aget js/ReactBootstrap "Image")))
23 | (def input (reagent/adapt-react-class (aget js/ReactBootstrap "Input")))
24 | (def interpolate (reagent/adapt-react-class (aget js/ReactBootstrap "Interpolate")))
25 | (def jumbotron (reagent/adapt-react-class (aget js/ReactBootstrap "Jumbotron")))
26 | (def label (reagent/adapt-react-class (aget js/ReactBootstrap "Label")))
27 | (def list-group (reagent/adapt-react-class (aget js/ReactBootstrap "ListGroup")))
28 | (def list-group-item (reagent/adapt-react-class (aget js/ReactBootstrap "ListGroupItem")))
29 | (def menu-item (reagent/adapt-react-class (aget js/ReactBootstrap "MenuItem")))
30 | (def modal (reagent/adapt-react-class (aget js/ReactBootstrap "Modal")))
31 | (def modal-body (reagent/adapt-react-class (aget js/ReactBootstrap "ModalBody")))
32 | (def modal-footer (reagent/adapt-react-class (aget js/ReactBootstrap "ModalFooter")))
33 | (def modal-header (reagent/adapt-react-class (aget js/ReactBootstrap "ModalHeader")))
34 | (def modal-title (reagent/adapt-react-class (aget js/ReactBootstrap "ModalTitle")))
35 | (def nav (reagent/adapt-react-class (aget js/ReactBootstrap "Nav")))
36 | (def navbar (reagent/adapt-react-class (aget js/ReactBootstrap "Navbar")))
37 | (def nav-brand (reagent/adapt-react-class (aget js/ReactBootstrap "NavBrand")))
38 | (def navbar-brand (reagent/adapt-react-class (aget js/ReactBootstrap "NavbarBrand")))
39 | (def nav-dropdown (reagent/adapt-react-class (aget js/ReactBootstrap "NavDropdown")))
40 | (def nav-item (reagent/adapt-react-class (aget js/ReactBootstrap "NavItem")))
41 | (def overlay (reagent/adapt-react-class (aget js/ReactBootstrap "Overlay")))
42 | (def overlay-trigger (reagent/adapt-react-class (aget js/ReactBootstrap "OverlayTrigger")))
43 | (def page-header (reagent/adapt-react-class (aget js/ReactBootstrap "PageHeader")))
44 | (def page-item (reagent/adapt-react-class (aget js/ReactBootstrap "PageItem")))
45 | (def pager (reagent/adapt-react-class (aget js/ReactBootstrap "Pager")))
46 | (def pagination (reagent/adapt-react-class (aget js/ReactBootstrap "Pagination")))
47 | (def panel (reagent/adapt-react-class (aget js/ReactBootstrap "Panel")))
48 | (def panel-group (reagent/adapt-react-class (aget js/ReactBootstrap "PanelGroup")))
49 | (def popover (reagent/adapt-react-class (aget js/ReactBootstrap "Popover")))
50 | (def progress-bar (reagent/adapt-react-class (aget js/ReactBootstrap "ProgressBar")))
51 | (def responsive-embed (reagent/adapt-react-class (aget js/ReactBootstrap "ResponsiveEmbed")))
52 | (def row (reagent/adapt-react-class (aget js/ReactBootstrap "Row")))
53 | (def safe-anchor (reagent/adapt-react-class (aget js/ReactBootstrap "SafeAnchor")))
54 | (def split-button (reagent/adapt-react-class (aget js/ReactBootstrap "SplitButton")))
55 | (def tab (reagent/adapt-react-class (aget js/ReactBootstrap "Tab")))
56 | (def table (reagent/adapt-react-class (aget js/ReactBootstrap "Table")))
57 | (def tabs (reagent/adapt-react-class (aget js/ReactBootstrap "Tabs")))
58 | (def thumbnail (reagent/adapt-react-class (aget js/ReactBootstrap "Thumbnail")))
59 | (def tooltip (reagent/adapt-react-class (aget js/ReactBootstrap "Tooltip")))
60 | (def well (reagent/adapt-react-class (aget js/ReactBootstrap "Well")))
61 | (def collapse (reagent/adapt-react-class (aget js/ReactBootstrap "Collapse")))
62 | (def fade (reagent/adapt-react-class (aget js/ReactBootstrap "Fade")))
63 |
64 |
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/react-bootstrap/dropdown.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.react-bootstrap.dropdown
2 | (:require [cljsjs.react-bootstrap]
3 | [reagent.core :as reagent]))
4 |
5 | (def menu (reagent/adapt-react-class (aget js/ReactBootstrap.Dropdown "Menu")))
6 | (def toggle (reagent/adapt-react-class (aget js/ReactBootstrap.Dropdown "Toggle")))
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/react-bootstrap/input.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.react-bootstrap.input
2 | (:require [cljsjs.react-bootstrap]
3 | [reagent.core :as reagent]))
4 |
5 | (def get-checked (reagent/adapt-react-class (aget js/ReactBootstrap.Input "getChecked")))
6 | (def get-input-dom-node (reagent/adapt-react-class (aget js/ReactBootstrap.Input "getInputDOMNode")))
7 | (def get-value (reagent/adapt-react-class (aget js/ReactBootstrap.Input "getValue")))
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/react-bootstrap/modal.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.react-bootstrap.modal
2 | (:require [cljsjs.react-bootstrap]
3 | [reagent.core :as reagent]))
4 |
5 | (def body (reagent/adapt-react-class (aget js/ReactBootstrap.Modal "Body")))
6 | (def dialog (reagent/adapt-react-class (aget js/ReactBootstrap.Modal "Dialog")))
7 | (def footer (reagent/adapt-react-class (aget js/ReactBootstrap.Modal"Footer")))
8 | (def header (reagent/adapt-react-class (aget js/ReactBootstrap.Modal "Header")))
9 | (def title (reagent/adapt-react-class (aget js/ReactBootstrap.Modal "Title")))
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/react-bootstrap/navbar.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.react-bootstrap.navbar
2 | (:require [cljsjs.react-bootstrap]
3 | [reagent.core :as reagent]))
4 |
5 | (def header (reagent/adapt-react-class (aget js/ReactBootstrap.Navbar "Header")))
6 | (def toggle (reagent/adapt-react-class (aget js/ReactBootstrap.Navbar "Toggle")))
7 | (def collapse (reagent/adapt-react-class (aget js/ReactBootstrap.Navbar "Collapse")))
8 | (def brand (reagent/adapt-react-class (aget js/ReactBootstrap.Navbar "Brand")))
9 | (def link (reagent/adapt-react-class (aget js/ReactBootstrap.Navbar "Link")))
10 | (def text (reagent/adapt-react-class (aget js/ReactBootstrap.Navbar "Text")))
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/react-bootstrap/split-button.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.react-bootstrap.split-button
2 | (:require [cljsjs.react-bootstrap]
3 | [reagent.core :as reagent]))
4 |
5 | (def toggle (reagent/adapt-react-class (aget js/ReactBootstrap.SplitButton "Toggle")))
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/subs.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.subs
2 | (:require-macros [reagent.ratom :refer [reaction]])
3 | (:require [re-frame.core :as re-frame]))
4 |
5 |
6 | ;; -------------------------
7 | ;; Layout-level state subscriptions
8 |
9 | (re-frame/register-sub
10 | :show-sidebar
11 | (fn [db]
12 | (reaction (:show-sidebar @db))))
13 |
14 |
15 | (re-frame/register-sub
16 | :show-login
17 | (fn [db]
18 | (reaction (:show-login @db))))
19 |
20 |
21 | ;; -------------------------
22 | ;; Page-level state subscriptions
23 |
24 |
25 | (re-frame/register-sub
26 | :home-page
27 | (fn [db]
28 | (reaction (:home-page @db))))
29 |
30 |
31 | (re-frame/register-sub
32 | :about-page
33 | (fn [db]
34 | (reaction (:about-page @db))))
35 |
36 |
37 | (re-frame/register-sub
38 | :bootstrap-page
39 | (fn [db]
40 | (reaction (:bootstrap-page @db))))
41 |
42 |
43 | (re-frame/register-sub
44 | :example-page
45 | (fn [db]
46 | (reaction (:example-page @db))))
47 |
48 |
49 | (re-frame/register-sub
50 | :test-page
51 | (fn [db]
52 | (reaction (:test-page @db))))
53 |
--------------------------------------------------------------------------------
/src/cljs/cljs-react-bootstrap/views.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-bootstrap.views
2 | (:require [re-frame.core :as re-frame]
3 | [cljs-react-bootstrap.react-bootstrap.core :as rbs]
4 | [cljs-react-bootstrap.components.bootstrap-page :as bootstrap-page]))
5 |
6 |
7 | (defn home-page []
8 | (let [state (re-frame/subscribe [:home-page])]
9 | [:div
10 | [rbs/jumbotron
11 | [:h1 "Hello, CLJS!"]
12 | [:p "A ClojureScript example single-page application."]]
13 | [:p "This is an example single-page application made with Clojure/ClojureScript using the reagent React wrapper and re-frame architecture, leveraging native React-Bootstrap components."]]))
14 |
15 |
16 | (defn about-page []
17 | (let [state (re-frame/subscribe [:about-page])]
18 | [:div
19 | [rbs/page-header
20 | "About "
21 | [:small "this app"]]
22 | [rbs/page-item "Item One"]]))
23 |
24 |
25 | (defn bootstrap-page
26 | "The bootstrap component example page"
27 | []
28 | (let [state (re-frame/subscribe [:bootstrap-page])]
29 | [:div
30 | [rbs/jumbotron
31 | [:h1 "React-Bootstrap"]
32 | [:p "A collection of React-Bootstrap component examples"]]
33 | [bootstrap-page/button-examples]
34 | [bootstrap-page/button-groups-examples]
35 | [bootstrap-page/dropdown-examples]
36 | [bootstrap-page/menu-items-examples]
37 | [bootstrap-page/modal-examples (@state :basic-modal-visible)]
38 | [bootstrap-page/tooltip-examples]
39 | [bootstrap-page/popover-examples]
40 | [bootstrap-page/nav-examples
41 | (@state :nav-basic-key)
42 | (@state :nav-dropdown-key)
43 | (@state :nav-stacked-key)
44 | (@state :nav-justified-key)]
45 | [bootstrap-page/navbar-examples
46 | (@state :navbar-basic-key)
47 | (@state :navbar-responsive-key)]
48 | [bootstrap-page/breadcrumb-examples]
49 | [bootstrap-page/tabs-examples
50 | (@state :tabs-controlled-key)
51 | (@state :tabs-no-animation-key)
52 | (@state :tabs-left-tabs-key)
53 | (@state :tabs-pills-key)
54 | (@state :tabs-left-pills-key)]
55 | [bootstrap-page/pagination-examples
56 | (@state :pagination-basic-key)
57 | (@state :pagination-smart-key)]
58 | [bootstrap-page/pager-examples
59 | (@state :pager-wired-key)]
60 | [bootstrap-page/grid-examples]
61 | [bootstrap-page/jumbotron-examples]
62 | [bootstrap-page/page-header-examples]
63 | [bootstrap-page/list-group-examples]
64 | [bootstrap-page/tables-examples]
65 | [bootstrap-page/panels-examples]
66 | [bootstrap-page/wells-examples]]))
67 |
68 |
69 | (defn example-page []
70 | (let [state (re-frame/subscribe [:example-page])]
71 | ))
72 |
73 |
74 | (defn test-page []
75 | (let [state (re-frame/subscribe [:test-page])]
76 | [:div#for-loop [:h1 "for-loop"]
77 | (for [x (range 1 10)]
78 | [:span x])]))
--------------------------------------------------------------------------------