Merge pull request #2976 from penpot/alotor-flex-position-absolute

Flex position absolute & z-index
This commit is contained in:
Alejandro 2023-02-24 07:42:43 +01:00 committed by GitHub
commit 8c618f95f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 264 additions and 50 deletions

View file

@ -9,6 +9,8 @@
- Adds paddings and gaps prediction on layout creation [Taiga #4838](https://tree.taiga.io/project/penpot/task/4838) - Adds paddings and gaps prediction on layout creation [Taiga #4838](https://tree.taiga.io/project/penpot/task/4838)
- Add visual feedback when proportionally scaling text elements with **K** [Taiga #3415](https://tree.taiga.io/project/penpot/us/3415) - Add visual feedback when proportionally scaling text elements with **K** [Taiga #3415](https://tree.taiga.io/project/penpot/us/3415)
- Add visualization and mouse control to paddings in frames with layout [Taiga #4839](https://tree.taiga.io/project/penpot/task/4839) - Add visualization and mouse control to paddings in frames with layout [Taiga #4839](https://tree.taiga.io/project/penpot/task/4839)
- Allow for absolute positioned elements inside layout [Taiga #4834](https://tree.taiga.io/project/penpot/us/4834)
- Add z-index option for flex layout items [Taiga #2980](https://tree.taiga.io/project/penpot/us/2980)
### :bug: Bugs fixed ### :bug: Bugs fixed

View file

@ -288,7 +288,7 @@
constraints-h constraints-h
(cond (cond
(ctl/layout? parent) (and (ctl/layout? parent) (not (ctl/layout-absolute? child)))
:left :left
(not ignore-constraints) (not ignore-constraints)
@ -299,7 +299,7 @@
constraints-v constraints-v
(cond (cond
(ctl/layout? parent) (and (ctl/layout? parent) (not (ctl/layout-absolute? child)))
:top :top
(not ignore-constraints) (not ignore-constraints)

View file

@ -94,9 +94,8 @@
(defn- set-children-modifiers (defn- set-children-modifiers
"Propagates the modifiers from a parent too its children applying constraints if necesary" "Propagates the modifiers from a parent too its children applying constraints if necesary"
[modif-tree objects bounds parent transformed-parent-bounds ignore-constraints] [modif-tree children objects bounds parent transformed-parent-bounds ignore-constraints]
(let [children (:shapes parent) (let [modifiers (dm/get-in modif-tree [(:id parent) :modifiers])]
modifiers (dm/get-in modif-tree [(:id parent) :modifiers])]
;; Move modifiers don't need to calculate constraints ;; Move modifiers don't need to calculate constraints
(if (ctm/only-move? modifiers) (if (ctm/only-move? modifiers)
@ -155,7 +154,7 @@
(gtr/transform-bounds modifiers))))) (gtr/transform-bounds modifiers)))))
(defn- set-layout-modifiers (defn- set-layout-modifiers
[modif-tree objects bounds parent transformed-parent-bounds] [modif-tree children objects bounds parent transformed-parent-bounds]
(letfn [(apply-modifiers [child] (letfn [(apply-modifiers [child]
[(-> (get-group-bounds objects bounds modif-tree child) [(-> (get-group-bounds objects bounds modif-tree child)
@ -173,7 +172,8 @@
[layout-line modif-tree]))] [layout-line modif-tree]))]
(let [children (->> (cph/get-immediate-children objects (:id parent)) (let [children (->> children
(map (d/getf objects))
(remove :hidden) (remove :hidden)
(map apply-modifiers)) (map apply-modifiers))
layout-data (gcl/calc-layout-data parent children @transformed-parent-bounds) layout-data (gcl/calc-layout-data parent children @transformed-parent-bounds)
@ -235,6 +235,7 @@
"Propagate modifiers to its children" "Propagate modifiers to its children"
[objects bounds ignore-constraints modif-tree parent] [objects bounds ignore-constraints modif-tree parent]
(let [parent-id (:id parent) (let [parent-id (:id parent)
children (:shapes parent)
root? (= uuid/zero parent-id) root? (= uuid/zero parent-id)
modifiers (-> (dm/get-in modif-tree [parent-id :modifiers]) modifiers (-> (dm/get-in modif-tree [parent-id :modifiers])
(ctm/select-geometry)) (ctm/select-geometry))
@ -244,7 +245,7 @@
(cond-> modif-tree (cond-> modif-tree
(and has-modifiers? parent? (not root?)) (and has-modifiers? parent? (not root?))
(set-children-modifiers objects bounds parent transformed-parent-bounds ignore-constraints)))) (set-children-modifiers children objects bounds parent transformed-parent-bounds ignore-constraints))))
(defn- propagate-modifiers-layout (defn- propagate-modifiers-layout
"Propagate modifiers to its children" "Propagate modifiers to its children"
@ -258,14 +259,25 @@
auto? (or (ctl/auto-height? parent) (ctl/auto-width? parent)) auto? (or (ctl/auto-height? parent) (ctl/auto-width? parent))
parent? (or (cph/group-like-shape? parent) (cph/frame-shape? parent)) parent? (or (cph/group-like-shape? parent) (cph/frame-shape? parent))
transformed-parent-bounds (delay (gtr/transform-bounds @(get bounds parent-id) modifiers))] transformed-parent-bounds (delay (gtr/transform-bounds @(get bounds parent-id) modifiers))
children-modifiers
(if layout?
(->> (:shapes parent)
(filter #(ctl/layout-absolute? objects %)))
(:shapes parent))
children-layout
(when layout?
(->> (:shapes parent)
(remove #(ctl/layout-absolute? objects %))))]
[(cond-> modif-tree [(cond-> modif-tree
(and (not layout?) has-modifiers? parent? (not root?)) (and has-modifiers? parent? (not root?))
(set-children-modifiers objects bounds parent transformed-parent-bounds ignore-constraints) (set-children-modifiers children-modifiers objects bounds parent transformed-parent-bounds ignore-constraints)
layout? layout?
(set-layout-modifiers objects bounds parent transformed-parent-bounds)) (set-layout-modifiers children-layout objects bounds parent transformed-parent-bounds))
;; Auto-width/height can change the positions in the parent so we need to recalculate ;; Auto-width/height can change the positions in the parent so we need to recalculate
(cond-> autolayouts auto? (conj (:id parent)))])) (cond-> autolayouts auto? (conj (:id parent)))]))

View file

@ -198,7 +198,9 @@
:layout-item-min-h :layout-item-min-h
:layout-item-max-w :layout-item-max-w
:layout-item-min-w :layout-item-min-w
:layout-item-align-self} :layout-item-align-self
:layout-item-absolute
:layout-item-z-index}
:rect #{:proportion-lock :rect #{:proportion-lock
:width :height :width :height

View file

@ -9,6 +9,7 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[cuerdas.core :as str])) [cuerdas.core :as str]))
@ -527,3 +528,18 @@
(d/seek root-frame?) (d/seek root-frame?)
:id)) :id))
(defn comparator-layout-z-index
[[idx-a child-a] [idx-b child-b]]
(cond
(> (ctl/layout-z-index child-a) (ctl/layout-z-index child-b)) 1
(< (ctl/layout-z-index child-a) (ctl/layout-z-index child-b)) -1
(> idx-a idx-b) 1
(< idx-a idx-b) -1
:else 0))
(defn sort-layout-children-z-index
[children]
(->> children
(d/enumerate)
(sort comparator-layout-z-index)
(mapv second)))

View file

@ -30,6 +30,8 @@
;; :layout-item-min-h ;; num ;; :layout-item-min-h ;; num
;; :layout-item-max-w ;; num ;; :layout-item-max-w ;; num
;; :layout-item-min-w ;; num ;; :layout-item-min-w ;; num
;; :layout-item-absolute
;; :layout-item-z-index
(s/def ::layout #{:flex :grid}) (s/def ::layout #{:flex :grid})
(s/def ::layout-flex-dir #{:row :reverse-row :row-reverse :column :reverse-column :column-reverse}) ;;TODO remove reverse-column and reverse-row after script (s/def ::layout-flex-dir #{:row :reverse-row :row-reverse :column :reverse-column :column-reverse}) ;;TODO remove reverse-column and reverse-row after script
@ -82,6 +84,8 @@
(s/def ::layout-item-min-h ::us/safe-number) (s/def ::layout-item-min-h ::us/safe-number)
(s/def ::layout-item-max-w ::us/safe-number) (s/def ::layout-item-max-w ::us/safe-number)
(s/def ::layout-item-min-w ::us/safe-number) (s/def ::layout-item-min-w ::us/safe-number)
(s/def ::layout-item-absolute boolean?)
(s/def ::layout-item-z-index ::us/safe-integer)
(s/def ::layout-child-props (s/def ::layout-child-props
(s/keys :opt-un [::layout-item-margin (s/keys :opt-un [::layout-item-margin
@ -92,7 +96,9 @@
::layout-item-min-h ::layout-item-min-h
::layout-item-max-w ::layout-item-max-w
::layout-item-min-w ::layout-item-min-w
::layout-item-align-self])) ::layout-item-align-self
::layout-item-absolute
::layout-item-z-index]))
(defn layout? (defn layout?
([objects id] ([objects id]
@ -357,3 +363,44 @@
(some (partial fill-height? objects) children-ids)) (some (partial fill-height? objects) children-ids))
(and (row? objects frame-id) (and (row? objects frame-id)
(every? (partial fill-height? objects) children-ids))))) (every? (partial fill-height? objects) children-ids)))))
(defn layout-absolute?
([objects id]
(layout-absolute? (get objects id)))
([shape]
(true? (:layout-item-absolute shape))))
(defn layout-z-index
([objects id]
(layout-z-index (get objects id)))
([shape]
(or (:layout-item-z-index shape) 0)))
(defn remove-layout-container-data
[shape]
(dissoc shape
:layout
:layout-flex-dir
:layout-gap
:layout-gap-type
:layout-wrap-type
:layout-padding-type
:layout-padding
:layout-justify-content
:layout-align-items
:layout-align-content))
(defn remove-layout-item-data
[shape]
(dissoc shape
:layout-item-margin
:layout-item-margin-type
:layout-item-h-sizing
:layout-item-v-sizing
:layout-item-max-h
:layout-item-min-h
:layout-item-max-w
:layout-item-min-w
:layout-item-align-self
:layout-item-absolute
:layout-item-z-index))

View file

@ -14,6 +14,7 @@
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.types.shape :as cts] [app.common.types.shape :as cts]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[clojure.spec.alpha :as s])) [clojure.spec.alpha :as s]))
@ -161,7 +162,16 @@
;; Check which index is lower ;; Check which index is lower
:else :else
(< index-a index-b)))) ;; If the base is a layout we should check if the z-index property is set
(let [[z-index-a z-index-b]
(if (ctl/layout? objects base)
[(ctl/layout-z-index objects (dm/get-in objects [base :shapes index-a]))
(ctl/layout-z-index objects (dm/get-in objects [base :shapes index-b]))]
[0 0])]
(if (= z-index-a z-index-b)
(< index-a index-b)
(< z-index-a z-index-b))))))
(defn sort-z-index (defn sort-z-index
([objects ids] ([objects ids]

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="-1.786 -18.5 500 500">
<path d="M15.4-18.5-1.785-1.314l18.898 18.9L34.3.398Zm85.903 0L-1.785 84.59l18.898 18.898L120.203.398Zm85.904 0L-1.785 170.492l18.898 18.9L206.105.399Zm85.93 0L-1.785 256.422l18.898 18.9L292.035.398Zm85.902 0L-1.785 342.326l18.898 18.899L377.94.398Zm85.904 0L-1.785 428.229l18.898 18.9L463.842.399Zm34.371 51.559L49.771 462.599l18.9 18.901L498.216 51.957Zm0 85.902L135.676 462.6l18.898 18.9 343.64-343.639Zm0 85.904L221.578 462.6l18.9 18.9 257.737-257.736Zm0 85.903L307.482 462.6l18.899 18.9 171.834-171.834Zm0 85.93L393.412 462.6l18.899 18.9 85.904-85.902z"/>
</svg>

After

Width:  |  Height:  |  Size: 667 B

View file

@ -1672,7 +1672,8 @@
.align-self-style, .align-self-style,
.justify-content-style, .justify-content-style,
.align-content-style, .align-content-style,
.layout-behavior { .layout-behavior,
.absolute {
display: flex; display: flex;
border-radius: $br4; border-radius: $br4;
border: 1px solid $color-gray-60; border: 1px solid $color-gray-60;
@ -1693,8 +1694,10 @@
border: none; border: none;
cursor: pointer; cursor: pointer;
border-right: 1px solid $color-gray-60; border-right: 1px solid $color-gray-60;
color: $color-gray-20;
&.active, &.active,
&:hover { &:hover {
color: $color-primary;
svg { svg {
fill: $color-primary; fill: $color-primary;
} }
@ -1736,6 +1739,15 @@
border-right: none; border-right: none;
} }
} }
.z-index {
display: flex;
align-items: center;
margin-left: 2px;
margin-top: -4px;
svg {
width: 30px;
}
}
} }
} }
.no-wrap { .no-wrap {

View file

@ -13,12 +13,44 @@
transition: none; transition: none;
width: 100%; width: 100%;
.icon {
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin-right: 4px;
margin-bottom: 3px;
width: 18px;
height: 18px;
svg { svg {
fill: $color-gray-20; fill: $color-gray-20;
height: 13px; height: 12px;
flex-shrink: 0; width: 12px;
margin-right: 8px; }
width: 13px;
& .absolute {
position: absolute;
top: 0;
left: 0;
width: 18px;
height: 18px;
svg {
width: 18px;
height: 18px;
fill: $color-gray-20;
fill-opacity: 0.3;
}
}
}
&.selected .icon .absolute svg {
fill: $color-primary;
}
&:hover .icon .absolute svg {
fill: $color-gray-60;
} }
&.group { &.group {

View file

@ -651,6 +651,10 @@
(-> (pcb/empty-changes it page-id) (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects) (pcb/with-objects objects)
;; Remove layout-item properties when moving a shape outside a layout
(cond-> (not (ctl/layout? objects parent-id))
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
;; Move the shapes ;; Move the shapes
(pcb/change-parent parent-id (pcb/change-parent parent-id
shapes shapes

View file

@ -11,6 +11,7 @@
[app.common.pages.changes-builder :as pcb] [app.common.pages.changes-builder :as pcb]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.path.shapes-to-path :as stp] [app.common.path.shapes-to-path :as stp]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.main.data.workspace.changes :as dch] [app.main.data.workspace.changes :as dch]
[app.main.data.workspace.selection :as dws] [app.main.data.workspace.selection :as dws]
@ -98,6 +99,7 @@
changes (-> (pcb/empty-changes it page-id) changes (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects) (pcb/with-objects objects)
(pcb/add-object boolean-data {:index index}) (pcb/add-object boolean-data {:index index})
(pcb/update-shapes (map :id shapes) ctl/remove-layout-item-data)
(pcb/change-parent shape-id shapes))] (pcb/change-parent shape-id shapes))]
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(dws/select-shapes (d/ordered-set shape-id))))))))) (dws/select-shapes (d/ordered-set shape-id)))))))))

