mirror of
https://github.com/logseq/logseq.git
synced 2026-06-01 19:01:22 +00:00
fix(properties): improve bottom row keyboard navigation and focus behavior
This commit is contained in:
@@ -2579,9 +2579,164 @@
|
||||
:tag? true
|
||||
:disable-preview? true
|
||||
:disable-click? true) tag)])
|
||||
[:div.text-sm.opacity-50.ml-1
|
||||
[:div.text-sm.opacity-50.ml-1
|
||||
(str "+" (- tags-count 2))]])))))
|
||||
|
||||
(defn- bottom-row-focus-elements
|
||||
[^js row]
|
||||
(->> (array-seq (.querySelectorAll row "[data-bottom-row-nav='true']"))
|
||||
vec))
|
||||
|
||||
(defn- focus-bottom-row-item!
|
||||
[^js row index]
|
||||
(when-let [el (nth (bottom-row-focus-elements row) index nil)]
|
||||
(.focus el)
|
||||
true))
|
||||
|
||||
(defn- move-bottom-row-focus!
|
||||
[^js el direction]
|
||||
(when-let [^js row (.closest el ".bottom-properties-row")]
|
||||
(let [items (bottom-row-focus-elements row)
|
||||
current-index (or (first (keep-indexed (fn [idx item]
|
||||
(when (identical? item el) idx))
|
||||
items))
|
||||
0)
|
||||
last-index (max 0 (dec (count items)))
|
||||
next-index (case direction
|
||||
:prev (max 0 (dec current-index))
|
||||
:next (min last-index (inc current-index))
|
||||
current-index)]
|
||||
(focus-bottom-row-item! row next-index))))
|
||||
|
||||
(defn- trigger-bottom-pill-edit!
|
||||
[^js pill]
|
||||
(when-let [trigger (some-> pill
|
||||
(.querySelector ".bottom-property-content .jtrigger"))]
|
||||
(.click trigger)
|
||||
(some-> trigger .focus)
|
||||
true))
|
||||
|
||||
(defn- current-bottom-pill
|
||||
[^js el]
|
||||
(some-> el (.closest ".bottom-property-pill-focusable")))
|
||||
|
||||
(defn- input-cursor-at-boundary?
|
||||
[^js input key]
|
||||
(let [start (.-selectionStart input)
|
||||
end (.-selectionEnd input)
|
||||
value (or (.-value input) "")]
|
||||
(and (number? start)
|
||||
(number? end)
|
||||
(= start end)
|
||||
(case key
|
||||
"ArrowUp" (zero? start)
|
||||
"ArrowDown" (= start (count value))
|
||||
false))))
|
||||
|
||||
(defn- focus-block-editor-from-bottom-row!
|
||||
[^js row]
|
||||
(when-let [^js current-block (.closest row ".ls-block")]
|
||||
(.blur row)
|
||||
(when-let [block-id (some-> (dom/attr current-block "blockid") uuid)]
|
||||
(let [container-id (some-> (dom/attr current-block "containerid") js/parseInt)]
|
||||
(editor-handler/edit-block! {:block/uuid block-id}
|
||||
:max
|
||||
{:container-id container-id})))))
|
||||
|
||||
(defn- handle-bottom-properties-row-key-down!
|
||||
[e]
|
||||
(let [key (util/ekey e)
|
||||
^js row (.-currentTarget e)
|
||||
^js active-el (.-activeElement js/document)]
|
||||
(cond
|
||||
(= "ArrowUp" key)
|
||||
(do
|
||||
(util/stop e)
|
||||
(focus-block-editor-from-bottom-row! row))
|
||||
|
||||
(= "ArrowDown" key)
|
||||
(do
|
||||
(util/stop e)
|
||||
(editor-handler/move-cross-boundary-up-down :down {:exclude-property? true}))
|
||||
|
||||
(contains? #{"ArrowLeft" "ArrowRight"} key)
|
||||
(do
|
||||
(util/stop e)
|
||||
(if (and active-el
|
||||
(= "true" (.getAttribute active-el "data-bottom-row-nav")))
|
||||
(move-bottom-row-focus! active-el (if (= key "ArrowLeft") :prev :next))
|
||||
(let [items (bottom-row-focus-elements row)]
|
||||
(when (seq items)
|
||||
(.focus (first items))))))
|
||||
|
||||
:else
|
||||
nil)))
|
||||
|
||||
(defn- handle-bottom-pill-key-down!
|
||||
[e]
|
||||
(let [key (util/ekey e)
|
||||
^js pill (.-currentTarget e)]
|
||||
(cond
|
||||
(contains? #{"ArrowUp" "ArrowDown"} key)
|
||||
(do
|
||||
(util/stop e)
|
||||
(some-> (.closest pill ".bottom-properties-row") (.focus)))
|
||||
|
||||
(contains? #{" " "Enter"} key)
|
||||
(do
|
||||
(util/stop e)
|
||||
(trigger-bottom-pill-edit! pill))
|
||||
|
||||
:else
|
||||
nil)))
|
||||
|
||||
(defn- bottom-property-pill-cp
|
||||
[block property opts]
|
||||
[:div.bottom-property-pill.bottom-property-pill-focusable
|
||||
{:key (str (:db/id block) "-" (:db/id property))
|
||||
:data-bottom-pill-focusable true
|
||||
:data-bottom-row-nav true
|
||||
:tab-index -1
|
||||
:on-key-down handle-bottom-pill-key-down!}
|
||||
[:div.flex.flex-row.items-center
|
||||
(property-component/property-key-cp block property opts)
|
||||
[:div.select-none ":"]]
|
||||
[:div {:class "bottom-property-content ls-block property-value-container"
|
||||
:style {:min-height 20}}
|
||||
(pv/property-value block property opts)
|
||||
(when (contains? #{:date :datetime} (:logseq.property/type property))
|
||||
[:button.bottom-property-edit-icon.select-none
|
||||
{:type "button"
|
||||
:on-click (fn [e]
|
||||
(util/stop e)
|
||||
(when-let [trigger
|
||||
(some-> (.-currentTarget e)
|
||||
(.closest ".bottom-property-content")
|
||||
(.querySelector ".jtrigger"))]
|
||||
(.click trigger)
|
||||
(some-> trigger .focus)))}
|
||||
(ui/icon "edit" {:size 15})])]])
|
||||
|
||||
(defn- block-below-positioned-properties-cp
|
||||
[block properties opts show-hidden-properties-toggle? show-add-property-button?]
|
||||
[:div.positioned-properties.block-below.flex.flex-col.gap-1.text-sm.overflow-x-hidden
|
||||
[:div.bottom-properties-row.flex.flex-row.gap-2.items-center.flex-wrap.overflow-x-hidden
|
||||
{:data-bottom-properties-row (:block/uuid block)
|
||||
:tab-index -1
|
||||
:on-key-down handle-bottom-properties-row-key-down!}
|
||||
(for [property properties]
|
||||
(bottom-property-pill-cp block property opts))
|
||||
(when show-hidden-properties-toggle?
|
||||
(property-component/hidden-properties-toggle-button block {:icon-only? true
|
||||
:bottom-row-nav? true
|
||||
:tab-index 0}))
|
||||
(when show-add-property-button?
|
||||
(property-component/new-property block (assoc opts
|
||||
:property-position :block-below
|
||||
:bottom-row-nav? true
|
||||
:icon-only? true
|
||||
:tab-index 0)))]])
|
||||
|
||||
(rum/defc block-positioned-properties
|
||||
[config block position]
|
||||
(let [properties (outliner-property/get-block-positioned-properties (db/get-db) (:db/id block) position)
|
||||
@@ -2603,38 +2758,48 @@
|
||||
(not config/publishing?))
|
||||
show-add-property-button? (and has-viewable-properties?
|
||||
show-page-add-property?)]
|
||||
(when (= position :block-below)
|
||||
(hooks/use-effect!
|
||||
(fn []
|
||||
(let [block-uuid (:block/uuid block)
|
||||
listener (fn [^js e]
|
||||
(let [key (util/ekey e)
|
||||
^js active-el (.-activeElement js/document)
|
||||
edit-input-id (str "edit-block-" block-uuid)
|
||||
row (when block-uuid
|
||||
(.querySelector js/document
|
||||
(str "[data-bottom-properties-row=\"" block-uuid "\"]")))]
|
||||
(when (and row
|
||||
has-viewable-properties?
|
||||
block-uuid
|
||||
(contains? #{"ArrowUp" "ArrowDown"} key)
|
||||
(not (or (.-metaKey e)
|
||||
(.-ctrlKey e)
|
||||
(.-altKey e)))
|
||||
active-el
|
||||
(= (.-id active-el) edit-input-id)
|
||||
(input-cursor-at-boundary? active-el key))
|
||||
(util/stop e)
|
||||
(.focus row))
|
||||
|
||||
(when (and row
|
||||
(= key "Escape")
|
||||
active-el
|
||||
(.contains row active-el))
|
||||
(when-let [pill (current-bottom-pill active-el)]
|
||||
(js/setTimeout (fn [] (.focus pill)) 0)))))]
|
||||
(.addEventListener js/document "keydown" listener)
|
||||
(fn []
|
||||
(.removeEventListener js/document "keydown" listener))))
|
||||
[(:block/uuid block) has-viewable-properties?]))
|
||||
(case position
|
||||
:block-below
|
||||
(when has-viewable-properties?
|
||||
[:div.positioned-properties.block-below.flex.flex-col.gap-1.text-sm.overflow-x-hidden
|
||||
[:div.bottom-properties-row.flex.flex-row.gap-2.items-center.flex-wrap.overflow-x-hidden
|
||||
(for [property properties]
|
||||
[:div.bottom-property-pill
|
||||
{:key (str (:db/id block) "-" (:db/id property))}
|
||||
[:div.flex.flex-row.items-center
|
||||
(property-component/property-key-cp block property opts)
|
||||
[:div.select-none ":"]]
|
||||
[:div.bottom-property-content.ls-block.property-value-container
|
||||
{:style {:min-height 20}}
|
||||
(pv/property-value block property opts)
|
||||
(when (contains? #{:number :date :datetime} (:logseq.property/type property))
|
||||
[:button.bottom-property-edit-icon.select-none
|
||||
{:type "button"
|
||||
:on-click (fn [e]
|
||||
(util/stop e)
|
||||
(when-let [trigger
|
||||
(some-> (.-currentTarget e)
|
||||
(.closest ".bottom-property-content")
|
||||
(.querySelector ".jtrigger"))]
|
||||
(.click trigger)
|
||||
(some-> trigger .focus)))}
|
||||
(ui/icon "edit" {:size 14})])]])
|
||||
(when show-hidden-properties-toggle?
|
||||
(property-component/hidden-properties-toggle-button block {:icon-only? true}))
|
||||
(when show-add-property-button?
|
||||
(property-component/new-property block (assoc opts
|
||||
:property-position :block-below
|
||||
:icon-only? true)))]])
|
||||
(block-below-positioned-properties-cp block
|
||||
properties
|
||||
opts
|
||||
show-hidden-properties-toggle?
|
||||
show-add-property-button?))
|
||||
|
||||
(when (seq properties)
|
||||
[:div.positioned-properties.flex.flex-row.gap-1.select-none.h-6.self-start
|
||||
|
||||
@@ -1063,14 +1063,34 @@ html.is-mac {
|
||||
@apply gap-1.5 py-1;
|
||||
}
|
||||
|
||||
.bottom-properties-row:focus {
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 0 1px var(--ls-link-text-color);
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.bottom-property-pill {
|
||||
@apply inline-flex items-center gap-1 rounded-full px-2 py-0.5 h-6 max-w-full;
|
||||
background-color: var(--ls-secondary-background-color);
|
||||
box-shadow: inset 0 0 0 1px var(--ls-border-color);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bottom-property-pill-focusable:focus {
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 0 1px var(--ls-link-text-color);
|
||||
}
|
||||
|
||||
.bottom-property-control-btn:focus,
|
||||
.bottom-property-control-btn:focus-visible,
|
||||
.bottom-property-add-btn:focus,
|
||||
.bottom-property-add-btn:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 0 1px var(--ls-link-text-color);
|
||||
}
|
||||
|
||||
.bottom-property-content {
|
||||
@apply flex items-center gap-1 min-w-0;
|
||||
@apply flex items-center gap-1 min-w-0 relative;
|
||||
}
|
||||
|
||||
.bottom-property-pill .property-key-inner {
|
||||
@@ -1098,8 +1118,29 @@ html.is-mac {
|
||||
box-shadow: inset 0 0 0 1px var(--ls-border-color);
|
||||
}
|
||||
|
||||
.bottom-property-add-btn {
|
||||
@apply justify-center w-6 h-6 p-0 rounded-full;
|
||||
}
|
||||
|
||||
.ls-new-property .jtrigger.bottom-property-add-btn:focus,
|
||||
.ls-new-property .jtrigger.bottom-property-add-btn:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 0 1px var(--ls-link-text-color);
|
||||
}
|
||||
|
||||
.bottom-property-edit-icon {
|
||||
@apply inline-flex items-center justify-center p-0 bg-transparent border-0 text-muted-foreground cursor-pointer;
|
||||
@apply inline-flex items-center justify-end pr-0 py-2 px-2 border-0 cursor-pointer opacity-0 pointer-events-none;
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
color: var(--ls-primary-text-color);
|
||||
background: linear-gradient(to left, var(--ls-primary-background-color) 65%, transparent);
|
||||
}
|
||||
|
||||
.bottom-property-pill:hover .bottom-property-edit-icon,
|
||||
.bottom-property-edit-icon:focus-visible {
|
||||
@apply opacity-100 pointer-events-auto;
|
||||
}
|
||||
|
||||
.ls-block.property-value-container {
|
||||
|
||||
@@ -447,6 +447,9 @@
|
||||
[state block opts]
|
||||
(when-not config/publishing?
|
||||
(let [icon-only? (:icon-only? opts)
|
||||
bottom-property-add-button? (= :block-below (:property-position opts))
|
||||
tab-index (:tab-index opts)
|
||||
bottom-row-nav? (:bottom-row-nav? opts)
|
||||
add-new-property! (fn [e]
|
||||
(state/pub-event! [:editor/new-property (merge opts {:block block
|
||||
:target (.-target e)})]))]
|
||||
@@ -454,8 +457,11 @@
|
||||
(shui/button
|
||||
{:variant :outline
|
||||
:size :small
|
||||
:class "jtrigger flex !px-2 !py-1"
|
||||
:tab-index 0
|
||||
:class (util/classnames
|
||||
["jtrigger flex !px-2 !py-1"
|
||||
{:bottom-property-add-btn bottom-property-add-button?}])
|
||||
:tab-index (or tab-index 0)
|
||||
:data-bottom-row-nav (when bottom-row-nav? true)
|
||||
:title (t :property/add-new)
|
||||
:on-click add-new-property!
|
||||
:on-key-press (fn [e]
|
||||
@@ -526,7 +532,7 @@
|
||||
(if (:class-schema? opts)
|
||||
(pv/property-value property (db/entity :logseq.property/description) opts)
|
||||
(pv/property-value block' property (assoc opts :suppress-inline-edit-icon? true)))]
|
||||
(when (contains? #{:number :date :datetime} type)
|
||||
(when (contains? #{:date :datetime} type)
|
||||
[:button.property-panel-edit-btn.select-none
|
||||
{:type "button"
|
||||
:on-click (fn [e]
|
||||
@@ -537,7 +543,7 @@
|
||||
(.querySelector ".jtrigger"))]
|
||||
(.click trigger)
|
||||
(some-> trigger .focus)))}
|
||||
(ui/icon "edit" {:size 14})])])]))))
|
||||
(ui/icon "edit" {:size 15})])])]))))
|
||||
|
||||
(defn- entity-ref-value?
|
||||
[value]
|
||||
@@ -765,13 +771,17 @@
|
||||
(boolean (seq hidden-properties))))
|
||||
|
||||
(rum/defc hidden-properties-toggle-button
|
||||
[block {:keys [icon-only?] :as _opts}]
|
||||
[block {:keys [icon-only? tab-index bottom-row-nav?] :as _opts}]
|
||||
(let [block-uuid (:block/uuid block)]
|
||||
(when block-uuid
|
||||
(shui/button
|
||||
{:variant :ghost
|
||||
:size :sm
|
||||
:class "bottom-property-control-btn px-1 text-muted-foreground h-6 text-xs"
|
||||
{:variant :outline
|
||||
:size :small
|
||||
:class (util/classnames
|
||||
["bottom-property-control-btn"
|
||||
{:bottom-property-add-btn icon-only?}])
|
||||
:tab-index (or tab-index 0)
|
||||
:data-bottom-row-nav (when bottom-row-nav? true)
|
||||
:title (t :property/hidden-properties)
|
||||
:on-click (fn [e]
|
||||
(util/stop e)
|
||||
@@ -803,14 +813,13 @@
|
||||
(assoc state
|
||||
::id (str (random-uuid))
|
||||
::block block)))}
|
||||
[state _target-block {:keys [sidebar-properties? tag-dialog?] :as opts}]
|
||||
[state _target-block {:keys [sidebar-properties?] :as opts}]
|
||||
(let [*bidirectional-properties (::bidirectional-properties state)
|
||||
bidirectional-properties @*bidirectional-properties
|
||||
id (::id state)
|
||||
current-db (db/get-db)
|
||||
db-id (:db/id (::block state))
|
||||
block (db/sub-block db-id)
|
||||
show-properties? (or sidebar-properties? tag-dialog?)
|
||||
show-hidden-properties? (let [shown-block-ids (rum/react *show-hidden-properties-block-ids)]
|
||||
(contains? shown-block-ids (:block/uuid block)))
|
||||
show-empty-and-hidden-properties? (let [{:keys [mode show? ids]} (state/sub :ui/show-empty-and-hidden-properties?)]
|
||||
|
||||
@@ -122,7 +122,23 @@
|
||||
}
|
||||
|
||||
.property-panel-edit-btn {
|
||||
@apply inline-flex items-center justify-center p-0 bg-transparent border-0 text-muted-foreground cursor-pointer;
|
||||
@apply inline-flex items-center justify-center p-0 border-0 cursor-pointer opacity-0 pointer-events-none;
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 9999px;
|
||||
color: var(--ls-primary-text-color);
|
||||
background-color: var(--ls-primary-background-color);
|
||||
box-shadow: inset 0 0 0 1px var(--ls-border-color);
|
||||
}
|
||||
|
||||
.property-value-panel:has(.property-value-panel-inner:hover) .property-panel-edit-btn,
|
||||
.property-value-panel:has(.property-value-panel-inner:focus-within) .property-panel-edit-btn,
|
||||
.property-panel-edit-btn:focus-visible {
|
||||
@apply opacity-100 pointer-events-auto;
|
||||
}
|
||||
|
||||
.property-pair {
|
||||
@@ -199,6 +215,10 @@
|
||||
color: var(--ls-primary-text-color);
|
||||
}
|
||||
|
||||
.property-value-panel {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.property-value.property-value-panel-inner > .property-value-inner {
|
||||
@apply w-full min-w-0;
|
||||
}
|
||||
|
||||
@@ -2146,22 +2146,25 @@
|
||||
(util/scroll-to-block sibling-block)
|
||||
(state/exit-editing-and-set-selected-blocks! [sibling-block]))))
|
||||
|
||||
(defn- active-jtrigger?
|
||||
[]
|
||||
(some-> js/document.activeElement (dom/has-class? "jtrigger")))
|
||||
|
||||
(defn- property-value-node?
|
||||
[node]
|
||||
(some-> node (dom/has-class? "property-value-container")))
|
||||
|
||||
(defn- bottom-properties-row-node
|
||||
[node]
|
||||
(some-> node (.closest ".bottom-properties-row")))
|
||||
|
||||
(defn- focus-trigger
|
||||
[_current-block sibling-block]
|
||||
(when-let [trigger (first (dom/by-class sibling-block "jtrigger"))]
|
||||
(state/clear-edit!)
|
||||
(if (or (dom/has-class? trigger "ls-number")
|
||||
(dom/has-class? trigger "ls-empty-text-property"))
|
||||
(.click trigger)
|
||||
(.focus trigger))))
|
||||
(if-let [trigger (first (dom/by-class sibling-block "jtrigger"))]
|
||||
(do
|
||||
(state/clear-edit!)
|
||||
(if (or (dom/has-class? trigger "ls-number")
|
||||
(dom/has-class? trigger "ls-empty-text-property"))
|
||||
(.click trigger)
|
||||
(.focus trigger)))
|
||||
(when-let [row (bottom-properties-row-node sibling-block)]
|
||||
(.focus row))))
|
||||
|
||||
(defn move-cross-boundary-up-down
|
||||
[direction move-opts]
|
||||
@@ -2174,11 +2177,14 @@
|
||||
:up util/get-prev-block-non-collapsed
|
||||
:down util/get-next-block-non-collapsed)
|
||||
current-block (util/rec-get-node input-or-active-element "ls-block")
|
||||
sibling-block (f current-block {:up-down? true})
|
||||
sibling-block (f current-block (cond-> {:up-down? true}
|
||||
(:exclude-property? move-opts)
|
||||
(assoc :exclude-property? true)))
|
||||
{:block/keys [uuid title]} (state/get-edit-block)
|
||||
sibling-block (or (when (property-value-node? sibling-block)
|
||||
(first (dom/by-class sibling-block "ls-block")))
|
||||
sibling-block)
|
||||
bottom-properties-row (bottom-properties-row-node sibling-block)
|
||||
property-value-container? (property-value-node? sibling-block)]
|
||||
(if sibling-block
|
||||
(let [sibling-block-id (dom/attr sibling-block "blockid")
|
||||
@@ -2196,6 +2202,11 @@
|
||||
(util/rec-get-node current-block "ls-page-title"))
|
||||
(.click sibling-block)
|
||||
|
||||
bottom-properties-row
|
||||
(do
|
||||
(state/clear-edit!)
|
||||
(.focus bottom-properties-row))
|
||||
|
||||
property-value-container?
|
||||
(focus-trigger current-block sibling-block)
|
||||
|
||||
@@ -2209,8 +2220,13 @@
|
||||
{:container-id container-id
|
||||
:direction direction})))))
|
||||
(case direction
|
||||
:up (cursor/move-cursor-to input 0)
|
||||
:down (cursor/move-cursor-to-end input)))))))
|
||||
:up (if input
|
||||
(cursor/move-cursor-to input 0)
|
||||
(when current-block
|
||||
(util/scroll-to-block current-block)
|
||||
(state/exit-editing-and-set-selected-blocks! [current-block])))
|
||||
:down (when input
|
||||
(cursor/move-cursor-to-end input))))))))
|
||||
|
||||
(defn keydown-up-down-handler
|
||||
[direction {:keys [_pos] :as move-opts}]
|
||||
@@ -2220,9 +2236,6 @@
|
||||
up? (= direction :up)
|
||||
down? (= direction :down)]
|
||||
(cond
|
||||
(active-jtrigger?)
|
||||
(move-cross-boundary-up-down direction move-opts)
|
||||
|
||||
(not= selected-start selected-end)
|
||||
(if up?
|
||||
(cursor/move-cursor-to input selected-start)
|
||||
@@ -2297,14 +2310,6 @@
|
||||
(and property? left? (not (cursor/start? input)))
|
||||
(cursor/move-cursor-to-start input)
|
||||
|
||||
(and property? right? (cursor/end? input)
|
||||
(or (not= (:logseq.property/type block) :default)
|
||||
(seq (:property/closed-values block))))
|
||||
(let [pair (util/rec-get-node input "property-pair")
|
||||
jtrigger (when pair (dom/sel1 pair ".property-value-container .jtrigger"))]
|
||||
(when jtrigger
|
||||
(.focus jtrigger)))
|
||||
|
||||
(not= selected-start selected-end)
|
||||
(cond
|
||||
left?
|
||||
@@ -2908,7 +2913,7 @@
|
||||
(not (state/get-timestamp-block)))
|
||||
(util/stop e)
|
||||
(cond
|
||||
(or (state/editing?) (active-jtrigger?))
|
||||
(state/editing?)
|
||||
(keydown-up-down-handler direction {})
|
||||
|
||||
(state/selection?)
|
||||
|
||||
@@ -1060,11 +1060,18 @@ Similar to re-frame subscriptions"
|
||||
selected-ids (set (get-selected-block-ids selected-blocks))
|
||||
_ (set-state! :selection/blocks blocks)
|
||||
new-ids (set (get-selection-block-ids))
|
||||
removed (set/difference selected-ids new-ids)]
|
||||
removed (set/difference selected-ids new-ids)
|
||||
next-blocks (set (remove nil? blocks))
|
||||
removed-nodes-without-blockid (->> selected-blocks
|
||||
(remove nil?)
|
||||
(remove #(contains? next-blocks %))
|
||||
(remove #(dom/attr % "blockid")))]
|
||||
(mark-dom-blocks-as-selected blocks)
|
||||
(doseq [id removed]
|
||||
(doseq [node (dom/sel (util/format "[blockid='%s']" id))]
|
||||
(unselect-node node)))))
|
||||
(unselect-node node)))
|
||||
(doseq [node removed-nodes-without-blockid]
|
||||
(unselect-node node))))
|
||||
|
||||
(defn set-selection-blocks!
|
||||
([blocks]
|
||||
|
||||
Reference in New Issue
Block a user