├── .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])])) --------------------------------------------------------------------------------