find_in_page.cljs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. (ns frontend.components.find-in-page
  2. (:require [rum.core :as rum]
  3. [frontend.ui :as ui]
  4. [frontend.state :as state]
  5. [frontend.util :as util]
  6. [frontend.handler.search :as search-handler :refer [debounced-search, stop-debounced-search!]]
  7. [goog.object :as gobj]
  8. [goog.dom :as gdom]
  9. [frontend.mixins :as mixins]
  10. [clojure.string :as string]))
  11. (rum/defc search-input
  12. [q matches]
  13. (let [*composing? (rum/use-ref false)
  14. on-change-fn (fn [e]
  15. (let [value (util/evalue e)
  16. e-type (gobj/getValueByKeys e "type")]
  17. (state/set-state! [:ui/find-in-page :q] value)
  18. (cond (= e-type "compositionstart")
  19. (do (rum/set-ref! *composing? true)
  20. (stop-debounced-search!))
  21. (= e-type "compositionend")
  22. (rum/set-ref! *composing? false))
  23. (when-not (rum/deref *composing?)
  24. (debounced-search))))]
  25. [:div.flex.w-48.relative
  26. [:input#search-in-page-input.form-input.block.sm:text-sm.sm:leading-5.my-2.border-none.mr-4.outline-none
  27. {:auto-focus true
  28. :placeholder "Find in page"
  29. :aria-label "Find in page"
  30. :value q
  31. :on-composition-start on-change-fn
  32. :on-composition-end on-change-fn
  33. :on-change on-change-fn}]
  34. (when-not (string/blank? q)
  35. (when-let [total (:matches matches)]
  36. [:div.text-sm.absolute.top-2.right-0.py-2.px-4
  37. (:activeMatchOrdinal matches 0)
  38. "/"
  39. total]))
  40. [:div#search-in-page-placeholder.absolute.top-2.left-0.p-2.sm:text-sm]]))
  41. (rum/defc search-inner < rum/static
  42. (mixins/event-mixin
  43. (fn [state]
  44. (mixins/hide-when-esc-or-outside
  45. state
  46. :node (gdom/getElement "search-in-page")
  47. :on-hide (fn []
  48. (search-handler/electron-exit-find-in-page!)))))
  49. [{:keys [matches match-case? q]}]
  50. [:div#search-in-page.flex.flex-row.absolute.top-2.right-4.shadow-lg.px-2.py-1.faster-fade-in.items-center
  51. (search-input q matches)
  52. (ui/button
  53. (ui/icon "letter-case")
  54. :on-click (fn []
  55. (state/update-state! [:ui/find-in-page :match-case?] not)
  56. (debounced-search))
  57. :intent "link"
  58. :small? true
  59. :title "Match case"
  60. :class (str (when match-case? "active ") "text-lg"))
  61. (ui/button
  62. (ui/icon "caret-up")
  63. :on-click (fn []
  64. (state/set-state! [:ui/find-in-page :backward?] true)
  65. (debounced-search))
  66. :intent "link"
  67. :small? true
  68. :class "text-lg"
  69. :title "Previous result")
  70. (ui/button
  71. (ui/icon "caret-down")
  72. :on-click (fn []
  73. (state/set-state! [:ui/find-in-page :backward?] false)
  74. (debounced-search))
  75. :intent "link"
  76. :small? true
  77. :class "text-lg"
  78. :title "Next result")
  79. (ui/button
  80. (ui/icon "x")
  81. :on-click (fn []
  82. (search-handler/electron-exit-find-in-page!))
  83. :intent "link"
  84. :small? true
  85. :class "text-lg"
  86. :title "Close")])
  87. (rum/defc search < rum/reactive
  88. []
  89. (let [{:keys [active?] :as opt} (state/sub :ui/find-in-page)]
  90. (when active?
  91. (search-inner opt))))