Skip to content

Commit

Permalink
cmdk initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
bendyorke committed Aug 2, 2023
1 parent 6f984d4 commit 8bff0f2
Show file tree
Hide file tree
Showing 14 changed files with 777 additions and 119 deletions.
25 changes: 19 additions & 6 deletions deps/shui/src/logseq/shui/button/v2.cljs
Expand Up @@ -3,25 +3,38 @@
[clojure.string :as str]
[logseq.shui.util :as util]
[rum.core :as rum]
[logseq.shui.icon.v2 :as icon]))
[logseq.shui.icon.v2 :as icon]
[clojure.string :as string]))


(rum/defc root
[{:keys [theme text depth size icon shortcut] :or {theme :color depth 1 size :md}} context]
[{:keys [theme text depth size icon interactive shortcut tiled on-click] :or {theme :color depth 1 size :md interactive true}} context]
(let [theme-class (str "shui__button-theme-" (name theme))
depth-class (str "shui__button-depth-" depth)
color-class (str "shui__button-color-" (some-> context :state deref :ui/radix-color name))
size-class (str "shui__button-size-" (name size))]
[:button.shui__button {:class (str theme-class " " depth-class " " color-class " " size-class)}
text
size-class (str "shui__button-size-" (name size))
tiled-class (when tiled "shui__button-tiled")]
[:button.shui__button {:class (str theme-class " " depth-class " " color-class " " size-class " " tiled-class)
:on-click (when on-click on-click)}
(if-not tiled text
(for [[index tile] (map-indexed vector (rest (string/split text #"")))]
[:<>
(when (< 0 index)
[:div.shui__button__tile-separator])
[:div.shui__button__tile {:class ""} tile]]))

(when icon
(icon/root icon))
(when (not-empty shortcut)
(for [key shortcut]
[:div.shui__button-shortcut-key
(case key
"cmd" (icon/root "command")
"shift" (icon/root "arrow-big-up-filled")
"shift" (icon/root "arrow-big-top")
"return" (icon/root "arrow-back")
"esc" [:div.tracking-tightest {:style {:transform "scaleX(0.8) scaleY(1.2) "
:font-size "0.5rem"
:font-weight "500"}} "ESC"]
key)]))]))


Expand Down
128 changes: 101 additions & 27 deletions deps/shui/src/logseq/shui/cmdk/v2.cljs
Expand Up @@ -8,7 +8,34 @@

(def state (atom {:current-engine "All"
:highlight-index 0
:button {:text "Open" :theme :gray :shortcut ["return"]}}))
:button {:text "Open" :theme :gray :shortcut ["return"]}
:query ""
:results {:blocks [] :pages [] :files []}}))

; (let [entity (-> @state :context :entity)
; block (-> @state :results :blocks first)
; preview-uuid (-> @state :preview-uuid)
; {:keys [blocks-container get-block-and-children get-current-repo]} (:context @state)]
; ; (keys (entity (:block/page block)))
; ; blockgc)
; ; (blocks-container
; ; (get-block-and-children (get-current-repo) preview-uuid)
; ; {:id preview-uuid :preview? true}))
; ; puuid)
; (get-block-and-children (get-current-repo) (keyword preview-uuid)))
; ; preview-uuid)
; ; (get-current-repo))

; "6492d9e2-7554-4015-a28b-d6acbb6c1a19"
; "logseq_local_shui-graph"


