Improve property pill behavior and property editing UX

This commit is contained in:
Tienson Qin
2026-04-25 16:00:48 +08:00
parent e8e0d67db7
commit fe651961e4
8 changed files with 73 additions and 27 deletions

View File

@@ -873,7 +873,8 @@
* :title - pluralized class title
* :entities - node entities that reference the target via ref properties"
[db target-id]
(when (and db target-id (d/entity db target-id))
(when (and db target-id
(not (:logseq.property/created-from-property (d/entity db target-id))))
(let [*attr->bidirectional? (volatile! {})
bidirectional-property-attr-cached?
(fn [attr]

View File

@@ -776,25 +776,26 @@
(defn- bottom-position-property?
[db block property]
(let [property-id (:db/ident property)
property-type (:logseq.property/type property)]
property-type (:logseq.property/type property)
node-many? (and (= :node property-type)
(= :db.cardinality/many (:db/cardinality property)))
default-bottom? (and (not= :url property-type)
(or node-many?
(not= :default property-type)
(seq (:property/closed-values property)))
(not (schema-or-tag-related-property? property-id)))]
(if (tag-class-page? db block)
(or (contains? #{:logseq.property.class/extends
:logseq.property.class/enable-bidirectional?}
property-id)
(and (not= :url property-type)
(or (not= :default property-type)
(seq (:property/closed-values property)))
(not (schema-or-tag-related-property? property-id))))
(and (not= :url property-type)
(or (not= :default property-type)
(seq (:property/closed-values property)))
(not (schema-or-tag-related-property? property-id))))))
default-bottom?)
default-bottom?)))
(defn- resolved-property-position
[db block property]
(let [ui-position (:logseq.property/ui-position property)]
(cond
(contains? #{:block-left :block-right :block-below} ui-position)
(contains? #{:properties :block-left :block-right :block-below} ui-position)
ui-position
(bottom-position-property? db block property)

View File

@@ -399,6 +399,24 @@
:logseq.property/type :url
:logseq.property/ui-position :block-left}))))
(testing "explicit properties ui-position keeps property in normal property rows"
(is (false?
(outliner-property/property-with-other-position?
nil
{}
{:db/ident :user.property/p1
:logseq.property/type :number
:logseq.property/ui-position :properties}))))
(testing "many node property without explicit ui-position defaults to bottom position"
(is (true?
(outliner-property/property-with-other-position?
nil
{}
{:db/ident :user.property/p1
:logseq.property/type :node
:db/cardinality :db.cardinality/many}))))
(testing "bidirectional config property stays in normal property rows"
(is (false?
(outliner-property/property-with-other-position?

View File

@@ -2692,16 +2692,21 @@
(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!}
(let [many-node? (and (= :node (:logseq.property/type property))
(= :db.cardinality/many (:db/cardinality property)))]
[:div.bottom-property-pill.bottom-property-pill-focusable
{:key (str (:db/id block) "-" (:db/id property))
:class (util/classnames [{:bottom-property-pill-wrap many-node?}])
: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"
[:div {:class (util/classnames
["bottom-property-content ls-block property-value-container"
{:bottom-property-content-wrap many-node?}])
:style {:min-height 20}}
(pv/property-value block property opts)
(when (contains? #{:date :datetime} (:logseq.property/type property))
@@ -2715,7 +2720,7 @@
(.querySelector ".jtrigger"))]
(.click trigger)
(some-> trigger .focus)))}
(ui/icon "edit" {:size 15})])]])
(ui/icon "edit" {:size 15})])]]))
(defn- block-below-positioned-properties-cp
[block properties opts show-hidden-properties-toggle? show-add-property-button?]

View File

@@ -1070,12 +1070,19 @@ html.is-mac {
}
.bottom-property-pill {
@apply inline-flex items-center gap-1 rounded-full px-2 py-0.5 h-6 max-w-full;
@apply inline-flex items-center gap-1 rounded-full px-2 py-0.5 h-6 max-w-full text-base;
background-color: var(--ls-secondary-background-color);
box-shadow: inset 0 0 0 1px var(--ls-border-color);
position: relative;
}
.bottom-property-pill.bottom-property-pill-wrap {
@apply h-auto;
min-height: 1.5rem; /* keep default 24px baseline, allow growth only when wrapped */
padding-top: 0;
padding-bottom: 0;
}
.bottom-property-pill-focusable:focus {
outline: none;
box-shadow: inset 0 0 0 1px var(--ls-link-text-color);
@@ -1090,7 +1097,15 @@ html.is-mac {
}
.bottom-property-content {
@apply flex items-center gap-1 min-w-0 relative;
@apply flex items-center gap-1 min-w-0 relative text-base;
}
.bottom-property-content.bottom-property-content-wrap {
@apply flex-1 flex-wrap min-w-0;
}
.bottom-property-pill-wrap .multi-values.jtrigger {
@apply min-w-0;
}
.bottom-property-pill .property-key-inner {

View File

@@ -291,7 +291,9 @@
}
.ui__button.empty-btn, .empty-text-btn {
@apply !h-6 !px-0 !text-base opacity-50 font-normal;
@apply !h-6 !px-0 opacity-50 font-normal;
font-size: inherit;
line-height: inherit;
}
.ui__button.empty-btn:hover, .empty-text-btn:hover {

View File

@@ -1359,7 +1359,8 @@
*ref (hooks/use-ref nil)
*input-ref (hooks/use-ref nil)
number-value (db-property/property-value-content value-block)
[value set-value!] (hooks/use-state number-value)
number-value-str (if (some? number-value) (str number-value) "")
[value set-value!] (hooks/use-state number-value-str)
[*value _] (hooks/use-state (atom value))
set-property-value! (fn [value & {:keys [exit-editing?]
:or {exit-editing? true}}]
@@ -1385,9 +1386,9 @@
(hooks/use-effect!
(fn []
(set-value! number-value)
(set-value! number-value-str)
#())
[number-value])
[number-value-str])
[:div.ls-number.flex.flex-1.jtrigger
{:ref *ref
@@ -1433,7 +1434,9 @@
(.focus (rum/deref *ref)))
nil))))})
value)]))
(if (string/blank? value)
(property-empty-btn-value property)
value))]))
(rum/defcs property-scalar-value-aux < rum/static rum/reactive
[state block property value* {:keys [editing? on-chosen]

View File

@@ -51,6 +51,7 @@
min-width: 3em;
}
.ls-properties-area .empty-btn {
.ls-properties-area .empty-btn,
.ls-properties-area .empty-text-btn {
@apply !text-base;
}