0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-06 12:01:19 -05:00

Merge remote-tracking branch 'origin/staging' into develop

This commit is contained in:
Andrey Antukh 2024-02-09 09:53:13 +01:00
commit cff44e34c3
22 changed files with 192 additions and 149 deletions

View file

@ -231,7 +231,7 @@
--assets-item-border-color: var(--color-accent-primary);
--assets-item-background-color-drag: transparent;
--assets-item-border-color-drag: var(--color-accent-primary-muted);
--assets-component-background-color: var(--app-white); // TODO: review this token
--assets-component-background-color: var(--color-foreground-secondary);
--assets-component-background-color-disabled: var(--df-secondary;);
--assets-component-border-color: var(--color-background-tertiary);
--assets-component-border-selected: var(--color-accent-tertiary);

View file

@ -237,39 +237,45 @@
(rx/buffer 2 1)
(rx/share))
changes-s
local-changes-s
(->> stream
(rx/filter dch/commit-changes?)
(rx/with-latest-from workspace-data-s)
(rx/merge-map (partial extract-root-frame-changes page-id))
(rx/tap #(l/trc :hint "incoming change" :origin "local" :frame-id (dm/str %))))
notification-changes-s
(->> stream
(rx/filter (ptk/type? ::wnt/handle-file-change))
(rx/observe-on :async)
(rx/with-latest-from workspace-data-s)
(rx/merge-map (partial extract-root-frame-changes page-id))
(rx/tap #(l/trc :hint "incoming change" :origin "notifications" :frame-id (dm/str %))))
persistence-changes-s
(->> stream
(rx/filter (ptk/type? ::update))
(rx/map deref)
(rx/filter (fn [[file-id page-id]]
(and (= file-id file-id)
(= page-id page-id))))
(rx/map (fn [[_ _ frame-id]] frame-id))
(rx/tap #(l/trc :hint "incoming change" :origin "persistence" :frame-id (dm/str %))))
all-changes-s
(->> (rx/merge
;; LOCAL CHANGES
(->> stream
(rx/filter dch/commit-changes?)
(rx/observe-on :async)
(rx/with-latest-from workspace-data-s)
(rx/merge-map (partial extract-root-frame-changes page-id))
(rx/tap #(l/trc :hint "incoming change" :origin "local" :frame-id (dm/str %))))
local-changes-s
;; NOTIFICATIONS CHANGES
(->> stream
(rx/filter (ptk/type? ::wnt/handle-file-change))
(rx/observe-on :async)
(rx/with-latest-from workspace-data-s)
(rx/merge-map (partial extract-root-frame-changes page-id))
(rx/tap #(l/trc :hint "incoming change" :origin "notifications" :frame-id (dm/str %))))
notification-changes-s
;; PERSISTENCE CHANGES
(->> stream
(rx/filter (ptk/type? ::update))
(rx/map deref)
(rx/filter (fn [[file-id page-id]]
(and (= file-id file-id)
(= page-id page-id))))
(rx/map (fn [[_ _ frame-id]] frame-id))
(rx/tap #(l/trc :hint "incoming change" :origin "persistence" :frame-id (dm/str %)))))
persistence-changes-s)
(rx/share))
;; BUFFER NOTIFIER (window of 5s of inactivity)
notifier-s
(->> changes-s
(->> all-changes-s
(rx/debounce 1000)
(rx/tap #(l/trc :hint "buffer initialized")))]
@ -277,12 +283,12 @@
;; Perform instant thumbnail cleaning of affected frames
;; and interrupt any ongoing update-thumbnail process
;; related to current frame-id
(->> changes-s
(->> all-changes-s
(rx/map #(clear-thumbnail file-id page-id % "frame")))
;; Generate thumbnails in batchs, once user becomes
;; inactive for some instant
(->> changes-s
(->> all-changes-s
(rx/buffer-until notifier-s)
(rx/mapcat #(into #{} %))
(rx/map #(request-thumbnail file-id page-id % "frame"))))

View file

@ -71,6 +71,8 @@
local (mf/use-state {:offset-y 0
:offset-x 0
:levels nil})
width (gobj/get props "width" "initial")
on-local-close
(mf/use-callback
@ -204,6 +206,7 @@
(let [level (-> @local :levels peek)]
[:ul {:class (stl/css-case :min-width min-width?
:context-menu-items true)
:style {:width width}
:role "menu"
:ref check-menu-offscreen}
(when-let [parent-option (:parent-option level)]

View file

@ -53,14 +53,13 @@
;; This `value` represents the previous value and is used as
;; initil value for the simple math expression evaluation.
value (d/parse-double value-str default)
value (when (not= :multiple value-str) (d/parse-double value-str default))
;; We need to store the handle-blur ref so we can call it on unmount
dirty-ref (mf/use-ref false)
;; Last value input by the user we need to store to save on unmount
last-value* (mf/use-var nil)
last-value* (mf/use-var value)
parse-value
(mf/use-fn

View file

@ -377,12 +377,14 @@
"Calculates the style properties for the given coordinates and position"
[{vh :height} position x y]
(let [;; picker height in pixels
h 510
h 510
;; Checks for overflow outside the viewport height
max-y (- vh h)
max-y (- vh h)
rulers? (mf/deref refs/rulers?)
left-offset (if rulers? 40 18)
x-pos 325]
x-pos 400]
(cond
(or (nil? x) (nil? y)) {:left "auto" :right "16rem" :top "4rem"}
(= position :left)
@ -391,8 +393,11 @@
:bottom "1rem"}
{:left (str (- x x-pos) "px")
:top (str (- y 70) "px")})
:else {:left (str (+ x 80) "px")
:top (str (- y 70) "px")})))
:else (if (> y max-y)
{:left (str (+ x left-offset) "px")
:bottom "1rem"}
{:left (str (+ x left-offset) "px")
:top (str (- y 70) "px")}))))
(mf/defc colorpicker-modal
{::mf/register modal/components
@ -401,7 +406,9 @@
disable-gradient
disable-opacity
disable-image
on-change on-close on-accept] :as props}]
on-change
on-close
on-accept] :as props}]
(let [vport (mf/deref viewport)
dirty? (mf/use-var false)
last-change (mf/use-var nil)

View file

@ -9,13 +9,15 @@
.workspace-header-left {
display: flex;
align-items: center;
padding: $s-8 $s-8 $s-4 $s-8;
padding: $s-12 $s-12 $s-8 $s-12;
min-height: $s-52;
}
.main-icon {
@include flexCenter;
width: $s-32;
height: $s-32;
min-height: $s-32;
margin-right: $s-4;
svg {
min-height: $s-32;
@ -27,6 +29,8 @@
.project-tree {
position: relative;
flex-grow: 1;
height: $s-32;
min-height: $s-32;
max-width: calc(100% - $s-64);
}

View file

@ -116,7 +116,7 @@
(when-not ^boolean mode-inspect?
[:& tab-element {:id :assets
:title (tr "workspace.toolbar.assets")}
[:& assets-toolbox]])]])]]))
[:& assets-toolbox {:size (- size 58)}]])]])]]))
;; --- Right Sidebar (Component)

View file

@ -14,8 +14,9 @@ $width-settings-bar-max: $s-500;
grid-template-areas:
"header header"
"content resize";
grid-template-rows: $s-48 1fr;
grid-template-rows: $s-52 1fr;
grid-template-columns: 1fr 0;
gap: $s-8 0;
position: relative;
grid-area: left-sidebar;
min-width: $width-settings-bar;
@ -54,7 +55,7 @@ $width-settings-bar-max: $s-500;
}
.tab-spacing {
margin-inline: $s-8;
margin-inline: $s-12;
}
.right-settings-bar {

View file

@ -67,7 +67,7 @@
(mf/defc assets-toolbox
{::mf/wrap [mf/memo]
::mf/wrap-props false}
[]
[{:keys [size]}]
(let [components-v2 (mf/use-ctx ctx/components-v2)
read-only? (mf/use-ctx ctx/workspace-read-only?)
filters* (mf/use-state
@ -178,7 +178,8 @@
:show menu-open?
:fixed? true
:min-width? true
:top 152
:width size
:top 158
:left 18
:options options
:workspace? true}]

View file

@ -12,16 +12,19 @@
grid-auto-rows: max-content;
// TODO: ugly hack :( Fix this! we shouldn't be hardcoding this height
max-height: calc(100vh - $s-80);
scrollbar-gutter: stable;
overflow-y: auto;
padding-top: $s-8;
}
.libraries-button {
@include tabTitleTipography;
@extend .button-secondary;
@include tabTitleTipography;
gap: $s-2;
height: $s-32;
width: 100%;
border-radius: $s-8;
margin-bottom: $s-4;
border-radius: $s-8;
.libraries-icon {
@include flexCenter;
width: $s-24;
@ -124,7 +127,7 @@
}
.assets-header {
padding: $s-8 $s-12 $s-12 $s-12;
padding: 0 0 $s-24 $s-12;
}
.search-wrapper {
@ -133,7 +136,7 @@
}
.sort-button {
@extend .button-secondary;
@extend .button-tertiary;
width: $s-32;
border-radius: $br-8;
svg {

View file

@ -386,17 +386,23 @@
(mf/use-fn
(mf/deps file-id)
(fn [event]
(st/emit! (dw/set-assets-section-open file-id :colors true)
(ptk/event ::ev/event {::ev/name "add-asset-to-library"
:asset-type "color"}))
;; FIXME: replace interop with dom helpers
(modal/show! :colorpicker
{:x (.-clientX event)
:y (.-clientY event)
:on-accept add-color
:data {:color "#406280"
:opacity 1}
:position :right})))
(let [bounding-rect (-> event
(dom/get-current-target)
(dom/get-bounding-rect))
x-position (:right bounding-rect)
y-position (:top bounding-rect)]
(st/emit! (dw/set-assets-section-open file-id :colors true)
(ptk/event ::ev/event {::ev/name "add-asset-to-library"
:asset-type "color"}))
;; FIXME: replace interop with dom helpers
(modal/show! :colorpicker
{:x x-position
:y y-position
:on-accept add-color
:data {:color "#406280"
:opacity 1}
:position :right}))))
create-group
(mf/use-fn

View file

@ -74,13 +74,13 @@
overflow: hidden;
.default-name-only,
.name {
color: var(--assets-item-name-foreground-color-hover);
color: var(--assets-item-name-foreground-color);
margin-right: $s-6;
@include textEllipsis;
}
.default-name {
min-width: 0;
color: var(--assets-item-name-foreground-color);
color: var(--assets-item-name-foreground-color-rest);
}
}

View file

@ -144,7 +144,8 @@
(mf/use-fn
(mf/deps file-id section open?)
(fn [_]
(st/emit! (dw/set-assets-section-open file-id section (not open?)))))
(when (< 0 assets-count)
(st/emit! (dw/set-assets-section-open file-id section (not open?))))))
title
(mf/html
@ -157,13 +158,15 @@
[:span {:class (stl/css :num-assets)}
assets-count]])]
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css-case :asset-section true
:opened (and (< 0 assets-count)
open?))}
[:& title-bar
{:collapsable true
{:collapsable (< 0 assets-count)
:collapsed (not open?)
:all-clickable true
:on-collapsed on-collapsed
:class (stl/css :title-spacing)
:class (stl/css-case :title-spacing open?)
:title title}
buttons]
(when ^boolean open? content)]))