(defn handle-query-change [e context]
(let [query (.. e -target -value)]
(swap! state assoc :query query)
(when (and (seq query) (seq (str/trim query)))
(-> ((:search context) query)
(.then #(swap! state assoc :results %))))))

(defn get-results []
[])
Expand Down Expand Up @@ -60,9 +87,16 @@
(fn []
(swap! state assoc :button {:text text :theme theme :shortcut (map name shortcut)})))

(defn button-updater-with-preview [preview-uuid text theme & shortcut]
(fn []
(apply button-updater text theme shortcut)
(if (string? preview-uuid)
(swap! state assoc :preview-uuid (uuid preview-uuid))
(swap! state assoc :preview-uuid preview-uuid))))

(rum/defc results < rum/reactive []
(let [state-value (rum/react state)
{:keys [current-engine highlight-index]} state-value
{:keys [current-engine highlight-index results]} state-value
filtered-actions (when (#{"All" "Actions"} current-engine)
[{:icon-theme :color :icon "plus" :text "Quick capture" :info "Add a block to todays journal page" :on-highlight (button-updater "Quick capture" :color :return)}
{:icon-theme :gradient :icon "question-mark" :text "Generate short answer" :on-highlight (button-updater "Generate" :gradient :return)}
Expand All @@ -78,12 +112,16 @@
{:icon-theme :gradient :icon "messages" :text "Chat" :info "Chat with an AI about any topic" :on-highlight (button-updater "Start chat" :gradient :return)}
{:icon-theme :gradient :icon "question-mark" :text "Generate short answer" :on-highlight (button-updater "Generate" :gradient :return)}])
filtered-blocks (when (#{"All" "Blocks"} current-engine)
[{:icon-theme :gray :icon "block" :title "Not a real document" :on-highlight (button-updater "Open" :gray :return) :text "When working on cmdk, we want to display blocks that appear from search. These can have quite a long body of text, and that body of text should potentially be truncated"}
{:icon-theme :gray :icon "block" :title "Not a real document" :on-highlight (button-updater "Open" :gray :return) :text "Of course, that truncated text should be truncated in a way that makes sense, and doesn't cut off in the middle of a word, and contains the search query if there is one"}
{:icon-theme :gray :icon "block" :title "Not a real document" :on-highlight (button-updater "Open" :gray :return) :text "We should play around with displaying the blocks hierarchy, currently it's very noisy, and I'm not sure if it's adding much value. It's possible that the preview will be a sufficient replacement"}])
(->> (:blocks results)
(map #(hash-map :title (:block/content %) :on-highlight (button-updater-with-preview (:block/uuid %) "Open" :gray :return) :icon-theme :gray :icon "block"))))
; [{:icon-theme :gray :icon "block" :title "Not a real document" :on-highlight (button-updater "Open" :gray :return) :text "When working on cmdk, we want to display blocks that appear from search. These can have quite a long body of text, and that body of text should potentially be truncated"}
; {:icon-theme :gray :icon "block" :title "Not a real document" :on-highlight (button-updater "Open" :gray :return) :text "Of course, that truncated text should be truncated in a way that makes sense, and doesn't cut off in the middle of a word, and contains the search query if there is one"}
; {:icon-theme :gray :icon "block" :title "Not a real document" :on-highlight (button-updater "Open" :gray :return) :text "We should play around with displaying the blocks hierarchy, currently it's very noisy, and I'm not sure if it's adding much value. It's possible that the preview will be a sufficient replacement"}])
filtered-pages (when (#{"All" "Pages"} current-engine)
[{:icon-theme :gray :icon "page" :text "Memo/CMDK" :on-highlight (button-updater "Open" :gray :return)}
{:icon-theme :gray :icon "page" :text "Logseq Logo Community Contest" :on-highlight (button-updater "Open" :gray :return)}])
(->> (:pages results)
(map #(hash-map :title % :on-highlight (button-updater "Open" :gray :return) :icon-theme :gray :icon "page"))))
; [{:icon-theme :gray :icon "page" :text "Memo/CMDK" :on-highlight (button-updater "Open" :gray :return)}
; {:icon-theme :gray :icon "page" :text "Logseq Logo Community Contest" :on-highlight (button-updater "Open" :gray :return)}])
grouped-items (->> [["Actions" filtered-actions] ["Actions" filtered-qc-actions] ["Actions" filtered-ai-actions] ["Blocks" filtered-blocks] ["Pages" filtered-pages]]
(filter #(not-empty (second %))))
item-count (count (mapcat second grouped-items))
Expand All @@ -105,8 +143,34 @@
(for [item items]
(result-item (assoc item :highlighted (= item highlight-item) :on-highlight-dep current-engine)))])]))

(rum/defc preview []
[:div "Preview"])
(rum/defc preview < rum/reactive
[_ {:keys [blocks-container get-block-and-children get-current-repo entity get-page page-cp get-page-blocks-no-cache get-block-children page] :as context}]
(let [state-value (rum/react state)
preview-uuid (:preview-uuid state-value)
preview-entity (entity [:block/uuid preview-uuid])
preview-page (:block/page preview-entity)
preview-page-uuid (:block/uuid preview-page)
preview-page-name (:block/name preview-page)]
(-> {:preview-uuid preview-uuid :preview-page-uuid preview-page-uuid :preview-page-name preview-page-name}
pr-str
js/console.log)
[:div
;; page
(page {:page-name preview-page-name})]))
; (page-cp {:preview? true
; :contents-page? (= "contents" (str/lower-case (str preview-page-name)))
; :children (get-block-children (get-current-repo) preview-page-uuid)}
; preview-page)]))
;; block
; (blocks-container
; (get-block-and-children (get-current-repo) preview-uuid)
; ; (get-block-and-children (get-current-repo) preview-page-uuid)
; ; (get-page preview-page-uuid)
; {:id preview-uuid :preview? true})]))

; (let [preview-uuid (:preview-uuid @state)
; entity (-> @state :context :entity)]
; (keys (:block/page (entity [:block/uuid preview-uuid]))))

(rum/defc actions < rum/reactive []
(let [state-value (rum/react state)
Expand All @@ -129,10 +193,14 @@
[:input {:class "w-full border-0 px-6 bg-transparent"
:type "text"}]]])

(rum/defc search []
[:input {:class "w-full border-0 px-6"
:type "text"
:placeholder "Search"}])
(rum/defc search < rum/reactive [context]
(let [state-value (rum/react state)
query (:query state-value)]
[:input {:class "w-full border-0 px-6"
:type "text"
:placeholder "Search"
:value query
:on-change #(handle-query-change % context)}]))

(rum/defc header < rum/reactive
[context]
Expand All @@ -145,7 +213,7 @@
(engines context)
(if (= current-engine "Quick capture")
(quick-capture)
(search))]))
(search context))]))

(defn prev-engine [current-engine]
(->> ["All" "Pages" "Blocks" "Quick capture" "AI" "All"]
Expand Down Expand Up @@ -179,25 +247,31 @@
#(js/window.removeEventListener "keydown" keydown-handler))
[]))

(rum/defc body < rum/reactive [context]
(let [state-value (rum/react state)
preview-uuid (:preview-uuid state-value)]
(if preview-uuid
[:div.grid.grid-cols-2
(results)
(preview preview-uuid context)]
[:div.grid.grid-cols-1
(results)])))


(rum/defc root < rum/reactive
{:did-mount (fn [_]
(js/window.removeEventListener "keydown" keydown-handler)
(js/window.addEventListener "keydown" keydown-handler))
:will-unmount (fn [_] (js/window.removeEventListener "keydown" keydown-handler))}
[props context]
(swap! state assoc :context context)
; (use-cmdk-keyboard-bindings!)
(let [preview-data (get-preview)]
[:div.-m-8 {:style {:background-color "var(--lx-gray-02)"
:width "75vw"
:max-width 800}}
(header context)
(if preview-data
[:div.grid.grid-cols-2
(results)
(preview)]
[:div.grid.grid-cols-1
(results)])
[:div
(actions)]]))
[:div.-m-8 {:style {:background-color "var(--lx-gray-02)"
:width "75vw"
:max-width 800}}
(header context)
(body context)
[:div
(actions)]])


