mirror of https://github.com/penpot/penpot.git
Merge remote-tracking branch 'origin/staging' into staging-render
This commit is contained in:
commit
45665a3c21
|
|
@ -21,6 +21,22 @@ jobs:
|
|||
with:
|
||||
gh_ref: ${{ github.ref_name }}
|
||||
|
||||
notify:
|
||||
name: Notifications
|
||||
runs-on: ubuntu-24.04
|
||||
needs: build-docker
|
||||
|
||||
steps:
|
||||
- name: Notify Mattermost
|
||||
uses: mattermost/action-mattermost-notify@master
|
||||
with:
|
||||
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK }}
|
||||
MATTERMOST_CHANNEL: bot-alerts-cicd
|
||||
TEXT: |
|
||||
🐳 *[PENPOT] Docker image available.*
|
||||
🔗 Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
@infra
|
||||
|
||||
publish-final-tag:
|
||||
if: ${{ !contains(github.ref_name, '-RC') && !contains(github.ref_name, '-alpha') && !contains(github.ref_name, '-beta') && contains(github.ref_name, '.') }}
|
||||
needs: build-docker
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ example. It's still usable as before, we just removed the example.
|
|||
- Fix U and E icon displayed in project list [Taiga #12806](https://tree.taiga.io/project/penpot/issue/12806)
|
||||
- Fix unpublish library modal not scrolling a long file list [Taiga #12285](https://tree.taiga.io/project/penpot/issue/12285)
|
||||
- Fix incorrect interaction betwen hower and scroll on assets sidebar [Taiga #12389](https://tree.taiga.io/project/penpot/issue/12389)
|
||||
- Fix switch variants with paths [Taiga #12841](https://tree.taiga.io/project/penpot/issue/12841)
|
||||
|
||||
## 2.11.1
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,11 @@
|
|||
[app.common.files.changes-builder :as pcb]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.files.variant :as cfv]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.rect :as grc]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
[app.common.logging :as log]
|
||||
[app.common.logic.shapes :as cls]
|
||||
[app.common.logic.variant-properties :as clvp]
|
||||
|
|
@ -26,6 +29,7 @@
|
|||
[app.common.types.library :as ctl]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.path.segment :as segment]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
|
|
@ -1876,6 +1880,44 @@
|
|||
roperations'
|
||||
uoperations')))))))
|
||||
|
||||
(defn- set-path-new-values
|
||||
[current-shape prev-shape transform]
|
||||
(let [new-content (segment/transform-content
|
||||
(:content current-shape)
|
||||
(gmt/transform-in (gpt/point 0 0) transform))
|
||||
new-points (-> (segment/content->selrect new-content)
|
||||
(grc/rect->points))
|
||||
points-center (gco/points->center new-points)
|
||||
new-selrect (gsh/calculate-selrect new-points points-center)
|
||||
shape (assoc current-shape
|
||||
:content new-content
|
||||
:points new-points
|
||||
:selrect new-selrect)
|
||||
|
||||
prev-center (segment/content-center (:content prev-shape))
|
||||
delta (gpt/subtract points-center (first new-points))
|
||||
new-pos (gpt/subtract prev-center delta)]
|
||||
(gsh/absolute-move shape new-pos)))
|
||||
|
||||
(defn- switch-path-change-value
|
||||
[prev-shape ;; The shape before the switch
|
||||
current-shape ;; The shape after the switch (a clean copy)
|
||||
ref-shape ;; The referenced shape on the main component
|
||||
;; before the switch
|
||||
attr]
|
||||
(let [old-width (-> ref-shape :selrect :width)
|
||||
new-width (-> prev-shape :selrect :width)
|
||||
|
||||
old-height (-> ref-shape :selrect :height)
|
||||
new-height (-> prev-shape :selrect :height)
|
||||
|
||||
transform (-> (gpt/point (/ new-width old-width)
|
||||
(/ new-height old-height))
|
||||
(gmt/scale-matrix))
|
||||
|
||||
shape (set-path-new-values current-shape prev-shape transform)]
|
||||
(get shape attr)))
|
||||
|
||||
|
||||
(defn- switch-text-change-value
|
||||
[prev-content ;; The :content of the text before the switch
|
||||
|
|
@ -2027,6 +2069,10 @@
|
|||
(= :content attr)
|
||||
(touched attr-group))
|
||||
|
||||
path-change?
|
||||
(and (= :path (:type current-shape))
|
||||
(contains? #{:points :selrect :content} attr))
|
||||
|
||||
;; position-data is a special case because can be affected by :geometry-group and :content-group
|
||||
;; so, if the position-data changes but the geometry is touched we need to reset the position-data
|
||||
;; so it's calculated again
|
||||
|
|
@ -2055,6 +2101,12 @@
|
|||
(:content origin-ref-shape)
|
||||
touched)
|
||||
|
||||
path-change?
|
||||
(switch-path-change-value previous-shape
|
||||
current-shape
|
||||
origin-ref-shape
|
||||
attr)
|
||||
|
||||
:else
|
||||
(get previous-shape attr)))
|
||||
|
||||
|
|
|
|||
|
|
@ -281,7 +281,20 @@
|
|||
(defn check-fn
|
||||
"Create a predefined check function"
|
||||
[s & {:keys [hint type code]}]
|
||||
(let [s (schema s)
|
||||
(let [s #?(:clj
|
||||
(schema s)
|
||||
:cljs
|
||||
(try
|
||||
(schema s)
|
||||
(catch :default cause
|
||||
(let [data (ex-data cause)]
|
||||
(if (= :malli.core/invalid-schema (:type data))
|
||||
(throw (ex-info
|
||||
(str "Invalid schema\n"
|
||||
(pp/pprint-str (:data data)))
|
||||
{}))
|
||||
(throw cause))))))
|
||||
|
||||
validator* (delay (m/validator s))
|
||||
explainer* (delay (m/explainer s))
|
||||
hint (or ^boolean hint "check error")
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ bb -i '(babashka.wait/wait-for-port "localhost" 9630)';
|
|||
bb -i '(babashka.wait/wait-for-path "target/app.js")';
|
||||
sleep 2;
|
||||
|
||||
export NODE_TLS_REJECT_UNAUTHORIZED=0
|
||||
exec node target/app.js
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@
|
|||
|
||||
(def browser-pool-factory
|
||||
(letfn [(create []
|
||||
(p/let [opts #js {:args #js ["--font-render-hinting=none"]}
|
||||
(p/let [opts #js {:args #js ["--allow-insecure-localhost" "--font-render-hinting=none"]}
|
||||
browser (.launch pw/chromium opts)
|
||||
id (swap! pool-browser-id inc)]
|
||||
(l/info :origin "factory" :action "create" :browser-id id)
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
(p/fmap (fn [resource]
|
||||
(assoc exchange :response/body resource)))
|
||||
(p/merr (fn [cause]
|
||||
(l/error :hint "unexpected error on export multiple"
|
||||
(l/error :hint "unexpected error on single export"
|
||||
:cause cause)
|
||||
(p/rejected cause))))))
|
||||
|
||||
|
|
@ -94,7 +94,7 @@
|
|||
(redis/pub! topic data))))
|
||||
|
||||
on-error (fn [cause]
|
||||
(l/error :hint "unexpected error on multiple exportation" :cause cause)
|
||||
(l/error :hint "unexpected error on multiple export" :cause cause)
|
||||
(if wait
|
||||
(p/rejected cause)
|
||||
(redis/pub! topic {:type :export-update
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@
|
|||
"@penpot/hljs": "portal:./vendor/hljs",
|
||||
"@penpot/mousetrap": "portal:./vendor/mousetrap",
|
||||
"@penpot/plugins-runtime": "1.3.2",
|
||||
"@penpot/svgo": "penpot/svgo#v3.1",
|
||||
"@penpot/svgo": "penpot/svgo#v3.2",
|
||||
"@penpot/text-editor": "portal:./text-editor",
|
||||
"@tokens-studio/sd-transforms": "1.2.11",
|
||||
"@zip.js/zip.js": "patch:@zip.js/zip.js@npm%3A2.7.60#~/.yarn/patches/@zip.js-zip.js-npm-2.7.60-b6b814410b.patch",
|
||||
|
|
|
|||
|
|
@ -351,19 +351,31 @@
|
|||
(on-success))))
|
||||
(rx/catch on-error))))))
|
||||
|
||||
|
||||
(def ^:private schema:create-invitation
|
||||
[:and
|
||||
[:map
|
||||
[:emails {:optional true} [::sm/set ::sm/email]]
|
||||
[:invitations {:optional true}
|
||||
[:vector
|
||||
[:map
|
||||
[:email ::sm/email]
|
||||
[:role [::sm/one-of ctt/valid-roles]]]]]
|
||||
[:team-id ::sm/uuid]
|
||||
[:resend? {:optional true} ::sm/boolean]]
|
||||
[:fn (fn [attrs]
|
||||
(or (contains? attrs :emails)
|
||||
(contains? attrs :invitations)))]])
|
||||
|
||||
(def ^:private check-create-invitations-params
|
||||
(sm/check-fn schema:create-invitation))
|
||||
|
||||
(defn create-invitations
|
||||
"Unified function to create invitations. Supports two parameter formats:
|
||||
1. {:emails #{...} :role :admin :team-id uuid} - single role for all emails
|
||||
2. {:invitations [{:email ... :role ...}] :team-id uuid} - individual roles per email"
|
||||
[{:keys [emails role team-id invitations resend?] :as params}]
|
||||
|
||||
(assert (uuid? team-id))
|
||||
;; Validate input format - must have either emails+role OR invitations
|
||||
(assert (or (and emails role (sm/check-set-of-emails emails) (keyword? role))
|
||||
(and invitations
|
||||
(sm/check-set-of-emails (map :email invitations))
|
||||
(every? #(contains? ctt/valid-roles (:role %)) invitations)))
|
||||
"Must provide either emails+role or invitations with individual roles")
|
||||
(check-create-invitations-params params)
|
||||
|
||||
(ptk/reify ::create-invitations
|
||||
ev/Event
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
:text [:visibility :geometry :text :shadow :blur :stroke :layout-element]
|
||||
:variant [:variant :geometry :fill :stroke :shadow :blur :layout :layout-element]})
|
||||
|
||||
(mf/defc attributes
|
||||
(mf/defc attributes*
|
||||
[{:keys [page-id file-id shapes frame from libraries share-id objects color-space]}]
|
||||
(let [shapes (hooks/use-equal-memo shapes)
|
||||
first-shape (first shapes)
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@
|
|||
embed-images? (replace-map images-data))]
|
||||
(str/format page-template style-code markup-code)))
|
||||
|
||||
(mf/defc code
|
||||
(mf/defc code*
|
||||
[{:keys [shapes frame on-expand from]}]
|
||||
(let [style-type* (mf/use-state "css")
|
||||
markup-type* (mf/use-state "html")
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
||||
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
|
||||
[app.main.ui.icons :as deprecated-icon]
|
||||
[app.main.ui.inspect.attributes :refer [attributes]]
|
||||
[app.main.ui.inspect.code :refer [code]]
|
||||
[app.main.ui.inspect.attributes :refer [attributes*]]
|
||||
[app.main.ui.inspect.code :refer [code*]]
|
||||
[app.main.ui.inspect.selection-feedback :refer [resolve-shapes]]
|
||||
[app.main.ui.inspect.styles :refer [styles-tab*]]
|
||||
[app.util.dom :as dom]
|
||||
|
|
@ -122,8 +122,7 @@
|
|||
(fn []
|
||||
(if (seq shapes)
|
||||
(st/emit! (ptk/event ::ev/event {::ev/name "inspect-mode-click-element"}))
|
||||
(handle-change-tab (if (contains? cf/flags :inspect-styles) :styles :info)))
|
||||
(reset! color-space* "hex")))
|
||||
(handle-change-tab (if (contains? cf/flags :inspect-styles) :styles :info)))))
|
||||
|
||||
[:aside {:class (stl/css-case :settings-bar-right true
|
||||
:viewer-code (= from :viewer))}
|
||||
|
|
@ -189,41 +188,41 @@
|
|||
:libraries libraries
|
||||
:file-id file-id}]
|
||||
:computed
|
||||
[:& attributes {:color-space color-space
|
||||
:page-id page-id
|
||||
:objects objects
|
||||
:file-id file-id
|
||||
:frame frame
|
||||
:shapes shapes
|
||||
:from from
|
||||
:libraries libraries
|
||||
:share-id share-id}]
|
||||
[:> attributes* {:color-space color-space
|
||||
:page-id page-id
|
||||
:objects objects
|
||||
:file-id file-id
|
||||
:frame frame
|
||||
:shapes shapes
|
||||
:from from
|
||||
:libraries libraries
|
||||
:share-id share-id}]
|
||||
|
||||
:code
|
||||
[:& code {:frame frame
|
||||
:shapes shapes
|
||||
:on-expand handle-expand
|
||||
:from from}])]
|
||||
[:> code* {:frame frame
|
||||
:shapes shapes
|
||||
:on-expand handle-expand
|
||||
:from from}])]
|
||||
[:> tab-switcher* {:tabs tabs
|
||||
:selected (name @section)
|
||||
:on-change handle-change-tab
|
||||
:class (stl/css :viewer-tab-switcher)}
|
||||
(case @section
|
||||
:info
|
||||
[:& attributes {:page-id page-id
|
||||
:objects objects
|
||||
:file-id file-id
|
||||
:frame frame
|
||||
:shapes shapes
|
||||
:from from
|
||||
:libraries libraries
|
||||
:share-id share-id}]
|
||||
[:> attributes* {:page-id page-id
|
||||
:objects objects
|
||||
:file-id file-id
|
||||
:frame frame
|
||||
:shapes shapes
|
||||
:from from
|
||||
:libraries libraries
|
||||
:share-id share-id}]
|
||||
|
||||
:code
|
||||
[:& code {:frame frame
|
||||
:shapes shapes
|
||||
:on-expand handle-expand
|
||||
:from from}])])]]
|
||||
[:> code* {:frame frame
|
||||
:shapes shapes
|
||||
:on-expand handle-expand
|
||||
:from from}])])]]
|
||||
[:div {:class (stl/css :empty)}
|
||||
[:div {:class (stl/css :code-info)}
|
||||
[:span {:class (stl/css :placeholder-icon)}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@
|
|||
(swap! shorthands* assoc (:panel shorthand) (:property shorthand))))]
|
||||
[:ol {:class (stl/css :styles-tab) :aria-label (tr "labels.styles")}
|
||||
;; TOKENS PANEL
|
||||
(when (or active-themes active-sets)
|
||||
(when (or (seq active-themes) (seq active-sets))
|
||||
[:li
|
||||
[:> style-box* {:panel :token}
|
||||
[:> tokens-panel* {:theme-paths active-themes :set-names active-sets}]]])
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
[app.main.ui.workspace.coordinates :as coordinates]
|
||||
[app.main.ui.workspace.libraries]
|
||||
[app.main.ui.workspace.nudge]
|
||||
[app.main.ui.workspace.palette :refer [palette]]
|
||||
[app.main.ui.workspace.palette :refer [palette*]]
|
||||
[app.main.ui.workspace.plugins]
|
||||
[app.main.ui.workspace.sidebar :refer [sidebar*]]
|
||||
[app.main.ui.workspace.sidebar.history :refer [history-toolbox*]]
|
||||
|
|
@ -84,8 +84,8 @@
|
|||
node-ref (use-resize-observer on-resize)]
|
||||
[:*
|
||||
(when (not ^boolean hide-ui?)
|
||||
[:& palette {:layout layout
|
||||
:on-change-palette-size on-resize-palette}])
|
||||
[:> palette* {:layout layout
|
||||
:on-change-size on-resize-palette}])
|
||||
|
||||
[:section
|
||||
{:key (dm/str "workspace-" page-id)
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@
|
|||
(let [{:keys [modal title]} (get dwta/token-properties :color)
|
||||
window-size (dom/get-window-size)
|
||||
left-sidebar (dom/get-element "left-sidebar-aside")
|
||||
x-size (dom/get-data left-sidebar "left-sidebar-width")
|
||||
x-size (dom/get-data left-sidebar "width")
|
||||
modal-height 392
|
||||
x (- (int x-size) 30)
|
||||
y (- (/ (:height window-size) 2) (/ modal-height 2))]
|
||||
|
|
|
|||
|
|
@ -33,12 +33,13 @@
|
|||
[okulary.core :as l]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def viewport
|
||||
(def ^:private ref:viewport
|
||||
(l/derived :vport refs/workspace-local))
|
||||
|
||||
(defn calculate-palette-padding [rulers?]
|
||||
(defn- calculate-palette-style
|
||||
[rulers?]
|
||||
(let [left-sidebar (dom/get-element "left-sidebar-aside")
|
||||
left-sidebar-size (-> (dom/get-data left-sidebar "left-sidebar-width")
|
||||
left-sidebar-size (-> (dom/get-data left-sidebar "width")
|
||||
(d/parse-integer))
|
||||
rulers-width (if rulers? 22 0)
|
||||
min-left-sidebar-width left-sidebar-default-width
|
||||
|
|
@ -48,36 +49,46 @@
|
|||
#js {"paddingLeft" (dm/str calculate-padding-left "px")
|
||||
"paddingRight" "322px"}))
|
||||
|
||||
(mf/defc palette
|
||||
[{:keys [layout on-change-palette-size]}]
|
||||
(let [color-palette? (:colorpalette layout)
|
||||
text-palette? (:textpalette layout)
|
||||
hide-palettes? (:hide-palettes layout)
|
||||
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
container (mf/use-ref nil)
|
||||
state* (mf/use-state {:show-menu false})
|
||||
state (deref state*)
|
||||
show-menu? (:show-menu state)
|
||||
selected (h/use-shared-state mdc/colorpalette-selected-broadcast-key :recent)
|
||||
selected-text* (mf/use-state :file)
|
||||
selected-text (deref selected-text*)
|
||||
on-select (mf/use-fn #(reset! selected %))
|
||||
rulers? (mf/deref refs/rulers?)
|
||||
{:keys [on-pointer-down on-lost-pointer-capture on-pointer-move parent-ref size]}
|
||||
(r/use-resize-hook :palette 72 54 80 :y true :bottom on-change-palette-size)
|
||||
(mf/defc palette*
|
||||
[{:keys [layout on-change-size]}]
|
||||
(let [color-palette? (:colorpalette layout)
|
||||
text-palette? (:textpalette layout)
|
||||
hide-palettes? (:hide-palettes layout)
|
||||
|
||||
vport (mf/deref viewport)
|
||||
vport-width (:width vport)
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
container (mf/use-ref nil)
|
||||
|
||||
state* (mf/use-state #(-> {:show-menu false}))
|
||||
state (deref state*)
|
||||
show-menu? (:show-menu state)
|
||||
|
||||
selected (h/use-shared-state mdc/colorpalette-selected-broadcast-key :recent)
|
||||
|
||||
selected-text* (mf/use-state :file)
|
||||
selected-text (deref selected-text*)
|
||||
|
||||
on-select (mf/use-fn #(reset! selected %))
|
||||
|
||||
rulers? (mf/deref refs/rulers?)
|
||||
vport (mf/deref ref:viewport)
|
||||
vport-width (get vport :width)
|
||||
|
||||
{:keys [on-pointer-down
|
||||
on-lost-pointer-capture
|
||||
on-pointer-move
|
||||
parent-ref
|
||||
size]}
|
||||
(r/use-resize-hook :palette 72 54 80 :y true :bottom on-change-size)
|
||||
|
||||
on-resize
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [_]
|
||||
(let [dom (mf/ref-val container)
|
||||
width (obj/get dom "clientWidth")]
|
||||
(swap! state* assoc :width width))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [_]
|
||||
(swap! state* assoc :show-menu false)))
|
||||
|
||||
|
|
@ -100,7 +111,7 @@
|
|||
(reset! selected-text* (:id lib)))))
|
||||
|
||||
toggle-palettes
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [_]
|
||||
(r/set-resize-type! :top)
|
||||
(dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down")
|
||||
|
|
@ -131,7 +142,9 @@
|
|||
(vary-meta assoc ::ev/origin "workspace-left-toolbar"))))
|
||||
(dom/blur! node))))
|
||||
|
||||
any-palette? (or color-palette? text-palette?)
|
||||
any-palette?
|
||||
(or color-palette? text-palette?)
|
||||
|
||||
size-classname
|
||||
(cond
|
||||
(<= size 64) (stl/css :small-palette)
|
||||
|
|
@ -142,16 +155,16 @@
|
|||
(let [key1 (events/listen js/window "resize" on-resize)]
|
||||
#(events/unlistenByKey key1)))
|
||||
|
||||
(mf/use-layout-effect
|
||||
#(let [dom (mf/ref-val parent-ref)
|
||||
(mf/with-layout-effect []
|
||||
(let [dom (mf/ref-val parent-ref)
|
||||
width (obj/get dom "clientWidth")]
|
||||
(swap! state* assoc :width width)))
|
||||
|
||||
[:div {:class (stl/css :palette-wrapper)
|
||||
:id "palette-wrapper"
|
||||
:style (calculate-palette-padding rulers?)
|
||||
:style (calculate-palette-style rulers?)
|
||||
:data-testid "palette"}
|
||||
(when-not workspace-read-only?
|
||||
(when-not ^boolean read-only?
|
||||
[:div {:ref parent-ref
|
||||
:class (dm/str size-classname " " (stl/css-case :palettes true
|
||||
:wide any-palette?
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
[app.main.ui.workspace.left-header :refer [left-header*]]
|
||||
[app.main.ui.workspace.right-header :refer [right-header*]]
|
||||
[app.main.ui.workspace.sidebar.assets :refer [assets-toolbox*]]
|
||||
[app.main.ui.workspace.sidebar.collapsable-button :refer [collapsed-button*]]
|
||||
[app.main.ui.workspace.sidebar.debug :refer [debug-panel*]]
|
||||
[app.main.ui.workspace.sidebar.debug-shape-info :refer [debug-shape-info*]]
|
||||
[app.main.ui.workspace.sidebar.history :refer [history-toolbox*]]
|
||||
|
|
@ -44,19 +43,34 @@
|
|||
|
||||
;; --- Left Sidebar (Component)
|
||||
|
||||
(defn- on-collapse-left-sidebar
|
||||
[]
|
||||
(st/emit! (dw/toggle-layout-flag :collapse-left-sidebar)))
|
||||
(def ^:private toggle-collapse-left-sidebar
|
||||
(partial st/emit! (dw/toggle-layout-flag :collapse-left-sidebar)))
|
||||
|
||||
(mf/defc collapse-button*
|
||||
{::mf/private true}
|
||||
[]
|
||||
;; NOTE: This custom button may be replace by an action button when this variant is designed
|
||||
[:button {:class (stl/css :collapse-sidebar-button)
|
||||
:on-click on-collapse-left-sidebar}
|
||||
:on-click toggle-collapse-left-sidebar}
|
||||
[:> icon* {:icon-id i/arrow
|
||||
:size "s"
|
||||
:aria-label (tr "workspace.sidebar.collapse")}]])
|
||||
|
||||
(mf/defc collapsed-button*
|
||||
{::mf/memo true
|
||||
::mf/private true}
|
||||
[]
|
||||
[:div {:id "left-sidebar-aside"
|
||||
:data-width "0"
|
||||
:class (stl/css :collapsed-sidebar)}
|
||||
[:div {:class (stl/css :collapsed-title)}
|
||||
[:button {:class (stl/css :collapsed-button)
|
||||
:title (tr "workspace.sidebar.expand")
|
||||
:on-click toggle-collapse-left-sidebar}
|
||||
[:> icon* {:icon-id i/arrow
|
||||
:size "s"
|
||||
:aria-label (tr "workspace.sidebar.expand")}]]]])
|
||||
|
||||
(mf/defc layers-content*
|
||||
{::mf/private true
|
||||
::mf/memo true}
|
||||
|
|
@ -97,6 +111,7 @@
|
|||
|
||||
[:> layers-toolbox* {:size-parent width}]]))
|
||||
|
||||
|
||||
(mf/defc left-sidebar*
|
||||
{::mf/memo true}
|
||||
[{:keys [layout file page-id tokens-lib active-tokens resolved-active-tokens]}]
|
||||
|
|
@ -161,7 +176,7 @@
|
|||
[:aside {:ref parent-ref
|
||||
:id "left-sidebar-aside"
|
||||
:data-testid "left-sidebar"
|
||||
:data-left-sidebar-width (str width)
|
||||
:data-width (str width)
|
||||
:class aside-class
|
||||
:style {:--left-sidebar-width (dm/str width "px")}}
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,44 @@
|
|||
}
|
||||
}
|
||||
|
||||
.collapsed-sidebar {
|
||||
@include deprecated.flexCenter;
|
||||
position: absolute;
|
||||
top: deprecated.$s-48;
|
||||
left: 0;
|
||||
padding: deprecated.$s-4;
|
||||
border-radius: deprecated.$br-8;
|
||||
background: var(--color-background-primary);
|
||||
margin-inline-start: var(--sp-m);
|
||||
}
|
||||
.collapsed-title {
|
||||
@include deprecated.flexCenter;
|
||||
height: deprecated.$s-36;
|
||||
width: deprecated.$s-24;
|
||||
border-radius: deprecated.$br-8;
|
||||
background: var(--color-background-secondary);
|
||||
}
|
||||
.collapsed-button {
|
||||
@include deprecated.buttonStyle;
|
||||
height: deprecated.$s-24;
|
||||
width: deprecated.$s-16;
|
||||
padding: 0;
|
||||
border-radius: deprecated.$br-5;
|
||||
svg {
|
||||
@include deprecated.flexCenter;
|
||||
height: deprecated.$s-16;
|
||||
width: deprecated.$s-16;
|
||||
color: transparent;
|
||||
fill: none;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
&:hover {
|
||||
svg {
|
||||
stroke: var(--icon-foreground-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.versions-tab {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
;; 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
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.collapsable-button
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc collapsed-button*
|
||||
{::mf/memo true}
|
||||
[]
|
||||
(let [on-click (mf/use-fn #(st/emit! (dw/toggle-layout-flag :collapse-left-sidebar)))]
|
||||
[:div {:id "left-sidebar-aside"
|
||||
:data-size "0"
|
||||
:class (stl/css :collapsed-sidebar)}
|
||||
[:div {:class (stl/css :collapsed-title)}
|
||||
[:button {:class (stl/css :collapsed-button)
|
||||
:title (tr "workspace.sidebar.expand")
|
||||
:on-click on-click}
|
||||
[:> icon* {:icon-id i/arrow
|
||||
:size "s"
|
||||
:aria-label (tr "workspace.sidebar.expand")}]]]]))
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
// 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 "refactor/common-refactor.scss" as deprecated;
|
||||
|
||||
.collapsed-sidebar {
|
||||
@include deprecated.flexCenter;
|
||||
position: absolute;
|
||||
top: deprecated.$s-48;
|
||||
left: 0;
|
||||
padding: deprecated.$s-4;
|
||||
border-radius: deprecated.$br-8;
|
||||
background: var(--color-background-primary);
|
||||
margin-inline-start: var(--sp-m);
|
||||
}
|
||||
.collapsed-title {
|
||||
@include deprecated.flexCenter;
|
||||
height: deprecated.$s-36;
|
||||
width: deprecated.$s-24;
|
||||
border-radius: deprecated.$br-8;
|
||||
background: var(--color-background-secondary);
|
||||
}
|
||||
.collapsed-button {
|
||||
@include deprecated.buttonStyle;
|
||||
height: deprecated.$s-24;
|
||||
width: deprecated.$s-16;
|
||||
padding: 0;
|
||||
border-radius: deprecated.$br-5;
|
||||
svg {
|
||||
@include deprecated.flexCenter;
|
||||
height: deprecated.$s-16;
|
||||
width: deprecated.$s-16;
|
||||
color: transparent;
|
||||
fill: none;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
&:hover {
|
||||
svg {
|
||||
stroke: var(--icon-foreground-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,15 +20,21 @@
|
|||
|
||||
;; Component -------------------------------------------------------------------
|
||||
|
||||
(defn calculate-position
|
||||
(defn- calculate-position
|
||||
"Calculates the style properties for the given coordinates and position"
|
||||
[{vh :height} position x y color?]
|
||||
(let [;; picker height in pixels
|
||||
;; TODO: Revisit these harcoded values
|
||||
h (if color? 610 510)
|
||||
[{vh :height} position x y token-type]
|
||||
(let [; TODO: Revisit these harcoded values
|
||||
modal-height (case token-type
|
||||
:color
|
||||
500
|
||||
:typography
|
||||
660
|
||||
:shadow
|
||||
660
|
||||
400)
|
||||
;; Checks for overflow outside the viewport height
|
||||
max-y (- vh h)
|
||||
overflow-fix (max 0 (+ y (- 50) h (- vh)))
|
||||
max-y (- vh modal-height)
|
||||
overflow-fix (max 0 (+ y (- 50) modal-height (- vh)))
|
||||
bottom-offset "1rem"
|
||||
top-offset (dm/str (- y 70) "px")
|
||||
max-height-top (str "calc(100vh - " top-offset)
|
||||
|
|
@ -61,17 +67,19 @@
|
|||
:top (dm/str (- y 70 overflow-fix) "px")
|
||||
:maxHeight max-height-top}))))
|
||||
|
||||
(defn use-viewport-position-style [x y position color?]
|
||||
(defn use-viewport-position-style [x y position token-type]
|
||||
(let [vport (-> (l/derived :vport refs/workspace-local)
|
||||
(mf/deref))]
|
||||
(-> (calculate-position vport position x y color?)
|
||||
(-> (calculate-position vport position x y token-type)
|
||||
(clj->js))))
|
||||
|
||||
(mf/defc token-update-create-modal
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [x y position token token-type action selected-token-set-id] :as _args}]
|
||||
(let [wrapper-style (use-viewport-position-style x y position (= token-type :color))
|
||||
modal-size-large* (mf/use-state (= token-type :typography))
|
||||
(let [wrapper-style (use-viewport-position-style x y position token-type)
|
||||
modal-size-large* (mf/use-state (or (= token-type :typography)
|
||||
(= token-type :color)
|
||||
(= token-type :shadow)))
|
||||
modal-size-large? (deref modal-size-large*)
|
||||
close-modal (mf/use-fn
|
||||
(fn []
|
||||
|
|
|
|||
|
|
@ -1226,16 +1226,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@penpot/svgo@penpot/svgo#v3.1":
|
||||
"@penpot/svgo@penpot/svgo#v3.2":
|
||||
version: 4.0.0
|
||||
resolution: "@penpot/svgo@https://github.com/penpot/svgo.git#commit=a46262c12c0d967708395972c374eb2adead4180"
|
||||
resolution: "@penpot/svgo@https://github.com/penpot/svgo.git#commit=8c9b0e32e9cb5f106085260bd9375f3c91a5010b"
|
||||
dependencies:
|
||||
"@trysound/sax": "npm:0.2.0"
|
||||
css-select: "npm:^5.1.0"
|
||||
css-tree: "npm:^3.1.0"
|
||||
csso: "npm:^5.0.5"
|
||||
lodash: "npm:^4.17.21"
|
||||
checksum: 10c0/db5f81c99dec2765721d73b69bb30594869ebf657380dfb46709c79775b6c0dc1af678fe9fe51bbe2272a2c78d19c2694a12ec6578bcc41235fa4aff475c9416
|
||||
checksum: 10c0/d7af2801451b97f8ffb17664147c609456f5bcc786c6d03b222546125260c0f268e750748311d61598e31f66610b00038d2b969635b1a15e5694647e19c6b63a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -4311,7 +4311,7 @@ __metadata:
|
|||
"@penpot/hljs": "portal:./vendor/hljs"
|
||||
"@penpot/mousetrap": "portal:./vendor/mousetrap"
|
||||
"@penpot/plugins-runtime": "npm:1.3.2"
|
||||
"@penpot/svgo": "penpot/svgo#v3.1"
|
||||
"@penpot/svgo": "penpot/svgo#v3.2"
|
||||
"@penpot/text-editor": "portal:./text-editor"
|
||||
"@playwright/test": "npm:1.52.0"
|
||||
"@storybook/addon-docs": "npm:10.0.4"
|
||||
|
|
|
|||
Loading…
Reference in New Issue