From 024b0547eafdbef131deb2d5e303c30c6823625a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20Schl=C3=BCter?= Date: Wed, 30 Jan 2019 16:28:42 +0100 Subject: [PATCH] Add bulma modal component --- src/cljs/bulma/modal/events.cljs | 12 ++++++++ src/cljs/bulma/modal/subs.cljs | 19 +++++++++++++ src/cljs/bulma/modal/views.cljs | 47 ++++++++++++++++++++++++++++++++ test/cljs/bulma/modal_test.cljs | 28 +++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 src/cljs/bulma/modal/events.cljs create mode 100644 src/cljs/bulma/modal/subs.cljs create mode 100644 src/cljs/bulma/modal/views.cljs create mode 100644 test/cljs/bulma/modal_test.cljs diff --git a/src/cljs/bulma/modal/events.cljs b/src/cljs/bulma/modal/events.cljs new file mode 100644 index 0000000..b2d75d9 --- /dev/null +++ b/src/cljs/bulma/modal/events.cljs @@ -0,0 +1,12 @@ +(ns bulma.modal.events + (:require [re-frame.core :as rf])) + +(defn show-modal [db [_ modal-id]] + (assoc-in db [:bulma :visible-modal] modal-id)) + +(rf/reg-event-db ::show show-modal) + +(defn hide-modal [db _] + (update db :bulma dissoc :visible-modal)) + +(rf/reg-event-db ::hide hide-modal) diff --git a/src/cljs/bulma/modal/subs.cljs b/src/cljs/bulma/modal/subs.cljs new file mode 100644 index 0000000..291f016 --- /dev/null +++ b/src/cljs/bulma/modal/subs.cljs @@ -0,0 +1,19 @@ +(ns bulma.modal.subs + (:require [re-frame.core :as rf])) + +(defn visible-modal + "Gives us the ID of the currently visible modal" + [db _] + (get-in db [:bulma :visible-modal])) + +(rf/reg-sub ::visible-modal visible-modal) + +(defn visible? + "Predicate to check the visibility of a single modal" + [visible-modal [_ modal-id]] + (= visible-modal modal-id)) + +(rf/reg-sub + ::visible? + :<- [::visible-modal] + visible?) diff --git a/src/cljs/bulma/modal/views.cljs b/src/cljs/bulma/modal/views.cljs new file mode 100644 index 0000000..107048c --- /dev/null +++ b/src/cljs/bulma/modal/views.cljs @@ -0,0 +1,47 @@ +(ns bulma.modal.views + (:require [re-frame.core :as rf] + [bulma.modal.events :as ev] + [bulma.modal.subs :as sub])) + +(defn hide-modal [_] + (rf/dispatch [::ev/hide])) + +(defn modal + "Generic modal; arguments: + + options: + {:has-hide-button? boolean + :modal-id :some-identifier} + + & children" + [{:keys [has-hide-button? modal-id]} & children] + {:pre [(some? modal-id)]} + (let [visible? @(rf/subscribe [::sub/visible? modal-id]) + modal-tag (if visible? :div.modal.is-active :div.modal)] + [modal-tag + [:div.modal-background {:on-click hide-modal}] + (into [:div.modal-content] children) + (when has-hide-button? + [:button.modal-hide.is-large {:aria-label "hide" + :on-click hide-modal}])])) + +(defn modal-card + "A card modal that renders content on a background. Arguments: + + options: + {:title \"Title of the card\" + :foot [[:div \"An array of hiccup elements\"]] + :modal-id :some-identifier} + + & children" + [{:keys [title foot modal-id]} & children] + [modal {:has-hide-button? (not (some? title)) + :modal-id modal-id} + (when title + [:div.modal-card-head + [:p.modal-card-title title] + [:button.delete {:aria-label "hide" + :on-click hide-modal}]]) + (into [:section.modal-card-body] children) + (when foot + (into [:div.modal-card-foot] foot))]) diff --git a/test/cljs/bulma/modal_test.cljs b/test/cljs/bulma/modal_test.cljs new file mode 100644 index 0000000..0a85127 --- /dev/null +++ b/test/cljs/bulma/modal_test.cljs @@ -0,0 +1,28 @@ +(ns bulma.modal-test + (:require [cljs.test :refer-macros [deftest testing is]] + [bulma.modal.subs :as sub] + [bulma.modal.events :as ev])) + +(enable-console-print!) + +(deftest bulma-modals + (testing "Should create a collection of modals if there is none" + (let [new-db (ev/show-modal {} [::ev/show :some-modal-id])] + (is (= :some-modal-id (sub/visible-modal new-db [::sub/visible-modal]))))) + (testing "Should hide other modals when displaying a new one" + (let [modal-ids [:some-id-1 :some-id-2 :some-id-3] + new-db (reduce (fn [db modal-id] + (ev/show-modal db [::ev/show modal-id])) + {} modal-ids)] + (is (= :some-id-3 (sub/visible-modal new-db [::sub/visible-modal]))))) + (testing "Should remove a modal from the collection when we hide it" + (let [modal-ids [:some-id-1 :some-id-2 :some-id-3] + new-db (-> (reduce (fn [db modal-id] + (ev/show-modal db [::ev/show modal-id])) + {} modal-ids) + (ev/hide-modal [::ev/hide]))] + (is (not (some? (sub/visible-modal new-db [::sub/visible-modal])))))) + (testing "Should tell us about the visibility of a modal with a predicate" + (is (-> (ev/show-modal {} [::ev/show :getting-repetitive]) + (sub/visible-modal [::sub/visible-modal]) + (sub/visible? [::sub/visible? :getting-repetitive])))))