Skip to content

Commit

Permalink
Refactor combo box to take dropdown panel as option
Browse files Browse the repository at this point in the history
  • Loading branch information
kelvinqian00 committed Oct 1, 2024
1 parent 3a28f07 commit 5d043b7
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 77 deletions.
80 changes: 39 additions & 41 deletions src/com/yetanalytics/lrs_admin_ui/views/form.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@
(:require [reagent.core :as r]
[com.yetanalytics.lrs-admin-ui.functions :as fns]
[com.yetanalytics.lrs-admin-ui.views.form.dropdown
:as form-drop
:refer [make-key-down-fn
select-input-top
dropdown-items
combo-box-dropdown]]
dropdown-items]]
[goog.string :refer [format]]
[goog.string.format]))

;; Combo Box Input ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn combo-box-dropdown
"A dropdown specific for combo boxes, including the search bar."
[{:keys [id name] :as opts}]
[:div {:id (str id "-dropdown")
:name (str name "-dropdown")
:class "form-select-dropdown"}
[form-drop/combo-box-search opts]
[form-drop/dropdown-items opts]])

(defn combo-box-input
"A combo box for selecting a single item.
Expand All @@ -25,19 +34,10 @@
| `disabled` | Is the combo box disabled? If so, the dropdown can't be opened.
| `custom-text?` | Is the user allowed to input custom text, and not just the select options?
| `options-fn` | A thunk that returns the options list.
| `tooltip` | A keyword or string that corresponds to tooltip info when the user hovers over the info icon.
| `required` | A boolean that will show a required indicator if true.
| `err-sub` | A subscription vector to buffer errors that may include errors corresponding to this component.
| `err-match` | An error location vector for filtering errors from err-sub. It is treated as a prefix and will match any error that begins with it.
| `removable?` | When true, a \"(None)\" option will appear as the first item in the dropdown; clicking it results in passing `nil` to `on-change`.
| `remove-text` | The dropdown label for `nil` when `removable?` is `true`. Default is \"(None)\"."
[{:keys [id name on-change on-search value placeholder disabled custom-text?
options-fn
#_:clj-kondo/ignore tooltip
#_:clj-kondo/ignore err-sub
#_:clj-kondo/ignore err-match
#_:clj-kondo/ignore required
removable? remove-text]
options-fn removable? remove-text]
:or {name (random-uuid)
id (random-uuid)
disabled false
Expand All @@ -48,7 +48,7 @@
options-fn (constantly [])
removable? false
remove-text "(None)"}}
& #_:clj-kondo/ignore label]
dropdown-panel]
(let [combo-box-ratom (r/atom {:current-value value
:dropdown {:open? false
:focus 0
Expand All @@ -64,7 +64,7 @@
on-blur-fn (fn [e]
(when-not (fns/child-event? e)
(reset! dropdown-open? false)))]
(fn []
(fn [_]
(let [opts-coll (cond->> (vec (options-fn))
removable?
(into [{:value nil :label remove-text}]))
Expand All @@ -74,33 +74,31 @@
:dropdown-open? dropdown-open?
:value-update-fn value-update-fn
:space-select? false})]
[:div
#_[form-label label id tooltip required err-sub err-match]
[:div {:id id
:disabled disabled
:tab-index 0
:class "form-custom-select-input"
:on-key-down on-key-down-fn
:on-blur on-blur-fn
:aria-label (format "Combo Box Input for %s" name)}
[select-input-top
{:id id
:name name
:disabled disabled
:options opts-coll
:current-value current-value
:dropdown-open? dropdown-open?
:placeholder placeholder}]
(when (and (not disabled) @dropdown-open?)
[combo-box-dropdown
{:id id
:name name
:dropdown-focus dropdown-focus
:dropdown-value dropdown-value
:value-update-fn value-update-fn
:search-update-fn on-search
:options opts-coll
:custom-text? custom-text?}])]]))))
[:div {:id id
:disabled disabled
:tab-index 0
:class "form-custom-select-input"
:on-key-down on-key-down-fn
:on-blur on-blur-fn
:aria-label (format "Combo Box Input for %s" name)}
[select-input-top
{:id id
:name name
:disabled disabled
:options opts-coll
:current-value current-value
:dropdown-open? dropdown-open?
:placeholder placeholder}]
(when (and (not disabled) @dropdown-open?)
[dropdown-panel
{:id id
:name name
:dropdown-focus dropdown-focus
:dropdown-value dropdown-value
:value-update-fn value-update-fn
:search-update-fn on-search
:options opts-coll
:custom-text? custom-text?}])]))))

