0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-24 23:49:45 -05:00

Highlight on track hover

This commit is contained in:
alonso.torres 2023-09-11 14:14:22 +02:00
parent 495ba6e4a4
commit 322767701c
11 changed files with 134 additions and 41 deletions

View file

@ -1088,3 +1088,21 @@
new-shapes (into new-shapes (:shapes parent))]
(assoc parent :shapes (into [] (reverse new-shapes)))))
(defn shapes-by-row
[parent index]
(->> (:layout-grid-cells parent)
(filter (fn [[_ {:keys [row row-span]}]]
(and (>= (inc index) row)
(< (inc index) (+ row row-span)))))
(map second)
(mapcat :shapes)))
(defn shapes-by-column
[parent index]
(->> (:layout-grid-cells parent)
(filter (fn [[_ {:keys [column column-span]}]]
(and (>= (inc index) column)
(< (inc index) (+ column column-span)))))
(map second)
(mapcat :shapes)))

View file

@ -71,7 +71,8 @@
}
}
&:hover {
&:hover,
&.hover {
background-color: $color-primary;
svg {

View file

@ -432,12 +432,22 @@
(ptk/reify ::hover-layout-track
ptk/UpdateEvent
(update [_ state]
(cond-> state
hover?
(update-in [:workspace-grid-edition (first ids) :hover-track] (fnil conj #{}) [type index])
(let [objects (wsh/lookup-page-objects state)
shape (get objects (first ids))
highlighted (when hover?
(->> (if (= type :row)
(ctl/shapes-by-row shape index)
(ctl/shapes-by-column shape index))
(set)))]
(cond-> state
hover?
(update-in [:workspace-grid-edition (first ids) :hover-track] (fnil conj #{}) [type index])
(not hover?)
(update-in [:workspace-grid-edition (first ids) :hover-track] (fnil disj #{}) [type index])))))
(not hover?)
(update-in [:workspace-grid-edition (first ids) :hover-track] (fnil disj #{}) [type index])
:always
(assoc-in [:workspace-local :highlighted] highlighted))))))
(defn change-layout-track
[ids type index props]

View file

@ -126,6 +126,9 @@
[id]
(l/derived #(contains? % id) selected-shapes))
(def highlighted-shapes
(l/derived :highlighted workspace-local))
(def export-in-progress?
(l/derived :export-in-progress? export))

View file

@ -32,7 +32,7 @@
(mf/defc layer-item
{::mf/wrap-props false}
[{:keys [index item selected objects sortable? filtered? depth parent-size component-child?]}]
[{:keys [index item selected objects sortable? filtered? depth parent-size component-child? highlighted]}]
(let [id (:id item)
name (:name item)
blocked? (:blocked item)
@ -50,6 +50,7 @@
expanded? (mf/deref expanded-iref)
selected? (contains? selected id)
highlighted? (contains? highlighted id)
container? (or (cph/frame-shape? item)
(cph/group-shape? item))
absolute? (ctl/layout-absolute? item)
@ -341,6 +342,7 @@
[:div.element-list-body {:class (stl/css-case*
:selected selected?
:hover highlighted?
:icon-layer (= (:type item) :icon))
:on-click select-shape
:on-pointer-enter on-pointer-enter
@ -395,6 +397,7 @@
[:& layer-item
{:item item
:selected selected
:highlighted highlighted
:index index
:objects objects
:key (dm/str id)

View file

@ -43,6 +43,8 @@
[{:keys [objects filtered? parent-size] :as props}]
(let [selected (mf/deref refs/selected-shapes)
selected (hooks/use-equal-memo selected)
highlighted (mf/deref refs/highlighted-shapes)
highlighted (hooks/use-equal-memo highlighted)
root (get objects uuid/zero)
new-css-system (mf/use-ctx ctx/new-css-system)]
[:ul
@ -54,6 +56,7 @@
[:& frame-wrapper
{:item obj
:selected selected
:highlighted highlighted
:index index
:objects objects
:key id
@ -64,6 +67,7 @@
[:& layer-item
{:item obj
:selected selected
:highlighted highlighted
:index index
:objects objects
:key id

View file

@ -1542,7 +1542,7 @@
[:div.layout-row
[:div.jusfiy-content-grid.row-title "Content"]
[:div.btn-wrapper.align-grid
[:div.btn-wrapper.align-grid-content
[:& justify-grid-row {:is-col? true
:justify-items grid-justify-content-column
:set-justify set-content-grid}]

View file

@ -27,7 +27,8 @@
;; --- Page Item
(mf/defc page-item [{:keys [page index deletable? selected? editing?] :as props}]
(mf/defc page-item
[{:keys [page index deletable? selected? editing? hovering?] :as props}]
(let [input-ref (mf/use-ref)
id (:id page)
new-css-system (mf/use-ctx ctx/new-css-system)
@ -135,6 +136,7 @@
(css :selected) selected?)
(dom/classnames
:element-list-body true
:hover hovering?
:selected selected?))
:data-test (dm/str "page-" id)
:tab-index "0"

View file

@ -176,7 +176,8 @@
}
}
}
&:hover {
&:hover,
&.hover {
.element-list-body {
color: var(--layer-row-foreground-color-hover);
background-color: var(--layer-row-background-color-hover);

View file

@ -25,6 +25,7 @@
[app.main.ui.css-cursors :as cur]
[app.main.ui.formats :as fmt]
[app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i]
[app.main.ui.workspace.viewport.viewport-ref :as uwvv]
[app.util.dom :as dom]
[app.util.keyboard :as kbd]
@ -443,10 +444,10 @@
start-p
(cond-> start-p
(and (= type :column) (= index 0))
(gpt/subtract (hv width))
(gpt/subtract (hv (/ width 2)))
(and (= type :row) (= index 0))
(gpt/subtract (vv height))
(gpt/subtract (vv (/ height 2)))
(and (= type :column) (not= index 0) (not last?))
(-> (gpt/subtract (hv (/ layout-gap-col 2)))
@ -605,6 +606,24 @@
(when esc?
(dom/blur! (dom/get-target event))))))
handle-pointer-enter
(mf/use-callback
(mf/deps (:id shape) type index)
(fn []
(st/emit! (dwsl/hover-layout-track [(:id shape)] type index true))))
handle-pointer-leave
(mf/use-callback
(mf/deps (:id shape) type index)
(fn []
(st/emit! (dwsl/hover-layout-track [(:id shape)] type index false))))
handle-remove-track
(mf/use-callback
(mf/deps (:id shape) type index)
(fn []
(st/emit! (dwsl/remove-layout-track [(:id shape)] type index))))
track-list-prop (if (= type :column) :column-tracks :row-tracks)
[text-x text-y text-width text-height]
(if (= type :column)
@ -619,7 +638,9 @@
(dom/set-value! (mf/ref-val track-input-ref) (format-size track-data))))
[:g.track
[:g {:transform (if (= type :column)
[:g {:on-pointer-enter handle-pointer-enter
:on-pointer-leave handle-pointer-leave
:transform (if (= type :column)
(dm/str (gmt/transform-in text-p (:transform shape)))
(dm/str (gmt/transform-in text-p (gmt/rotate (:transform shape) -90))))}
@ -629,17 +650,22 @@
:width (- text-width (/ 10 zoom))
:height (- text-height (/ 5 zoom))
:rx (/ 3 zoom)
:fill "#DB00FF"
:fill "var(--color-distance)"
:opacity 0.2}])
[:foreignObject {:x text-x :y text-y :width text-width :height text-height}
[:input
{:ref track-input-ref
:class (css :grid-editor-label)
:type "text"
:default-value (format-size track-data)
:data-default-value (format-size track-data)
:on-key-down handle-keydown-track-input
:on-blur handle-blur-track-input}]]]
[:div {:class (css :grid-editor-wrapper)}
[:input
{:ref track-input-ref
:style {}
:class (css :grid-editor-label)
:type "text"
:default-value (format-size track-data)
:data-default-value (format-size track-data)
:on-key-down handle-keydown-track-input
:on-blur handle-blur-track-input}]
(when hovering?
[:button {:class (css :grid-editor-button)
:on-click handle-remove-track} i/trash])]]]
[:g {:transform (when (= type :row) (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p)))}
[:& track-marker
@ -755,6 +781,15 @@
[:g.grid-editor {:pointer-events (when view-only "none")
:on-pointer-down handle-pointer-down}
[:g.cells
(for [cell (ctl/get-cells shape {:sort? true})]
[:& grid-cell {:key (dm/str "cell-" (:id cell))
:shape base-shape
:layout-data layout-data
:cell cell
:zoom zoom
:hover? (contains? hover-cells (:id cell))
:selected? (= selected-cells (:id cell))}])]
(when-not view-only
[:*
[:& grid-editor-frame {:zoom zoom
@ -846,14 +881,4 @@
:type :row
:track-before (last row-tracks)
:snap-pixel? snap-pixel?
:zoom zoom}]]))])
[:g.cells
(for [cell (ctl/get-cells shape {:sort? true})]
[:& grid-cell {:key (dm/str "cell-" (:id cell))
:shape base-shape
:layout-data layout-data
:cell cell
:zoom zoom
:hover? (contains? hover-cells (:id cell))
:selected? (= selected-cells (:id cell))}])]]))
:zoom zoom}]]))])]))

View file

@ -11,19 +11,27 @@
}
}
.grid-editor-label {
position: absolute;
background: none;
.grid-editor-wrapper {
width: 100%;
height: 100%;
text-align: center;
font-family: worksans;
height: 80%;
display: flex;
justify-content: center;
align-items: center;
}
.grid-editor-label {
background: none;
border-bottom: calc(1px / var(--zoom)) solid transparent;
border: 0;
color: var(--color-distance);
font-family: worksans;
font-size: calc(12px / var(--zoom));
font-weight: 600;
margin: 0;
max-width: calc(80px / var(--zoom));
padding: 0;
border: 0;
font-size: calc(12px / var(--zoom));
padding: 4px;
text-align: center;
&:focus {
outline: none;
@ -31,6 +39,24 @@
}
}
.grid-editor-button {
background: none;
border: none;
cursor: pointer;
margin: 0;
padding: 0;
position: absolute;
right: calc(10px / var(--zoom));
width: calc(20px / var(--zoom));
height: calc(20px / var(--zoom));
svg {
width: calc(16px / var(--zoom));
height: auto;
fill: var(--color-distance);
}
}
.grid-frame {
fill: #f6f6f6;
stroke: var(--color-distance);