0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-24 07:46:13 -05:00

♻️ Changed layers component to reuse it in viewer

This commit is contained in:
alonso.torres 2023-12-11 13:06:17 +01:00
parent dfd8ff96b7
commit a0a479b08c
5 changed files with 325 additions and 179 deletions

View file

@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect.left-sidebar (ns app.main.ui.viewer.inspect.left-sidebar
(:require-macros [app.main.style :as stl])
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
@ -15,7 +16,9 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.shape-icon :as si] [app.main.ui.components.shape-icon :as si]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.layer-item :refer [layer-item-inner]]
[app.main.ui.workspace.sidebar.layer-name :refer [layer-name]] [app.main.ui.workspace.sidebar.layer-name :refer [layer-name]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.keyboard :as kbd] [app.util.keyboard :as kbd]
@ -28,34 +31,46 @@
(l/derived st/state))) (l/derived st/state)))
(mf/defc layer-item (mf/defc layer-item
[{:keys [item selected objects disable-collapse?] :as props}] [{:keys [item selected objects disable-collapse? depth component-child? hide-toggle?] :as props}]
(let [id (:id item) (let [new-css-system (mf/use-ctx ctx/new-css-system)
id (:id item)
name (:name item) name (:name item)
hidden? (:hidden item) hidden? (:hidden item)
touched? (-> item :touched seq boolean) touched? (-> item :touched seq boolean)
selected? (contains? selected id) selected? (contains? selected id)
item-ref (mf/use-ref nil) item-ref (mf/use-ref nil)
depth (+ depth 1)
file (mf/deref refs/viewer-file) file (mf/deref refs/viewer-file)
components-v2 (dm/get-in file [:data :options :components-v2]) components-v2 (dm/get-in file [:data :options :components-v2])
main-instance? (if components-v2
main-instance?
(if components-v2
(ctk/main-instance? item) (ctk/main-instance? item)
true) true)
collapsed-iref (mf/use-memo
component-tree? (or component-child? (:component-root item))
collapsed-iref
(mf/use-memo
(mf/deps id) (mf/deps id)
(make-collapsed-iref id)) (make-collapsed-iref id))
expanded? (not (mf/deref collapsed-iref)) expanded? (not (mf/deref collapsed-iref))
absolute? (ctl/item-absolute? item) absolute? (ctl/item-absolute? item)
toggle-collapse toggle-collapse
(mf/use-callback
(mf/deps id)
(fn [event] (fn [event]
(dom/stop-propagation event) (dom/stop-propagation event)
(st/emit! (dv/toggle-collapse id))) (st/emit! (dv/toggle-collapse id))))
select-shape select-shape
(mf/use-callback
(mf/deps id)
(fn [event] (fn [event]
(dom/prevent-default event) (dom/prevent-default event)
(let [id (:id item)]
(cond (cond
(kbd/mod? event) (kbd/mod? event)
(st/emit! (dv/toggle-selection id)) (st/emit! (dv/toggle-selection id))
@ -72,6 +87,38 @@
(when (and (= (count selected) 1) selected?) (when (and (= (count selected) 1) selected?)
(dom/scroll-into-view-if-needed! (mf/ref-val item-ref) true)))) (dom/scroll-into-view-if-needed! (mf/ref-val item-ref) true))))
(if new-css-system
[:& layer-item-inner
{:ref item-ref
:item item
:depth depth
:read-only? true
:highlighted? false
:selected? selected?
:component-tree? component-tree?
:hidden? hidden?
:filtered? false
:expanded? expanded?
:hide-toggle? hide-toggle?
:on-select-shape select-shape
:on-toggle-collapse toggle-collapse}
(when (and (:shapes item) expanded?)
[:div {:class (stl/css-case
:element-children true
:parent-selected selected?)}
(for [[index id] (reverse (d/enumerate (:shapes item)))]
(when-let [item (get objects id)]
[:& layer-item
{:item item
:selected selected
:index index
:objects objects
:key (dm/str id)
:depth depth
:component-child? component-tree?}]))])]
;; OLD
[:li {:ref item-ref [:li {:ref item-ref
:class (dom/classnames :class (dom/classnames
:component (not (nil? (:component-id item))) :component (not (nil? (:component-id item)))
@ -108,13 +155,28 @@
:selected selected :selected selected
:index index :index index
:objects objects :objects objects
:key (:id item)}]))])])) :key (:id item)}]))])])))
(mf/defc left-sidebar (mf/defc left-sidebar
[{:keys [frame page local]}] [{:keys [frame page local]}]
(let [selected (:selected local) (let [new-css-system (mf/use-ctx ctx/new-css-system)
selected (:selected local)
objects (:objects page)] objects (:objects page)]
(if new-css-system
[:aside {:class (stl/css :settings-bar-left)}
[:div {:class (stl/css :settings-bar-inside)}
[:div {:class (stl/css :element-list)}
[:& layer-item
{:item frame
:selected selected
:index 0
:objects objects
:sortable? false
:filtered? false
:depth -2
:hide-toggle? true}]]]]
[:aside.settings-bar.settings-bar-left [:aside.settings-bar.settings-bar-left
[:div.settings-bar-inside [:div.settings-bar-inside
[:ul.element-list [:ul.element-list
@ -123,4 +185,4 @@
:selected selected :selected selected
:index 0 :index 0
:objects objects :objects objects
:disable-collapse? true}]]]])) :disable-collapse? true}]]]])))