;; Action Dropdown ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand Down
11 changes: 1 addition & 10 deletions src/com/yetanalytics/lrs_admin_ui/views/form/dropdown.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
[:p label]])
options)))

(defn- combo-box-search
(defn combo-box-search
"The top combo box search bar."
[{:keys
[id name dropdown-value value-update-fn search-update-fn custom-text?]}]
Expand Down Expand Up @@ -108,15 +108,6 @@
[:img {:src "images/icons/icon-add.svg"}]
"Add"])]])

(defn combo-box-dropdown
"A dropdown specific for combo boxes, including the search bar."
[{:keys [id name] :as opts}]
[:div {:id (str id "-dropdown")
:name (str name "-dropdown")
:class "form-select-dropdown"}
[combo-box-search opts]
[dropdown-items opts]])

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Top Component
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
57 changes: 31 additions & 26 deletions src/com/yetanalytics/lrs_admin_ui/views/reactions/path.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@
(format "[%s]" seg-val)
(str seg-val))])

(defn- parse-path-segment-selection [v]
(let [parsed-int (js/parseInt v)]
(if (js/isNaN parsed-int)
(if (nil? v)
""
v)
parsed-int)))

(defn- path-segment-options [next-keys search-str]
(if (= ['idx] next-keys)
;; index expected
(for [idx (range 10)]
{:label (str idx) :value idx})
(rfns/order-select-entries
(for [k next-keys
:when (.startsWith k search-str)]
{:label k :value k}))))

(defn- path-input-segment-edit
[_ _ _]
(let [search (r/atom "")]
Expand All @@ -24,7 +42,7 @@
{:keys [next-keys]} (rpath/analyze-path
path-until)]
[:div.path-input-segment-edit
(if (= '[idx] next-keys)
(if false #_(= '[idx] next-keys)
;; When we know it is an index, use a numeric input
[:input.index
{:type "number"
Expand All @@ -35,34 +53,21 @@
(change-fn (js/parseInt (fns/ps-event-val e))))}]
[:div.segment-combo
[form/combo-box-input
{:id id
:name (format "combo-%s" id)
:on-change (fn [v]
;; If it can be an int, pass it as such
(let [parsed-int (js/parseInt v)]
(if (js/isNaN parsed-int)
(if (nil? v)
(change-fn "")
(change-fn v))
(change-fn parsed-int))))
:on-search (fn [v] (reset! search v))
:value seg-val
:placeholder "(select)"
:disabled false
{:id id
:name (format "combo-%s" id)
:on-search (fn [v] (reset! search v))
:on-change (fn [v]
(change-fn (parse-path-segment-selection v)))
:options-fn (fn []
(path-segment-options next-keys @search))
:value seg-val
:placeholder "(select)"
:disabled false
:custom-text? true
:options-fn
(fn []
(if (= ['idx] next-keys)
;; index expected
(for [idx (range 10)]
{:label (str idx) :value idx})
(rfns/order-select-entries
(for [k next-keys
:when (.startsWith k @search)]
{:label k :value k}))))
;; :tooltip "I'M A TOOLTIP OVA HEA" ;; NOT YET IMPLEMENTED, MIGHT NEVER BE
;; :required true
:removable? false}]])]))))
:removable? false}
form/combo-box-dropdown]])]))))

(defn path-input
[path
Expand Down

0 comments on commit 5d043b7

Please sign in to comment.