swinging-needle-meter/resources/public/js/compiled/out/re_com/tabs.cljs
2020-10-20 14:44:11 +01:00

154 lines
6.5 KiB
Clojure

(ns re-com.tabs
(:require-macros [re-com.core :refer [handler-fn]])
(:require [re-com.util :refer [deref-or-value]]
[re-com.box :refer [flex-child-style]]
[re-com.validate :refer [css-style? vector-of-maps?] :refer-macros [validate-args-macro]]))
;;--------------------------------------------------------------------------------------------------
;; Component: horizontal-tabs
;;--------------------------------------------------------------------------------------------------
(def tabs-args-desc
[{:name :tabs :required true :type "vector of tabs | atom" :validate-fn vector-of-maps? :description "one element in the vector for each tab. Typically, each element is a map with :id and :label keys"}
{:name :model :required true :type "unique-id | atom" :description "the unique identifier of the currently selected tab"}
{:name :on-change :required true :type "unique-id -> nil" :validate-fn fn? :description "called when user alters the selection. Passed the unique identifier of the selection"}
{:name :id-fn :required false :default :id :type "tab -> anything" :validate-fn ifn? :description [:span "given an element of " [:code ":tabs"] ", returns its unique identifier (aka id)"]}
{:name :label-fn :required false :default :label :type "tab -> string | hiccup" :validate-fn ifn? :description [:span "given an element of " [:code ":tabs"] ", returns its displayable label"]}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override (for each individual tab rather than the container)"}])
(defn horizontal-tabs
[& {:keys [model tabs on-change id-fn label-fn style]
:or {id-fn :id label-fn :label}
:as args}]
{:pre [(validate-args-macro tabs-args-desc args "tabs")]}
(let [current (deref-or-value model)
tabs (deref-or-value tabs)
_ (assert (not-empty (filter #(= current (id-fn %)) tabs)) "model not found in tabs vector")]
[:ul
{:class "rc-tabs nav nav-tabs noselect"
:style (flex-child-style "none")}
(for [t tabs]
(let [id (id-fn t)
label (label-fn t)
selected? (= id current)] ;; must use current instead of @model to avoid reagent warnings
[:li
{:class (if selected? "active")
:key (str id)}
[:a
{:style (merge {:cursor "pointer"}
style)
:on-click (when on-change (handler-fn (on-change id)))}
label]]))]))
;;--------------------------------------------------------------------------------------------------
;; Component: horizontal-bar-tabs
;;--------------------------------------------------------------------------------------------------
(defn- bar-tabs
[& {:keys [model tabs on-change id-fn label-fn style vertical?]}]
(let [current (deref-or-value model)
tabs (deref-or-value tabs)
_ (assert (not-empty (filter #(= current (id-fn %)) tabs)) "model not found in tabs vector")]
[:div
{:class (str "rc-tabs noselect btn-group" (if vertical? "-vertical"))
:style (flex-child-style "none")}
(for [t tabs]
(let [id (id-fn t)
label (label-fn t)
selected? (= id current)] ;; must use current instead of @model to avoid reagent warnings
[:button
{:type "button"
:key (str id)
:class (str "btn btn-default " (if selected? "active"))
:style style
:on-click (when on-change (handler-fn (on-change id)))}
label]))]))
(defn horizontal-bar-tabs
[& {:keys [model tabs on-change id-fn label-fn style]
:or {id-fn :id label-fn :label}
:as args}]
{:pre [(validate-args-macro tabs-args-desc args "tabs")]}
(bar-tabs
:model model
:tabs tabs
:on-change on-change
:style style
:id-fn id-fn
:label-fn label-fn
:vertical? false))
(defn vertical-bar-tabs
[& {:keys [model tabs on-change id-fn label-fn style]
:or {id-fn :id label-fn :label}
:as args}]
{:pre [(validate-args-macro tabs-args-desc args "tabs")]}
(bar-tabs
:model model
:tabs tabs
:on-change on-change
:style style
:id-fn id-fn
:label-fn label-fn
:vertical? true))
;;--------------------------------------------------------------------------------------------------
;; Component: pill-tabs
;;--------------------------------------------------------------------------------------------------
(defn- pill-tabs ;; tabs-like in action
[& {:keys [model tabs on-change id-fn label-fn style vertical?]}]
(let [current (deref-or-value model)
tabs (deref-or-value tabs)
_ (assert (not-empty (filter #(= current (id-fn %)) tabs)) "model not found in tabs vector")]
[:ul
{:class (str "rc-tabs noselect nav nav-pills" (when vertical? " nav-stacked"))
:style (flex-child-style "none")
:role "tabslist"}
(for [t tabs]
(let [id (id-fn t)
label (label-fn t)
selected? (= id current)] ;; must use 'current' instead of @model to avoid reagent warnings
[:li
{:class (if selected? "active" "")
:key (str id)}
[:a
{:style (merge {:cursor "pointer"}
style)
:on-click (when on-change (handler-fn (on-change id)))}
label]]))]))
(defn horizontal-pill-tabs
[& {:keys [model tabs on-change id-fn style label-fn]
:or {id-fn :id label-fn :label}
:as args}]
{:pre [(validate-args-macro tabs-args-desc args "tabs")]}
(pill-tabs
:model model
:tabs tabs
:on-change on-change
:style style
:id-fn id-fn
:label-fn label-fn
:vertical? false))
(defn vertical-pill-tabs
[& {:keys [model tabs on-change id-fn style label-fn]
:or {id-fn :id label-fn :label}
:as args}]
{:pre [(validate-args-macro tabs-args-desc args "tabs")]}
(pill-tabs
:model model
:tabs tabs
:on-change on-change
:style style
:id-fn id-fn
:label-fn label-fn
:vertical? true))