View file

@ -12,6 +12,7 @@
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.types.component :as ctk] [app.common.types.component :as ctk]
[app.common.types.shape :as cts] [app.common.types.shape :as cts]
[app.common.types.shape.layout :as ctl]
[app.main.data.workspace.changes :as dch] [app.main.data.workspace.changes :as dch]
[app.main.data.workspace.selection :as dws] [app.main.data.workspace.selection :as dws]
[app.main.data.workspace.state-helpers :as wsh] [app.main.data.workspace.state-helpers :as wsh]
@ -98,6 +99,7 @@
changes (-> (pcb/empty-changes it page-id) changes (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects) (pcb/with-objects objects)
(pcb/add-object group {:index group-idx}) (pcb/add-object group {:index group-idx})
(pcb/update-shapes (map :id shapes) ctl/remove-layout-item-data)
(pcb/change-parent (:id group) (reverse shapes)) (pcb/change-parent (:id group) (reverse shapes))
(pcb/update-shapes (map :id shapes-to-detach) ctk/detach-shape) (pcb/update-shapes (map :id shapes-to-detach) ctk/detach-shape)
(pcb/remove-objects ids-to-delete))] (pcb/remove-objects ids-to-delete))]
@ -142,6 +144,8 @@
(-> (pcb/empty-changes it page-id) (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects) (pcb/with-objects objects)
(cond-> (ctl/layout? frame)
(pcb/update-shapes (:shapes frame) ctl/remove-layout-item-data))
(pcb/change-parent parent-id children idx-in-parent) (pcb/change-parent parent-id children idx-in-parent)
(pcb/remove-objects [(:id frame)])))) (pcb/remove-objects [(:id frame)]))))

