command_palette.cljs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. (ns frontend.components.command-palette
  2. (:require [frontend.handler.command-palette :as cp]
  3. [frontend.modules.shortcut.core :as shortcut]
  4. [frontend.modules.shortcut.data-helper :as shortcut-helper]
  5. [frontend.context.i18n :refer [t]]
  6. [frontend.search :as search]
  7. [frontend.state :as state]
  8. [frontend.ui :as ui]
  9. [frontend.util :as util]
  10. [rum.core :as rum]
  11. [clojure.string :as string]))
  12. (defn translate [t {:keys [id desc]}]
  13. (when id
  14. (let [desc-i18n (t (shortcut-helper/decorate-namespace id))]
  15. (if (string/starts-with? desc-i18n "{Missing key")
  16. desc
  17. desc-i18n))))
  18. (defn get-matched-commands [commands input limit t]
  19. (search/fuzzy-search commands input :limit limit :extract-fn (partial translate t)))
  20. (rum/defc render-command
  21. [{:keys [id shortcut] :as cmd} chosen?]
  22. (let [first-shortcut (first (string/split shortcut #" \| "))
  23. desc (translate t cmd)]
  24. [:div.inline-grid.grid-cols-4.gap-x-4.w-full
  25. {:class (when chosen? "chosen")}
  26. [:span.col-span-3 desc]
  27. [:div.col-span-1.justify-end.tip.flex
  28. (when (and (keyword? id) (namespace id))
  29. [:code.opacity-20.bg-transparent (namespace id)])
  30. (when-not (string/blank? first-shortcut)
  31. [:code.ml-1 first-shortcut])]]))
  32. (rum/defcs command-palette <
  33. (shortcut/disable-all-shortcuts)
  34. (rum/local "" ::input)
  35. {:will-unmount (fn [state]
  36. (state/set-state! :ui/command-palette-open? false)
  37. state)}
  38. [state {:keys [commands limit]
  39. :or {limit 100}}]
  40. (let [input (::input state)]
  41. [:div.cp__palette.cp__palette-main
  42. [:div.input-wrap
  43. [:input.cp__palette-input.w-full
  44. {:type "text"
  45. :placeholder (t :command-palette/prompt)
  46. :auto-focus true
  47. :value @input
  48. :on-change (fn [e] (reset! input (util/evalue e)))}]]
  49. [:div.command-results-wrap
  50. (ui/auto-complete
  51. (if (string/blank? @input)
  52. (cp/top-commands limit)
  53. (get-matched-commands commands @input limit t))
  54. {:item-render render-command
  55. :class "cp__palette-results"
  56. :on-chosen (fn [cmd] (cp/invoke-command cmd))})]]))
  57. (rum/defc command-palette-modal < rum/reactive
  58. []
  59. (let [open? (state/sub :ui/command-palette-open?)]
  60. (when open?
  61. (state/set-modal!
  62. #(command-palette {:commands (cp/get-commands)})
  63. {:fullscreen? false
  64. :close-btn? false}))
  65. nil))