22 changes: 18 additions & 4 deletions deps/shui/src/logseq/shui/context.cljs
@@ -1,7 +1,10 @@
(ns logseq.shui.context
(:require
[frontend.state :as state]
[frontend.colors :as colors]))
[frontend.colors :as colors]
[frontend.db :as db]
[frontend.db.utils :as db-utils]
[frontend.handler.search :as search-handler]
[frontend.state :as state]))

(defn inline->inline-block [inline block-config]
(fn [_context item]
Expand All @@ -12,7 +15,7 @@
(fn [context col]
(map #(inline* context %) col))))

(defn make-context [{:keys [block-config app-config inline int->local-time-2]}]
(defn make-context [{:keys [block-config app-config inline int->local-time-2 blocks-container page-cp page]}]
{;; Shui needs access to the global configuration of the application
:config app-config
;; Until components are converted over, they need to fallback to the old inline function
Expand Down Expand Up @@ -43,4 +46,15 @@
:sub-color-gradient-bg-styles state/sub-color-gradient-bg-styles
:sub-color-gradient-text-styles state/sub-color-gradient-text-styles
:linear-gradient colors/linear-gradient
:state state/state})
:state state/state
;; Add search to context
:search search-handler/search
:entity db-utils/entity
:blocks-container blocks-container
:get-block-and-children db/get-block-and-children
:get-block-children db/get-block-children
:get-current-repo state/get-current-repo
:get-page-blocks-no-cache db/get-page-blocks-no-cache
:get-page db/get-page
:page-cp page-cp
:page page})
10 changes: 10 additions & 0 deletions deps/shui/src/logseq/shui/core.cljs
Expand Up @@ -3,6 +3,8 @@
[logseq.shui.button.v2 :as shui.button.v2]
[logseq.shui.cmdk.v2 :as shui.cmdk.v2]
[logseq.shui.context :as shui.context]
[logseq.shui.icon.v2 :as shui.icon.v2]
[logseq.shui.list-item.v1 :as shui.list-item.v1]
[logseq.shui.table.v2 :as shui.table.v2]))

;; table component
Expand All @@ -17,5 +19,13 @@
(def cmdk shui.cmdk.v2/root)
(def cmdk-v2 shui.cmdk.v2/root)

;; icon
(def icon shui.icon.v2/root)
(def icon-v2 shui.icon.v2/root)

;; list-item
(def list-item shui.list-item.v1/root)
(def list-item-v1 shui.list-item.v1/root)

;; context
(def make-context shui.context/make-context)
78 changes: 78 additions & 0 deletions deps/shui/src/logseq/shui/list_item/v1.cljs
@@ -0,0 +1,78 @@
(ns logseq.shui.list-item.v1
(:require
[rum.core :as rum]
[clojure.string :as string]
[logseq.shui.icon.v2 :as icon]
[logseq.shui.button.v2 :as button]))

(defn print-shortcut-key [key]
(case key
("cmd" "command" "mod" "") ""
("return" "enter" "") ""
("shift" "") ""
("alt" "option" "opt" "") ""
("ctrl" "control" "") ""
("space" " ") " "
("up" "") ""
("down" "") ""
("left" "") ""
("right" "") ""
("disabled") ""
("backspace" "delete") ""
("tab") ""
(nil) ""
(name key)))

;; result-item
(rum/defc root [{:keys [icon icon-theme text info shortcut value-label value title highlighted on-highlight on-highlight-dep header]}]
(let [ref (rum/create-ref)]
(rum/use-effect!
(fn []
(when (and highlighted on-highlight)
(on-highlight ref)))
[highlighted on-highlight-dep])
[:div.flex.flex-col.px-6.gap-1.py-4 {:style {:background (if highlighted "var(--lx-gray-04-alpha)" "var(--lx-gray-02)")
:opacity (if highlighted 1 0.8)
:mix-blend-mode (if highlighted :normal :luminosity)}
:ref ref}
;; header
(when header
[:div.text-xs.pl-8.font-light {:class "-mt-1"
:style {:color "var(--lx-gray-11)"}}
header])
;; main row
[:div.flex.items-center.gap-3
[:div.w-5.h-5.rounded.flex.items-center.justify-center
{:style {:background (case icon-theme :color "var(--lx-accent-09)" :gray "var(--lx-gray-09)" :gradient "linear-gradient(-65deg, #8AE8FF, #5373E7, #369EFF, #00B1CC)" "var(--lx-gray-09)")
:box-shadow (when (#{:color :gradient} icon-theme) "inset 0 0 0 1px rgba(255,255,255,0.3) ")}}
(icon/root icon {:size "14"})]
[:div.flex.flex-1.flex-col
(when title
[:div.text-sm.pb-2.font-bold {:style {:color "var(--lx-gray-11)"}} title])
[:div {:class "text-sm font-medium"
:style {:color "var(--lx-gray-12)"}} text
(when info
[:span {:style {:color "var(--lx-gray-11)"}} (str "" info)])]]
(when (or value-label value)
[:div {:class "text-xs"}
(when (and value-label value)
[:span {:style {:color "var(--lx-gray-11)"}} (str value-label ": ")])
(when (and value-label (not value))
[:span {:style {:color "var(--lx-gray-11)"}} (str value-label)])
(when value
[:span {:style {:color "var(--lx-gray-12)"}} value])])
(when shortcut
[:div {:class "flex gap-1"}
(for [[index option] (map-indexed vector (string/split shortcut #" \| "))]
[:<>
(when (< 0 index)
[:div {:style {:color "var(--lx-gray-11)"}} "|"])
(for [sequence (string/split option #" ")
:let [text (->> (string/split sequence #"\+")
(map print-shortcut-key)
(apply str))]]
(button/root {:theme :gray
:interactive false
:text text
:tiled true}))])])]]))
; [:span {:style} (str key)])])])

0 comments on commit 8bff0f2

Please sign in to comment.