View file

@ -149,17 +149,19 @@
children-ids (into [] (mapcat #(get-in objects [% :shapes])) ids) children-ids (into [] (mapcat #(get-in objects [% :shapes])) ids)
children-shapes (map (d/getf objects) children-ids) children-shapes (map (d/getf objects) children-ids)
parent (get objects (first ids)) parent (get objects (first ids))
flex-params (shapes->flex-params objects children-shapes parent) flex-params (when (d/not-empty? children-shapes)
(shapes->flex-params objects children-shapes parent))
undo-id (js/Symbol)] undo-id (js/Symbol)]
(rx/of (dwu/start-undo-transaction undo-id) (rx/of (dwu/start-undo-transaction undo-id)
(dwc/update-shapes ids (get-layout-initializer type from-frame?)) (dwc/update-shapes ids (get-layout-initializer type from-frame?))
(dwc/update-shapes (dwc/update-shapes
ids ids
(fn [shape] (fn [shape]
(-> shape (cond-> shape
(assoc :layout-item-h-sizing :auto (not from-frame?)
(-> (assoc :layout-item-h-sizing :auto
:layout-item-v-sizing :auto) :layout-item-v-sizing :auto)
(merge flex-params)))) (merge flex-params)))))
(ptk/data-event :layout/update ids) (ptk/data-event :layout/update ids)
(dwc/update-shapes children-ids #(dissoc % :constraints-h :constraints-v)) (dwc/update-shapes children-ids #(dissoc % :constraints-h :constraints-v))
(dwu/commit-undo-transaction undo-id)))))) (dwu/commit-undo-transaction undo-id))))))

