mirror of
https://github.com/penpot/penpot.git
synced 2025-05-02 11:25:55 +02:00
✨ Recalculate token context-menu submenu position
This commit is contained in:
parent
a361e0b990
commit
390cf6b642
2 changed files with 29 additions and 36 deletions
|
@ -307,47 +307,46 @@
|
||||||
|
|
||||||
(mf/defc menu-entry
|
(mf/defc menu-entry
|
||||||
{::mf/props :obj}
|
{::mf/props :obj}
|
||||||
[{:keys [title value hint on-click selected? children submenu-offset submenu-direction no-selectable]}]
|
[{:keys [title value hint on-click selected? children submenu-offset no-selectable]}]
|
||||||
(let [submenu-ref (mf/use-ref nil)
|
(let [submenu-ref (mf/use-ref nil)
|
||||||
hovering? (mf/use-ref false)
|
hovering? (mf/use-ref false)
|
||||||
|
parent-menu-dom-element-pos* (mf/use-state nil)
|
||||||
|
parent-menu-dom-element-pos (deref parent-menu-dom-element-pos*)
|
||||||
|
is-submenu-outside* (mf/use-state false)
|
||||||
|
is-submenu-outside? (deref is-submenu-outside*)
|
||||||
hint? (and hint (seq hint))
|
hint? (and hint (seq hint))
|
||||||
on-pointer-enter
|
on-pointer-enter
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
(mf/deps is-submenu-outside?)
|
||||||
(fn []
|
(fn []
|
||||||
(mf/set-ref-val! hovering? true)
|
(mf/set-ref-val! hovering? true)
|
||||||
(when-let [submenu-node (mf/ref-val submenu-ref)]
|
(when-let [submenu-node (mf/ref-val submenu-ref)]
|
||||||
(dom/set-css-property! submenu-node "display" "block"))))
|
(dom/set-css-property! submenu-node "display" "block")
|
||||||
|
(reset! is-submenu-outside* (dom/is-element-outside? submenu-node)))))
|
||||||
|
|
||||||
on-pointer-leave
|
on-pointer-leave
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
(mf/deps is-submenu-outside?)
|
||||||
(fn []
|
(fn []
|
||||||
(mf/set-ref-val! hovering? false)
|
(mf/set-ref-val! hovering? false)
|
||||||
(when-let [submenu-node (mf/ref-val submenu-ref)]
|
(when-let [submenu-node (mf/ref-val submenu-ref)]
|
||||||
(timers/schedule 50 #(when-not (mf/ref-val hovering?)
|
(timers/schedule 50 #(when-not (mf/ref-val hovering?)
|
||||||
(dom/set-css-property! submenu-node "display" "none"))))))
|
(dom/set-css-property! submenu-node "display" "none")
|
||||||
|
(reset! is-submenu-outside* false))))))
|
||||||
|
|
||||||
set-dom-node
|
get-parent-menu-entry-position
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [dom]
|
(fn [parent-menu-dom-element]
|
||||||
(let [submenu-node (mf/ref-val submenu-ref)]
|
|
||||||
(when (and (some? dom) (some? submenu-node) (= submenu-direction "up"))
|
|
||||||
(dom/set-css-property! submenu-node "top" "unset"))
|
|
||||||
(when (and (some? dom) (some? submenu-node) (= submenu-direction "down"))
|
|
||||||
(dom/set-css-property! submenu-node "top" (dm/str (.-offsetTop dom) "px"))))))]
|
|
||||||
|
|
||||||
(mf/use-effect
|
(when (some? parent-menu-dom-element)
|
||||||
(mf/deps submenu-direction)
|
(reset! parent-menu-dom-element-pos* (dm/str (.-offsetTop parent-menu-dom-element) "px")))))]
|
||||||
(fn []
|
|
||||||
(let [submenu-node (mf/ref-val submenu-ref)]
|
|
||||||
(when (= submenu-direction "up")
|
|
||||||
(dom/set-css-property! submenu-node "top" "unset")))))
|
|
||||||
|
|
||||||
[:li {:class (stl/css-case
|
[:li {:class (stl/css-case
|
||||||
:context-menu-item true
|
:context-menu-item true
|
||||||
:context-menu-item-selected (and (not no-selectable) selected?)
|
:context-menu-item-selected (and (not no-selectable) selected?)
|
||||||
:context-menu-item-unselected (and (not no-selectable) (not selected?))
|
:context-menu-item-unselected (and (not no-selectable) (not selected?))
|
||||||
:context-menu-item-hint-wrapper hint?)
|
:context-menu-item-hint-wrapper hint?)
|
||||||
:ref set-dom-node
|
:ref get-parent-menu-entry-position
|
||||||
:data-value value
|
:data-value value
|
||||||
:on-click on-click
|
:on-click on-click
|
||||||
:on-pointer-enter on-pointer-enter
|
:on-pointer-enter on-pointer-enter
|
||||||
|
@ -361,21 +360,17 @@
|
||||||
(when children
|
(when children
|
||||||
[:*
|
[:*
|
||||||
[:> icon* {:icon-id "arrow" :size "s"}]
|
[:> icon* {:icon-id "arrow" :size "s"}]
|
||||||
[:ul {:class (stl/css :token-context-submenu)
|
[:ul {:ref submenu-ref
|
||||||
:data-direction submenu-direction
|
:class (stl/css-case
|
||||||
:ref submenu-ref
|
:token-context-submenu true
|
||||||
;; Under review: This distances are arbitrary,
|
:token-context-submenu-top is-submenu-outside?)
|
||||||
;; https://tree.taiga.io/project/penpot/task/9627
|
:style {:left (dm/str submenu-offset "px")
|
||||||
:style {:display "none"
|
:top (if is-submenu-outside? "unset" parent-menu-dom-element-pos)}
|
||||||
:--dist (if (= submenu-direction "down")
|
|
||||||
"-80px"
|
|
||||||
"80px")
|
|
||||||
:left (dm/str submenu-offset "px")}
|
|
||||||
:on-context-menu prevent-default}
|
:on-context-menu prevent-default}
|
||||||
children]])]))
|
children]])]))
|
||||||
|
|
||||||
(mf/defc menu-tree
|
(mf/defc menu-tree
|
||||||
[{:keys [selected-shapes submenu-offset submenu-direction type errors] :as context-data}]
|
[{:keys [selected-shapes submenu-offset type errors] :as context-data}]
|
||||||
(let [entries (if (and (not (some? errors))
|
(let [entries (if (and (not (some? errors))
|
||||||
(seq selected-shapes))
|
(seq selected-shapes))
|
||||||
(if (some? type)
|
(if (some? type)
|
||||||
|
@ -389,7 +384,6 @@
|
||||||
submenu [:& menu-entry {:title title
|
submenu [:& menu-entry {:title title
|
||||||
:hint hint
|
:hint hint
|
||||||
:no-selectable true
|
:no-selectable true
|
||||||
:submenu-direction submenu-direction
|
|
||||||
:submenu-offset submenu-offset}
|
:submenu-offset submenu-offset}
|
||||||
[:& menu-tree (assoc context-data :type submenu)]]
|
[:& menu-tree (assoc context-data :type submenu)]]
|
||||||
:else [:& menu-entry
|
:else [:& menu-entry
|
||||||
|
@ -400,7 +394,7 @@
|
||||||
:selected? selected?}])])))
|
:selected? selected?}])])))
|
||||||
|
|
||||||
(mf/defc token-context-menu-tree
|
(mf/defc token-context-menu-tree
|
||||||
[{:keys [width direction errors] :as mdata}]
|
[{:keys [width errors] :as mdata}]
|
||||||
(let [objects (mf/deref refs/workspace-page-objects)
|
(let [objects (mf/deref refs/workspace-page-objects)
|
||||||
selected (mf/deref refs/selected-shapes)
|
selected (mf/deref refs/selected-shapes)
|
||||||
selected-shapes (into [] (keep (d/getf objects)) selected)
|
selected-shapes (into [] (keep (d/getf objects)) selected)
|
||||||
|
@ -409,7 +403,6 @@
|
||||||
selected-token-set-name (mf/deref refs/selected-token-set-name)]
|
selected-token-set-name (mf/deref refs/selected-token-set-name)]
|
||||||
[:ul {:class (stl/css :context-list)}
|
[:ul {:class (stl/css :context-list)}
|
||||||
[:& menu-tree {:submenu-offset width
|
[:& menu-tree {:submenu-offset width
|
||||||
:submenu-direction direction
|
|
||||||
:token token
|
:token token
|
||||||
:errors errors
|
:errors errors
|
||||||
:selected-token-set-name selected-token-set-name
|
:selected-token-set-name selected-token-set-name
|
||||||
|
@ -463,5 +456,5 @@
|
||||||
:left (dm/str left "px")}
|
:left (dm/str left "px")}
|
||||||
:on-context-menu prevent-default}
|
:on-context-menu prevent-default}
|
||||||
(when mdata
|
(when mdata
|
||||||
[:& token-context-menu-tree (assoc mdata :width @width :direction dropdown-direction)])]])
|
[:& token-context-menu-tree (assoc mdata :width @width)])]])
|
||||||
(dom/get-body)))))
|
(dom/get-body)))))
|
||||||
|
|
|
@ -33,12 +33,12 @@
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.token-context-submenu[data-direction="up"] {
|
.token-context-submenu {
|
||||||
bottom: var(--dist);
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.token-context-submenu[data-direction="down"] {
|
.token-context-submenu-top {
|
||||||
top: var(--dist);
|
bottom: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.token-context-submenu {
|
.token-context-submenu {
|
||||||
|
|
Loading…
Add table
Reference in a new issue