Enhance(UX): polish details for the plugin fenced code block (#9590)

Add the ability for real-time rendering of fenced code block.
This commit is contained in:
Charlie
2023-06-14 21:49:00 +08:00
committed by GitHub
parent 3e7bdda4bf
commit 1696081bed
3 changed files with 103 additions and 14 deletions

View File

@@ -3116,14 +3116,15 @@
:else
(let [language (if (contains? #{"edn" "clj" "cljc" "cljs"} language) "clojure" language)]
[:div {:ref (fn [el]
(set-inside-portal? (and el (whiteboard-handler/inside-portal? el))))}
[:div.ui-fenced-code-editor
{:ref (fn [el]
(set-inside-portal? (and el (whiteboard-handler/inside-portal? el))))}
(cond
(nil? inside-portal?) nil
(or (:slide? config) inside-portal?)
(highlight/highlight (str (random-uuid))
{:class (str "language-" language)
{:class (str "language-" language)
:data-lang language}
code)
@@ -3292,10 +3293,14 @@
[:sup.fn (str name "↩︎")]])]])
["Src" options]
[:div.cp__fenced-code-block
(if-let [opts (plugin-handler/hook-fenced-code-by-type (util/safe-lower-case (:language options)))]
(plugins/hook-ui-fenced-code (string/join "" (:lines options)) opts)
(src-cp config options html-export?))]
(let [lang (util/safe-lower-case (:language options))]
[:div.cp__fenced-code-block
{:data-lang lang}
(if-let [opts (plugin-handler/hook-fenced-code-by-type lang)]
[:div.ui-fenced-code-wrap
(src-cp config options html-export?)
(plugins/hook-ui-fenced-code (:block config) (string/join "" (:lines options)) opts)]
(src-cp config options html-export?))])
:else
"")

View File

@@ -5,6 +5,7 @@
[frontend.context.i18n :refer [t]]
[frontend.ui :as ui]
[frontend.handler.ui :as ui-handler]
[frontend.handler.editor :as editor-handler]
[frontend.handler.plugin-config :as plugin-config-handler]
[frontend.handler.common.plugin :as plugin-common-handler]
[frontend.search :as search]
@@ -1113,14 +1114,61 @@
(let [updates-coming (state/sub :plugin/updates-coming)]
(toolbar-plugins-manager-list updates-coming items)))]]))))
(rum/defcs hook-ui-fenced-code < rum/reactive
[_state content {:keys [render edit] :as _opts}]
(rum/defc hook-ui-fenced-code
[block content {:keys [render edit] :as _opts}]
[:div
{:on-mouse-down (fn [e] (when (false? edit) (util/stop e)))
:class (util/classnames [{:not-edit (false? edit)}])}
(when (fn? render)
(js/React.createElement render #js {:content content}))])
(let [[content1 set-content1!] (rum/use-state content)
[editor-active? set-editor-active!] (rum/use-state (string/blank? content))
*cm (rum/use-ref nil)
*el (rum/use-ref nil)]
(rum/use-effect!
#(set-content1! content)
[content])
(rum/use-effect!
(fn []
(some-> (rum/deref *el)
(.closest ".ui-fenced-code-wrap")
(.-classList)
(#(if editor-active?
(.add % "is-active")
(.remove % "is-active"))))
(when-let [cm (rum/deref *cm)]
(.refresh cm)
(.focus cm)
(.setCursor cm (.lineCount cm) (count (.getLine cm (.lastLine cm))))))
[editor-active?])
(rum/use-effect!
(fn []
(let [t (js/setTimeout
#(when-let [^js cm (some-> (rum/deref *el)
(.closest ".ui-fenced-code-wrap")
(.querySelector ".CodeMirror")
(.-CodeMirror))]
(rum/set-ref! *cm cm)
(doto cm
(.on "change" (fn []
(some-> cm (.getDoc) (.getValue) (set-content1!))))))
;; wait for the cm loaded
1000)]
#(js/clearTimeout t)))
[])
[:div.ui-fenced-code-result
{:on-mouse-down (fn [e] (when (false? edit) (util/stop e)))
:class (util/classnames [{:not-edit (false? edit)}])
:ref *el}
[:<>
[:span.actions
{:on-mouse-down #(util/stop %)}
(ui/button (ui/icon "square-toggle-horizontal" {:size 14})
:on-click #(set-editor-active! (not editor-active?)))
(ui/button (ui/icon "source-code" {:size 14})
:on-click #(editor-handler/edit-block! block (count content1) (:block/uuid block)))]
(when (fn? render)
(js/React.createElement render #js {:content content1}))]]))
(rum/defc plugins-page
[]

View File

@@ -898,6 +898,42 @@
}
}
.ui-fenced-code {
&-wrap {
&:not(.is-active) {
.ui-fenced-code-editor {
display: none !important;
}
}
&.is-active {
.ui-fenced-code-result {
@apply pt-2;
}
}
}
&-result {
@apply relative;
> .actions {
@apply absolute top-2 right-1 z-10 opacity-0 transition-opacity;
.ui__button {
font-size: 13px;
padding: 4px;
margin-left: 6px;
}
}
&:hover {
> .actions {
@apply opacity-100;
}
}
}
}
.lsp-frame-readme {
margin: -2rem;
min-height: 75vh;