View file

@ -131,6 +131,8 @@
(when (d/not-empty? to-move-shapes) (when (d/not-empty? to-move-shapes)
(-> (pcb/empty-changes it page-id) (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects) (pcb/with-objects objects)
(cond-> (not (ctl/layout? objects frame-id))
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
(pcb/change-parent frame-id to-move-shapes 0)))] (pcb/change-parent frame-id to-move-shapes 0)))]
(if (some? changes) (if (some? changes)

View file

@ -729,13 +729,15 @@
changes changes
(-> (pcb/empty-changes it page-id) (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects) (pcb/with-objects objects)
;; Remove layout-item properties when moving a shape outside a layout
(cond-> (not (ctl/layout? objects frame-id))
(pcb/update-shapes (map :id moving-shapes) ctl/remove-layout-item-data))
(pcb/change-parent frame-id moving-shapes drop-index) (pcb/change-parent frame-id moving-shapes drop-index)
(pcb/remove-objects empty-parents))] (pcb/remove-objects empty-parents))]
(when (and (some? frame-id) (d/not-empty? changes)) (when (and (some? frame-id) (d/not-empty? changes))
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(dwc/expand-collapse frame-id))))))) (dwc/expand-collapse frame-id)))))))
(defn- get-displacement (defn- get-displacement
"Retrieve the correct displacement delta point for the "Retrieve the correct displacement delta point for the
provided direction speed and distances thresholds." provided direction speed and distances thresholds."

View file

@ -185,6 +185,7 @@
(def play (icon-xref :play)) (def play (icon-xref :play))
(def plus (icon-xref :plus)) (def plus (icon-xref :plus))
(def pointer-inner (icon-xref :pointer-inner)) (def pointer-inner (icon-xref :pointer-inner))
(def position-absolute (icon-xref :position-absolute))
(def position-bottom-center (icon-xref :position-bottom-center)) (def position-bottom-center (icon-xref :position-bottom-center))
(def position-bottom-left (icon-xref :position-bottom-left)) (def position-bottom-left (icon-xref :position-bottom-left))
(def position-bottom-right (icon-xref :position-bottom-right)) (def position-bottom-right (icon-xref :position-bottom-right))

View file

@ -8,6 +8,8 @@
(:require (:require
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.pages.helpers :as cph]
[app.common.types.shape.layout :as ctl]
[app.config :as cf] [app.config :as cf]
[app.main.ui.context :as muc] [app.main.ui.context :as muc]
[app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.attrs :as attrs]
@ -125,7 +127,10 @@
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [shape (unchecked-get props "shape") (let [shape (unchecked-get props "shape")
childs (unchecked-get props "childs")] childs (unchecked-get props "childs")
childs (cond-> childs
(ctl/layout? shape)
(cph/sort-layout-children-z-index))]
[:> frame-container props [:> frame-container props
[:g.frame-children {:opacity (:opacity shape)} [:g.frame-children {:opacity (:opacity shape)}
(for [item childs] (for [item childs]

View file

@ -9,6 +9,7 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.collapse :as dwc] [app.main.data.workspace.collapse :as dwc]
@ -101,6 +102,7 @@
selected? (contains? selected id) selected? (contains? selected id)
container? (or (cph/frame-shape? item) container? (or (cph/frame-shape? item)
(cph/group-shape? item)) (cph/group-shape? item))
absolute? (ctl/layout-absolute? item)
components-v2 (mf/use-ctx ctx/components-v2) components-v2 (mf/use-ctx ctx/components-v2)
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?) workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
@ -253,9 +255,11 @@
:on-pointer-enter on-pointer-enter :on-pointer-enter on-pointer-enter
:on-pointer-leave on-pointer-leave :on-pointer-leave on-pointer-leave
:on-double-click #(dom/stop-propagation %)} :on-double-click #(dom/stop-propagation %)}
[:div {:on-double-click #(do (dom/stop-propagation %) [:div.icon {:on-double-click #(do (dom/stop-propagation %)
(dom/prevent-default %) (dom/prevent-default %)
(st/emit! dw/zoom-to-selected-shape))} (st/emit! dw/zoom-to-selected-shape))}
(when absolute?
[:div.absolute i/position-absolute])
[:& si/element-icon {:shape item [:& si/element-icon {:shape item
:main-instance? main-instance?}]] :main-instance? main-instance?}]]
[:& layer-name {:shape item [:& layer-name {:shape item

View file

@ -29,7 +29,8 @@
:layout-item-max-w ;; num :layout-item-max-w ;; num
:layout-item-min-w ;; num :layout-item-min-w ;; num
:layout-item-align-self ;; :start :end :center :stretch :baseline :layout-item-align-self ;; :start :end :center :stretch :baseline
]) :layout-item-absolute
:layout-item-z-index])
(mf/defc margin-section (mf/defc margin-section
[{:keys [values change-margin-style on-margin-change] :as props}] [{:keys [values change-margin-style on-margin-change] :as props}]
@ -193,13 +194,44 @@
on-size-change on-size-change
(fn [measure value] (fn [measure value]
(st/emit! (dwsl/update-layout-child ids {measure value})))] (st/emit! (dwsl/update-layout-child ids {measure value})))
on-change-position
(fn [value]
(st/emit! (dwsl/update-layout-child ids {:layout-item-absolute (= value :absolute)})))
on-change-z-index
(fn [value]
(st/emit! (dwsl/update-layout-child ids {:layout-item-z-index value})))]
[:div.element-set [:div.element-set
[:div.element-set-title [:div.element-set-title
[:span "Flex elements"]] [:span "Flex elements"]]
[:div.element-set-content.layout-item-menu [:div.element-set-content.layout-item-menu
[:div.layout-row
[:div.row-title.sizing "Position"]
[:div.btn-wrapper
[:div.absolute
[:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Static"
:class (dom/classnames :active (not (:layout-item-absolute values)))
:on-click #(on-change-position :static)}
"Static"]
[:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Absolute"
:class (dom/classnames :active (and (:layout-item-absolute values) (not= :multiple (:layout-item-absolute values))))
:on-click #(on-change-position :absolute)}
"Absolute"]]
[:div.tooltip.tooltip-bottom-left.z-index {:alt "z-index"}
i/layers
[:> numeric-input
{:placeholder "--"
:on-click #(dom/select-target %)
:on-change #(on-change-z-index %)
:value (:layout-item-z-index values)}]]]]
[:div.layout-row [:div.layout-row
[:div.row-title.sizing "Sizing"] [:div.row-title.sizing "Sizing"]
[:& element-behavior {:is-layout-child? is-layout-child? [:& element-behavior {:is-layout-child? is-layout-child?

View file

@ -6,6 +6,7 @@
(ns app.main.ui.workspace.sidebar.options.shapes.bool (ns app.main.ui.workspace.sidebar.options.shapes.bool
(:require (:require
[app.common.types.shape.layout :as ctl]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
@ -30,7 +31,9 @@
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref)] is-layout-child? (mf/deref is-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids ids [:& measures-menu {:ids ids
:type type :type type
@ -46,7 +49,7 @@
:is-layout-child? true :is-layout-child? true
:shape shape}]) :shape shape}])
(when (not is-layout-child?) (when (or (not is-layout-child?) is-layout-child-absolute?)
[:& constraints-menu {:ids ids [:& constraints-menu {:ids ids
:values constraint-values}]) :values constraint-values}])
[:& layer-menu {:ids ids [:& layer-menu {:ids ids

View file

@ -6,6 +6,7 @@
(ns app.main.ui.workspace.sidebar.options.shapes.circle (ns app.main.ui.workspace.sidebar.options.shapes.circle
(:require (:require
[app.common.types.shape.layout :as ctl]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
@ -32,7 +33,9 @@
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref)] is-layout-child? (mf/deref is-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids ids [:& measures-menu {:ids ids
:type type :type type
@ -47,7 +50,7 @@
:is-layout-child? true :is-layout-child? true
:is-layout-container? false :is-layout-container? false
:shape shape}]) :shape shape}])
(when (not is-layout-child?) (when (or (not is-layout-child?) is-layout-child-absolute?)
[:& constraints-menu {:ids ids [:& constraints-menu {:ids ids
:values constraint-values}]) :values constraint-values}])
[:& layer-menu {:ids ids [:& layer-menu {:ids ids

View file

@ -38,7 +38,8 @@
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref) is-layout-child? (mf/deref is-layout-child-ref)
is-layout-container? (ctl/layout? shape)] is-layout-container? (ctl/layout? shape)
is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids [(:id shape)] [:& measures-menu {:ids [(:id shape)]
:values measure-values :values measure-values
@ -47,7 +48,7 @@
[:& component-menu {:ids comp-ids [:& component-menu {:ids comp-ids
:values comp-values :values comp-values
:shape-name (:name shape)}] :shape-name (:name shape)}]
(when (not is-layout-child?) (when (or (not is-layout-child?) is-layout-child-absolute?)
[:& constraints-menu {:ids ids [:& constraints-menu {:ids ids
:values constraint-values}]) :values constraint-values}])
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}] [:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]

View file

@ -7,6 +7,7 @@
(ns app.main.ui.workspace.sidebar.options.shapes.group (ns app.main.ui.workspace.sidebar.options.shapes.group
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.types.shape.layout :as ctl]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]] [app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]]
@ -37,6 +38,7 @@
ids [(:id shape)] ids [(:id shape)]
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref) is-layout-child? (mf/deref is-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)
type :group type :group
[measure-ids measure-values] (get-attrs [shape] objects :measure) [measure-ids measure-values] (get-attrs [shape] objects :measure)
@ -64,8 +66,9 @@
:is-layout-container? false :is-layout-container? false
:values layout-item-values}]) :values layout-item-values}])
(when (not is-layout-child?) (when (or (not is-layout-child?) is-layout-child-absolute?)
[:& constraints-menu {:ids constraint-ids :values constraint-values}]) [:& constraints-menu {:ids constraint-ids :values constraint-values}])
[:& layer-menu {:type type :ids layer-ids :values layer-values}] [:& layer-menu {:type type :ids layer-ids :values layer-values}]
(when-not (empty? fill-ids) (when-not (empty? fill-ids)

View file

@ -6,6 +6,7 @@
(ns app.main.ui.workspace.sidebar.options.shapes.image (ns app.main.ui.workspace.sidebar.options.shapes.image
(:require (:require
[app.common.types.shape.layout :as ctl]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
@ -32,7 +33,8 @@
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref)] is-layout-child? (mf/deref is-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids ids [:& measures-menu {:ids ids
:type type :type type
@ -48,7 +50,7 @@
:is-layout-child? true :is-layout-child? true
:shape shape}]) :shape shape}])
(when (not is-layout-child?) (when (or (not is-layout-child?) is-layout-child-absolute?)
[:& constraints-menu {:ids ids [:& constraints-menu {:ids ids
:values constraint-values}]) :values constraint-values}])

View file

@ -6,6 +6,7 @@
(ns app.main.ui.workspace.sidebar.options.shapes.path (ns app.main.ui.workspace.sidebar.options.shapes.path
(:require (:require
[app.common.types.shape.layout :as ctl]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
@ -32,7 +33,8 @@
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref)] is-layout-child? (mf/deref is-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids ids [:& measures-menu {:ids ids
:type type :type type
@ -47,7 +49,7 @@
:is-layout-child? true :is-layout-child? true
:is-layout-container? false :is-layout-container? false
:shape shape}]) :shape shape}])
(when (not is-layout-child?) (when (or (not is-layout-child?) is-layout-child-absolute?)
[:& constraints-menu {:ids ids [:& constraints-menu {:ids ids
:values constraint-values}]) :values constraint-values}])
[:& layer-menu {:ids ids [:& layer-menu {:ids ids

View file

@ -6,6 +6,7 @@
(ns app.main.ui.workspace.sidebar.options.shapes.rect (ns app.main.ui.workspace.sidebar.options.shapes.rect
(:require (:require
[app.common.types.shape.layout :as ctl]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
@ -32,7 +33,8 @@
layout-item-values (select-keys shape layout-item-attrs) layout-item-values (select-keys shape layout-item-attrs)
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref)] is-layout-child? (mf/deref is-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids ids [:& measures-menu {:ids ids
:type type :type type
@ -47,7 +49,7 @@
:is-layout-child? true :is-layout-child? true
:shape shape}]) :shape shape}])
(when (not is-layout-child?) (when (or (not is-layout-child?) is-layout-child-absolute?)
[:& constraints-menu {:ids ids [:& constraints-menu {:ids ids
:values constraint-values}]) :values constraint-values}])

View file

@ -8,6 +8,7 @@
(:require (:require
[app.common.colors :as clr] [app.common.colors :as clr]
[app.common.data :as d] [app.common.data :as d]
[app.common.types.shape.layout :as ctl]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
@ -106,7 +107,8 @@
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref)] is-layout-child? (mf/deref is-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)]
(when (contains? svg-elements tag) (when (contains? svg-elements tag)
[:* [:*
@ -124,7 +126,7 @@
:is-layout-child? true :is-layout-child? true
:shape shape}]) :shape shape}])
(when (not is-layout-child?) (when (or (not is-layout-child?) is-layout-child-absolute?)
[:& constraints-menu {:ids ids [:& constraints-menu {:ids ids
:values constraint-values}]) :values constraint-values}])

View file

@ -7,6 +7,7 @@
(ns app.main.ui.workspace.sidebar.options.shapes.text (ns app.main.ui.workspace.sidebar.options.shapes.text
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.types.shape.layout :as ctl]
[app.main.data.workspace.texts :as dwt :refer [text-fill-attrs root-attrs paragraph-attrs text-attrs]] [app.main.data.workspace.texts :as dwt :refer [text-fill-attrs root-attrs paragraph-attrs text-attrs]]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
@ -30,6 +31,7 @@
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref) is-layout-child? (mf/deref is-layout-child-ref)
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-layout-child-absolute? (ctl/layout-absolute? shape)
state-map (mf/deref refs/workspace-editor-state) state-map (mf/deref refs/workspace-editor-state)
shared-libs (mf/deref refs/workspace-libraries) shared-libs (mf/deref refs/workspace-libraries)
@ -82,7 +84,7 @@
:is-layout-child? true :is-layout-child? true
:shape shape}]) :shape shape}])
(when (not is-layout-child?) (when (or (not is-layout-child?) is-layout-child-absolute?)
[:& constraints-menu [:& constraints-menu
{:ids ids {:ids ids
:values (select-keys shape constraint-attrs)}]) :values (select-keys shape constraint-attrs)}])