View file

@ -0,0 +1,22 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@use "common/refactor/common-refactor.scss" as *;
.settings-bar-left {
background-color: $db-primary;
height: 100%;
width: $s-256;
}
.settings-bar-inside {
display: grid;
grid-template-columns: 100%;
grid-template-rows: 100%;
height: calc(100% - $s-2);
overflow-y: auto;
padding-top: $s-8;
}

View file

@ -32,6 +32,129 @@
[okulary.core :as l] [okulary.core :as l]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc layer-item-inner
{::mf/wrap-props false
::mf/forward-ref true}
[{:keys [item depth parent-size name-ref children
;; Flags
read-only? highlighted? selected? component-tree?
filtered? expanded? dnd-over? dnd-over-top? dnd-over-bot? hide-toggle?
;; Callbacks
on-select-shape on-context-menu on-pointer-enter on-pointer-leave on-zoom-to-selected
on-toggle-collapse on-enable-drag on-disable-drag on-toggle-visibility on-toggle-blocking]}
dref]
(let [id (:id item)
name (:name item)
blocked? (:blocked item)
hidden? (:hidden item)
has-shapes? (-> item :shapes seq boolean)
touched? (-> item :touched seq boolean)
parent-board? (and (cfh/frame-shape? item)
(= uuid/zero (:parent-id item)))
absolute? (ctl/item-absolute? item)
components-v2 (mf/use-ctx ctx/components-v2)
main-instance? (or (not components-v2) (:main-instance item))]
[:*
[:div {:id id
:ref dref
:on-click on-select-shape
:on-context-menu on-context-menu
:class (stl/css-case
:layer-row true
:highlight highlighted?
:component (some? (:component-id item))
:masked (:masked-group item)
:selected selected?
:type-frame (cfh/frame-shape? item)
:type-bool (cfh/bool-shape? item)
:type-comp component-tree?
:hidden hidden?
:dnd-over dnd-over?
:dnd-over-top dnd-over-top?
:dnd-over-bot dnd-over-bot?
:root-board parent-board?)}
[:span {:class (stl/css-case
:tab-indentation true
:filtered filtered?)
:style {"--depth" depth}}]
[:div {:class (stl/css-case
:element-list-body true
:filtered filtered?
:selected selected?
:icon-layer (= (:type item) :icon))
:style {"--depth" depth}
:on-pointer-enter on-pointer-enter
:on-pointer-leave on-pointer-leave
:on-double-click dom/stop-propagation}
(if (< 0 (count (:shapes item)))
[:div {:class (stl/css :button-content)}
(when (and (not hide-toggle?) (not filtered?))
[:button {:class (stl/css-case
:toggle-content true
:inverse expanded?)
:on-click on-toggle-collapse}
i/arrow-refactor])
[:div {:class (stl/css :icon-shape)
:on-double-click on-zoom-to-selected}
(when absolute?
[:div {:class (stl/css :absolute)}])
[:& sic/element-icon-refactor
{:shape item
:main-instance? main-instance?}]]]
[:div {:class (stl/css :button-content)}
(when (not ^boolean filtered?)
[:span {:class (stl/css :toggle-content)}])
[:div {:class (stl/css :icon-shape)
:on-double-click on-zoom-to-selected}
(when ^boolean absolute?
[:div {:class (stl/css :absolute)}])
[:& sic/element-icon-refactor
{:shape item
:main-instance? main-instance?}]]])
[:& layer-name {:ref name-ref
:shape-id id
:shape-name name
:shape-touched? touched?
:disabled-double-click read-only?
:on-start-edit on-disable-drag
:on-stop-edit on-enable-drag
:depth depth
:parent-size parent-size
:selected? selected?
:type-comp component-tree?
:type-frame (cfh/frame-shape? item)
:hidden? hidden?}]
(when (not read-only?)
[:div {:class (stl/css-case
:element-actions true
:is-parent has-shapes?
:selected hidden?
:selected blocked?)}
[:button {:class (stl/css-case
:toggle-element true
:selected hidden?)
:title (if hidden?
(tr "workspace.shape.menu.show")
(tr "workspace.shape.menu.hide"))
:on-click on-toggle-visibility}
(if ^boolean hidden? i/hide-refactor i/shown-refactor)]
[:button {:class (stl/css-case
:block-element true
:selected blocked?)
:title (if (:blocked item)
(tr "workspace.shape.menu.unlock")
(tr "workspace.shape.menu.lock"))
:on-click on-toggle-blocking}
(if ^boolean blocked? i/lock-refactor i/unlock-refactor)]])]]
children]))
(mf/defc layer-item (mf/defc layer-item
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [index item selected objects sortable? filtered? depth parent-size component-child? highlighted]}] [{:keys [index item selected objects sortable? filtered? depth parent-size component-child? highlighted]}]
@ -211,114 +334,44 @@
(let [scroll-to @scroll-to-middle?] (let [scroll-to @scroll-to-middle?]
(ts/schedule (ts/schedule
100 100
#(let [scroll-distance-ratio (dom/get-scroll-distance-ratio node scroll-node) #(when (and node scroll-node)
(let [scroll-distance-ratio (dom/get-scroll-distance-ratio node scroll-node)
scroll-behavior (if (> scroll-distance-ratio 1) "instant" "smooth")] scroll-behavior (if (> scroll-distance-ratio 1) "instant" "smooth")]
(if scroll-to (if scroll-to
(dom/scroll-into-view! first-child-node #js {:block "center" :behavior scroll-behavior :inline "start"}) (dom/scroll-into-view! first-child-node #js {:block "center" :behavior scroll-behavior :inline "start"})
(do (do
(dom/scroll-into-view-if-needed! first-child-node #js {:block "center" :behavior scroll-behavior :inline "start"}) (dom/scroll-into-view-if-needed! first-child-node #js {:block "center" :behavior scroll-behavior :inline "start"})
(reset! scroll-to-middle? true)))))))] (reset! scroll-to-middle? true))))))))]
#(when (some? subid) #(when (some? subid)
(rx/dispose! subid)))) (rx/dispose! subid))))
(if new-css-system (if new-css-system
[:* [:& layer-item-inner
[:div {:on-context-menu on-context-menu {:ref dref
:ref dref :item item
:on-click select-shape
:id id
:class (stl/css-case
:layer-row true
:highlight highlighted?
:component (some? (:component-id item))
:masked (:masked-group item)
:selected selected?
:type-frame (cfh/frame-shape? item)
:type-bool (cfh/bool-shape? item)
:type-comp component-tree?
:hidden hidden?
:dnd-over (= (:over dprops) :center)
:dnd-over-top (= (:over dprops) :top)
:dnd-over-bot (= (:over dprops) :bot)
:root-board parent-board?)}
[:span {:class (stl/css-case
:tab-indentation true
:filtered filtered?)
:style {"--depth" depth}}]
[:div {:class (stl/css-case
:element-list-body true
:filtered filtered?
:selected selected?
:icon-layer (= (:type item) :icon))
:style {"--depth" depth}
:on-pointer-enter on-pointer-enter
:on-pointer-leave on-pointer-leave
:on-double-click dom/stop-propagation}
(if (< 0 (count (:shapes item)))
[:div {:class (stl/css :button-content)}
(when (not filtered?)
[:button {:class (stl/css-case
:toggle-content true
:inverse expanded?)
:on-click toggle-collapse}
i/arrow-refactor])
[:div {:class (stl/css :icon-shape)
:on-double-click zoom-to-selected}
(when absolute?
[:div {:class (stl/css :absolute)}])
[:& sic/element-icon-refactor
{:shape item
:main-instance? main-instance?}]]]
[:div {:class (stl/css :button-content)}
(when (not ^boolean filtered?)
[:span {:class (stl/css :toggle-content)}])
[:div {:class (stl/css :icon-shape)
:on-double-click zoom-to-selected}
(when ^boolean absolute?
[:div {:class (stl/css :absolute)}])
[:& sic/element-icon-refactor
{:shape item
:main-instance? main-instance?}]]])
[:& layer-name {:ref ref
:shape-id id
:shape-name name
:shape-touched? touched?
:disabled-double-click read-only?
:on-start-edit disable-drag
:on-stop-edit enable-drag
:depth depth :depth depth
:parent-size parent-size :parent-size parent-size
:name-ref ref
:read-only? read-only?
:highlighted? highlighted?
:selected? selected? :selected? selected?
:type-comp component-tree? :component-tree? component-tree?
:type-frame (cfh/frame-shape? item) :filtered? filtered?
:hidden? hidden?}] :expanded? expanded?
[:div {:class (stl/css-case :dnd-over? (= (:over dprops) :center)
:element-actions true :dnd-over-top? (= (:over dprops) :top)
:is-parent has-shapes? :dnd-over-bot? (= (:over dprops) :bot)
:selected hidden? :on-select-shape select-shape
:selected blocked?)} :on-context-menu on-context-menu
[:button {:class (stl/css-case :on-pointer-enter on-pointer-enter
:toggle-element true :on-pointer-leave on-pointer-leave
:selected hidden?) :on-zoom-to-selected zoom-to-selected
:title (if hidden? :on-toggle-collapse toggle-collapse
(tr "workspace.shape.menu.show") :on-enable-drag enable-drag
(tr "workspace.shape.menu.hide")) :on-disable-drag disable-drag
:on-click toggle-visibility} :on-toggle-visibility toggle-visibility
(if ^boolean hidden? i/hide-refactor i/shown-refactor)] :on-toggle-blocking toggle-blocking}
[:button {:class (stl/css-case
:block-element true
:selected blocked?)
:title (if (:blocked item)
(tr "workspace.shape.menu.unlock")
(tr "workspace.shape.menu.lock"))
:on-click toggle-blocking}
(if ^boolean blocked? i/lock-refactor i/unlock-refactor)]]]]
(when (and (:shapes item) expanded?) (when (and (:shapes item) expanded?)
[:div {:class (stl/css-case [:div {:class (stl/css-case
@ -326,7 +379,6 @@
:parent-selected selected? :parent-selected selected?
:sticky-children parent-board?) :sticky-children parent-board?)
:data-id (when ^boolean parent-board? id)} :data-id (when ^boolean parent-board? id)}
(for [[index id] (reverse (d/enumerate (:shapes item)))] (for [[index id] (reverse (d/enumerate (:shapes item)))]
(when-let [item (get objects id)] (when-let [item (get objects id)]
[:& layer-item [:& layer-item

View file

@ -12,6 +12,7 @@
align-items: center; align-items: center;
width: 100%; width: 100%;
background-color: var(--layer-row-background-color); background-color: var(--layer-row-background-color);
border: 2px solid transparent;
&.highlight, &.highlight,
&:hover { &:hover {
@ -43,6 +44,16 @@
.parent-selected &:hover { .parent-selected &:hover {
background-color: var(--layer-row-background-color-hover); background-color: var(--layer-row-background-color-hover);
} }
&.dnd-over-bot {
border-bottom: $s-2 solid var(--layer-row-foreground-color-hover);
}
&.dnd-over-top {
border-bottom: $s-2 solid var(--layer-row-foreground-color-hover);
}
&.dnd-over {
border: $s-2 solid var(--layer-row-foreground-color-hover);
}
} }
.element-children { .element-children {
@ -164,6 +175,9 @@
.layer-row.hidden & { .layer-row.hidden & {
opacity: $op-7; opacity: $op-7;
} }
.layer-row.selected & {
stroke: var(--layer-row-foreground-color-selected);
}
.layer-row.type-comp & { .layer-row.type-comp & {
stroke: var(--layer-row-component-foreground-color); stroke: var(--layer-row-component-foreground-color);
} }
@ -172,10 +186,6 @@
opacity: $op-10; opacity: $op-10;
stroke: var(--layer-row-foreground-color-hover); stroke: var(--layer-row-foreground-color-hover);
} }
.layer-row.selected & {
stroke: var(--layer-row-foreground-color-selected);
}
} }
.layer-row.selected & { .layer-row.selected & {

View file

@ -47,7 +47,7 @@
highlighted (hooks/use-equal-memo highlighted) highlighted (hooks/use-equal-memo highlighted)
root (get objects uuid/zero) root (get objects uuid/zero)
new-css-system (mf/use-ctx ctx/new-css-system)] new-css-system (mf/use-ctx ctx/new-css-system)]
[:ul [:div
{:class (stl/css new-css-system :element-list)} {:class (stl/css new-css-system :element-list)}
[:& hooks/sortable-container {} [:& hooks/sortable-container {}
(for [[index id] (reverse (d/enumerate (:shapes root)))] (for [[index id] (reverse (d/enumerate (:shapes root)))]