|
@@ -157,9 +157,61 @@
|
|
|
[tab])
|
|
[tab])
|
|
|
nil)
|
|
nil)
|
|
|
|
|
|
|
|
|
|
+(rum/defc select-observer
|
|
|
|
|
+ [*result *select-mode?]
|
|
|
|
|
+ (let [*el-ref (rum/use-ref nil)
|
|
|
|
|
+ *items-ref (rum/use-ref [])
|
|
|
|
|
+ *current-ref (rum/use-ref [-1])
|
|
|
|
|
+ set-current! (fn [idx node] (set! (. *current-ref -current) [idx node]))
|
|
|
|
|
+ get-cnt #(some-> (rum/deref *el-ref) (.closest ".cp__emoji-icon-picker"))
|
|
|
|
|
+ focus! (fn [idx]
|
|
|
|
|
+ (let [items (rum/deref *items-ref)
|
|
|
|
|
+ total (count items)]
|
|
|
|
|
+ (let [idx (if (< idx -1) 0 (if (> idx total) (dec total) idx))]
|
|
|
|
|
+ (if-let [node (nth items idx)]
|
|
|
|
|
+ (do (.focus node) (set-current! idx node))
|
|
|
|
|
+ (set-current! -1 nil)))))
|
|
|
|
|
+ down-handler!
|
|
|
|
|
+ (rum/use-callback
|
|
|
|
|
+ (fn [^js e]
|
|
|
|
|
+ (let []
|
|
|
|
|
+ (if (= 13 (.-keyCode e))
|
|
|
|
|
+ ;; enter
|
|
|
|
|
+ (some-> (second (rum/deref *current-ref)) (.click))
|
|
|
|
|
+ (let [[idx _node] (rum/deref *current-ref)]
|
|
|
|
|
+ (case (.-keyCode e)
|
|
|
|
|
+ ;;left
|
|
|
|
|
+ 37 (focus! (dec idx))
|
|
|
|
|
+ ;; right
|
|
|
|
|
+ 39 (focus! (inc idx))
|
|
|
|
|
+ ;; up
|
|
|
|
|
+ 38 (do (focus! (- idx 9)) (util/stop e))
|
|
|
|
|
+ ;; down
|
|
|
|
|
+ 40 (do (focus! (+ idx 9)) (util/stop e))
|
|
|
|
|
+ :dune))))) [])]
|
|
|
|
|
+
|
|
|
|
|
+ (rum/use-effect!
|
|
|
|
|
+ (fn []
|
|
|
|
|
+ ;; calculate items
|
|
|
|
|
+ (let [^js blocks (.querySelectorAll (get-cnt) ".pane-block")
|
|
|
|
|
+ items (map #(some-> (.querySelectorAll % ".its > button") (js/Array.from) (js->clj)) blocks)]
|
|
|
|
|
+ (set! (. *items-ref -current) (flatten items))
|
|
|
|
|
+ (focus! 0))
|
|
|
|
|
+
|
|
|
|
|
+ ;; handlers
|
|
|
|
|
+ (let [^js cnt (get-cnt)]
|
|
|
|
|
+ (prn "==>>> init select 0b")
|
|
|
|
|
+ (.addEventListener cnt "keydown" down-handler! false)
|
|
|
|
|
+ (fn []
|
|
|
|
|
+ (prn "==>> bye: 0b")
|
|
|
|
|
+ (.removeEventListener cnt "keydown" down-handler!))))
|
|
|
|
|
+ [])
|
|
|
|
|
+ [:span.absolute.hidden {:ref *el-ref}]))
|
|
|
|
|
+
|
|
|
(rum/defcs icon-search <
|
|
(rum/defcs icon-search <
|
|
|
(rum/local "" ::q)
|
|
(rum/local "" ::q)
|
|
|
(rum/local nil ::result)
|
|
(rum/local nil ::result)
|
|
|
|
|
+ (rum/local false ::select-mode?)
|
|
|
(rum/local :all ::tab)
|
|
(rum/local :all ::tab)
|
|
|
(rum/local nil ::hover)
|
|
(rum/local nil ::hover)
|
|
|
[state {:keys [on-chosen] :as opts}]
|
|
[state {:keys [on-chosen] :as opts}]
|
|
@@ -174,9 +226,11 @@
|
|
|
:on-chosen (fn [e m]
|
|
:on-chosen (fn [e m]
|
|
|
(and on-chosen (on-chosen e m))
|
|
(and on-chosen (on-chosen e m))
|
|
|
(when (:type m) (add-used-item! m))))
|
|
(when (:type m) (add-used-item! m))))
|
|
|
|
|
+ *select-mode? (::select-mode? state)
|
|
|
reset-q! #(when-let [^js input (rum/deref *input-ref)]
|
|
reset-q! #(when-let [^js input (rum/deref *input-ref)]
|
|
|
(reset! *q "")
|
|
(reset! *q "")
|
|
|
(reset! *result {})
|
|
(reset! *result {})
|
|
|
|
|
+ (reset! *select-mode? false)
|
|
|
(set! (. input -value) "")
|
|
(set! (. input -value) "")
|
|
|
(js/setTimeout
|
|
(js/setTimeout
|
|
|
(fn [] (.focus input)
|
|
(fn [] (.focus input)
|
|
@@ -186,6 +240,8 @@
|
|
|
;; header
|
|
;; header
|
|
|
[:div.hd
|
|
[:div.hd
|
|
|
(tab-observer @*tab {:reset-q! reset-q!})
|
|
(tab-observer @*tab {:reset-q! reset-q!})
|
|
|
|
|
+ (when @*select-mode?
|
|
|
|
|
+ (select-observer *result *select-mode?))
|
|
|
[:div.search-input
|
|
[:div.search-input
|
|
|
(shui/tabler-icon "search" {:size 16})
|
|
(shui/tabler-icon "search" {:size 16})
|
|
|
[:input.form-input
|
|
[:input.form-input
|
|
@@ -193,6 +249,7 @@
|
|
|
:ref *input-ref
|
|
:ref *input-ref
|
|
|
:placeholder (util/format "Search %s items" (string/lower-case (name @*tab)))
|
|
:placeholder (util/format "Search %s items" (string/lower-case (name @*tab)))
|
|
|
:default-value ""
|
|
:default-value ""
|
|
|
|
|
+ :on-focus #(reset! *select-mode? false)
|
|
|
:on-key-down (fn [^js e]
|
|
:on-key-down (fn [^js e]
|
|
|
(case (.-keyCode e)
|
|
(case (.-keyCode e)
|
|
|
;; esc
|
|
;; esc
|
|
@@ -200,14 +257,15 @@
|
|
|
(if (string/blank? @*q)
|
|
(if (string/blank? @*q)
|
|
|
(some-> (rum/deref *input-ref) (.blur))
|
|
(some-> (rum/deref *input-ref) (.blur))
|
|
|
(reset-q!)))
|
|
(reset-q!)))
|
|
|
- ;; up
|
|
|
|
|
38 (do (util/stop e))
|
|
38 (do (util/stop e))
|
|
|
- ;; down
|
|
|
|
|
- 40 (do (util/stop e))
|
|
|
|
|
|
|
+ 40 (do
|
|
|
|
|
+ (reset! *select-mode? true)
|
|
|
|
|
+ (util/stop e))
|
|
|
:dune))
|
|
:dune))
|
|
|
:on-change (debounce
|
|
:on-change (debounce
|
|
|
(fn [e]
|
|
(fn [e]
|
|
|
(reset! *q (util/evalue e))
|
|
(reset! *q (util/evalue e))
|
|
|
|
|
+ (reset! *select-mode? false)
|
|
|
(if (string/blank? @*q)
|
|
(if (string/blank? @*q)
|
|
|
(reset! *result {})
|
|
(reset! *result {})
|
|
|
(p/let [result (search @*q @*tab)]
|
|
(p/let [result (search @*q @*tab)]
|