View file

@ -41,3 +41,7 @@
.title-spacing {
margin-bottom: $s-4;
}
.asset-section.opened {
margin-bottom: $s-12;
}

View file

@ -238,7 +238,7 @@
(when group-open?
[:*
(let [components (get groups "" [])]
(when-let [components (not-empty (get groups "" []))]
[:div {:class-name (stl/css-case :asset-grid listing-thumbs?
:asset-enum (not listing-thumbs?)
:drop-space (and
@ -512,27 +512,26 @@
:assets-count (count components)
:open? open?}
[:& cmm/asset-section-block {:role :title-button}
[:*
(when open?
[:div {:class (stl/css :listing-options)}
[:& radio-buttons {:selected (if listing-thumbs? "grid" "list")
:on-change toggle-list-style
:name "listing-style"}
[:& radio-button {:icon i/view-as-list-refactor
:value "list"
:id "opt-list"}]
[:& radio-button {:icon i/flex-grid-refactor
:value "grid"
:id "opt-grid"}]]])
(when ^boolean open?
[:div {:class (stl/css :listing-options)}
[:& radio-buttons {:selected (if listing-thumbs? "grid" "list")
:on-change toggle-list-style
:name "listing-style"}
[:& radio-button {:icon i/view-as-list-refactor
:value "list"
:id "opt-list"}]
[:& radio-button {:icon i/flex-grid-refactor
:value "grid"
:id "opt-grid"}]]])
(when (and components-v2 (not read-only?) local?)
[:div {:on-click add-component
:class (stl/css :add-component)}
i/add-refactor
[:& file-uploader {:accept cm/str-image-types
:multi true
:ref input-ref
:on-selected on-file-selected}]])]]
(when (and components-v2 (not read-only?) local?)
[:div {:on-click add-component
:class (stl/css :add-component)}
i/add-refactor
[:& file-uploader {:accept cm/str-image-types
:multi true
:ref input-ref
:on-selected on-file-selected}]])]
[:& cmm/asset-section-block {:role :content}
(when ^boolean open?

View file

@ -9,10 +9,10 @@
.drop-space {
height: $s-12;
}
.asset-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax($s-96, 1fr));
grid-auto-rows: $s-112;
max-width: 100%;
gap: $s-4;
margin-inline: $s-8;
@ -21,6 +21,7 @@
.grid-cell {
@include flexCenter;
position: relative;
aspect-ratio: 1 / 1;
padding: $s-8;
border-radius: $br-8;
background-color: var(--assets-component-background-color);
@ -63,7 +64,6 @@
}
&:hover {
background-color: var(--assets-item-background-color-hover);
.cell-name {
display: block;
}
@ -74,6 +74,12 @@
}
}
.component-group {
display: grid;
grid-template-columns: 1fr;
gap: $s-4;
}
.thumbnail {
width: 100%;
height: 100%;
@ -89,23 +95,22 @@
border: $s-2 solid var(--assets-item-border-color-drag);
}
.asset-enum {
margin: 0 $s-12;
}
.enum-item {
position: relative;
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
column-gap: $s-8;
height: $s-36;
margin-bottom: $s-4;
height: $s-44;
padding: $s-2;
border-radius: $br-8;
background-color: var(--assets-item-background-color);
cursor: pointer;
&:not(:last-child) {
margin-bottom: $s-4;
}
&:hover {
background-color: var(--assets-item-background-color-hover);
.item-name {
@ -159,8 +164,8 @@
@include flexCenter;
flex-shrink: 0;
padding: $s-2;
height: $s-32;
width: $s-32;
height: $s-36;
width: $s-36;
border-radius: $br-6;
background-color: var(--assets-component-background-color);
}

View file

@ -51,7 +51,8 @@
(mf/deps file-id open?)
(fn []
(st/emit! (dw/set-assets-section-open file-id :library (not open?)))))]
[:div {:class (stl/css :library-title)}
[:div {:class (stl/css-case :library-title true
:open open?)}
[:& title-bar {:collapsable true
:collapsed (not open?)
:all-clickable true

View file

@ -6,14 +6,10 @@
@import "refactor/common-refactor.scss";
.tool-window {
padding-inline-start: $s-12;
overflow-y: auto;
padding: 0 0 $s-24 $s-12;
display: grid;
grid-auto-rows: max-content;
scrollbar-gutter: stable;
&:last-child {
margin-block-end: $s-24;
}
gap: $s-4;
height: 100%;
}
@ -47,6 +43,9 @@
.library-content {
width: 100%;
display: grid;
grid-auto-rows: max-content;
gap: $s-4;
}
.asset-title {

View file

@ -87,8 +87,7 @@
}
}
.asset-enum {
margin: 0 $s-12;
padding-bottom: $s-4;
.enum-item {
position: relative;
display: flex;

View file

@ -264,7 +264,7 @@
font-size: $s-12;
cursor: pointer;
width: 100%;
height: $s-36;
height: $s-44;
border-radius: $br-8;
background-color: var(--assets-item-background-color);
color: var(--assets-item-name-foreground-color);
@ -278,8 +278,8 @@
img {
background-color: var(--assets-component-background-color);
border-radius: $br-8;
height: $s-32;
width: $s-32;
height: $s-36;
width: $s-36;
margin: $s-2 $s-8 $s-2 $s-2;
}

View file

@ -391,7 +391,7 @@
[:span {:class (stl/css :icon-text)} "W"]
[:> numeric-input* {:min 0.01
:no-validate true
:placeholder "--"
:placeholder (if (= :multiple (:width values)) (tr "settings.multiple") "--")
:on-change on-width-change
:disabled disabled-width-sizing?
:className (stl/css :numeric-input)
@ -402,7 +402,7 @@
[:span {:class (stl/css :icon-text)} "H"]
[:> numeric-input* {:min 0.01
:no-validate true
:placeholder "--"
:placeholder (if (= :multiple (:height values)) (tr "settings.multiple") "--")
:on-change on-height-change
:disabled disabled-height-sizing?
:className (stl/css :numeric-input)
@ -422,7 +422,7 @@
:title (tr "workspace.options.x")}
[:span {:class (stl/css :icon-text)} "X"]
[:> numeric-input* {:no-validate true
:placeholder "--"
:placeholder (if (= :multiple (:x values)) (tr "settings.multiple") "--")
:on-change on-pos-x-change
:disabled disabled-position-x?
:className (stl/css :numeric-input)
@ -433,7 +433,7 @@
:title (tr "workspace.options.y")}
[:span {:class (stl/css :icon-text)} "Y"]
[:> numeric-input* {:no-validate true
:placeholder "--"
:placeholder (if (= :multiple (:y values)) (tr "settings.multiple") "--")
:disabled disabled-position-y?
:on-change on-pos-y-change
:className (stl/css :numeric-input)
@ -450,7 +450,7 @@
:min 0
:max 359
:data-wrap true
:placeholder "--"
:placeholder (if (= :multiple (:rotation values)) (tr "settings.multiple") "--")
:on-change on-rotation-change
:className (stl/css :numeric-input)
:value (:rotation values)}]])
@ -464,7 +464,7 @@
:title (tr "workspace.options.radius")}
[:span {:class (stl/css :icon)} i/corner-radius-refactor]
[:> numeric-input*
{:placeholder "Mixed"
{:placeholder (if (= :multiple (:rx values)) (tr "settings.multiple") "--")
:ref radius-input-ref
:min 0
:on-change on-radius-1-change

View file

@ -21,43 +21,6 @@
color: var(--assets-item-name-foreground-color-hover);
}
.typography-selection-wrapper {
display: grid;
grid-template-columns: $s-24 auto 1fr;
flex: 1;
height: 100%;
width: 100%;
padding: 0 $s-12;
&.is-selectable {
cursor: pointer;
}
.typography-sample {
@include flexCenter;
min-width: $s-24;
height: $s-32;
color: var(--assets-item-name-foreground-color-hover);
}
.typography-name,
.typography-font {
@include titleTipography;
@include textEllipsis;
display: flex;
align-items: center;
justify-content: flex-start;
margin-left: $s-6;
color: var(--assets-item-name-foreground-color-hover);
}
.typography-font {
display: flex;
align-items: center;
justify-content: flex-start;
min-width: 0;
color: var(--assets-item-name-foreground-color);
}
}
&.selected {
border: $s-1 solid var(--assets-item-border-color);
}
@ -78,6 +41,7 @@
}
}
}
&:hover {
background-color: var(--assets-item-background-color-hover);
.element-set-actions {
@ -86,6 +50,45 @@
}
}
.typography-selection-wrapper {
display: grid;
grid-template-columns: $s-24 auto 1fr;
flex: 1;
height: 100%;
width: 100%;
padding: 0 $s-12;
&.is-selectable {
cursor: pointer;
}
}
.typography-sample {
@include flexCenter;
min-width: $s-24;
height: $s-32;
color: var(--assets-item-name-foreground-color);
}
.typography-name,
.typography-font {
@include titleTipography;
@include textEllipsis;
display: flex;
align-items: center;
justify-content: flex-start;
margin-left: $s-6;
color: var(--assets-item-name-foreground-color);
}
.typography-font {
display: flex;
align-items: center;
justify-content: flex-start;
min-width: 0;
color: var(--assets-item-name-foreground-color-rest);
}
.font-name-wrapper {
@include titleTipography;
display: flex;