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:
parent
495ba6e4a4
commit
322767701c
11 changed files with 134 additions and 41 deletions
|
@ -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)))
|
||||
|
|
|
@ -71,7 +71,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&.hover {
|
||||
background-color: $color-primary;
|
||||
|
||||
svg {
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}]
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}]]))])]))
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue