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

This commit is contained in:
Alejandro Alonso 2026-04-24 12:06:27 +02:00
commit 89a1ee7813
9 changed files with 84 additions and 15 deletions

View File

@ -0,0 +1,27 @@
---
name: commiter
description: Git commit assistant following CONTRIBUTING.md commit rules
mode: primary
---
Role: You are responsible for creating git commits for Penpot and must follow
the repository commit-format rules exactly.
Requirements:
* Read `CONTRIBUTING.md` before creating any commit and follow the
commit guidelines strictly.
* Use commit messages in the form `:emoji: <imperative subject>`.
* Keep the subject capitalized, concise, 70 characters or fewer, and
without a trailing period.
* Keep the description (commit body) with maximum line length of 80
characters. Use manual line breaks to wrap text before it exceeds
this limit.
* Separate the subject from the body with a blank line.
* Write a clear and concise body when needed.
* Use `git commit -s` so the commit includes the required
`Signed-off-by` line.
* Do not guess or hallucinate git author information (Name or
Email). Never include the `--author` flag in git commands unless
specifically instructed by the user for a unique case; assume the
local environment is already configured.

View File

@ -32,6 +32,36 @@ precision while maintaining a strong focus on maintainability and performance.
5. When searching code, prefer `ripgrep` (`rg`) over `grep` — it respects 5. When searching code, prefer `ripgrep` (`rg`) over `grep` — it respects
`.gitignore` by default. `.gitignore` by default.
## GitHub Operations
To obtain the list of repository members/collaborators:
```bash
gh api repos/:owner/:repo/collaborators --paginate --jq '.[].login'
```
To obtain the list of open PRs authored by members:
```bash
MEMBERS=$(gh api repos/:owner/:repo/collaborators --paginate --jq '.[].login' | tr '\n' '|' | sed 's/|$//')
gh pr list --state open --limit 200 --json author,title,number | jq -r --arg members "$MEMBERS" '
($members | split("|")) as $m |
.[] | select(.author.login as $a | $m | index($a)) |
"\(.number)\t\(.author.login)\t\(.title)"
'
```
To obtain the list of open PRs from external contributors (non-members):
```bash
MEMBERS=$(gh api repos/:owner/:repo/collaborators --paginate --jq '.[].login' | tr '\n' '|' | sed 's/|$//')
gh pr list --state open --limit 200 --json author,title,number | jq -r --arg members "$MEMBERS" '
($members | split("|")) as $m |
.[] | select(.author.login as $a | $m | index($a) | not) |
"\(.number)\t\(.author.login)\t\(.title)"
'
```
## Architecture Overview ## Architecture Overview
Penpot is an open-source design tool composed of several modules: Penpot is an open-source design tool composed of several modules:

View File

@ -75,6 +75,7 @@
- Fix wrong `mapcat` call in `collect-main-shapes` - Fix wrong `mapcat` call in `collect-main-shapes`
- Fix stale accumulator in `get-children-in-instance` recursion - Fix stale accumulator in `get-children-in-instance` recursion
- Fix typo `:podition` in swap-shapes grid cell - Fix typo `:podition` in swap-shapes grid cell
- Fix multiple selection on shapes with token applied to stroke color
## 2.14.2 ## 2.14.2

View File

@ -29,9 +29,10 @@
.project-tree { .project-tree {
position: relative; position: relative;
flex-grow: 1; flex-grow: 1;
flex-shrink: 1;
min-width: 0;
height: deprecated.$s-32; height: deprecated.$s-32;
min-height: deprecated.$s-32; min-height: deprecated.$s-32;
max-width: calc(100% - deprecated.$s-64);
} }
.project-name, .project-name,

View File

@ -49,16 +49,16 @@
• :prop → the property type (:fill, :stroke, :shadow, etc.) • :prop → the property type (:fill, :stroke, :shadow, etc.)
• :shape-id → the UUID of the shape using this color • :shape-id → the UUID of the shape using this color
• :index → index of the color in the shape's fill/stroke list • :index → index of the color in the shape's fill/stroke list
Example of groups: Example of groups:
{ {
{:color \"#9f2929\", :opacity 0.3, :token-name \"asd2\" :has-token-applied true} {:color \"#9f2929\", :opacity 0.3, :token-name \"asd2\" :has-token-applied true}
[{:prop :fill, :shape-id #uuid \"d0231035-25c9-80d5-8006-eae4c3dff32e\", :index 0}] [{:prop :fill, :shape-id #uuid \"d0231035-25c9-80d5-8006-eae4c3dff32e\", :index 0}]
{:color \"#1b54b6\", :opacity 1} {:color \"#1b54b6\", :opacity 1}
[{:prop :fill, :shape-id #uuid \"aab34f9a-98c1-801a-8006-eae5e8236f1b\", :index 0}] [{:prop :fill, :shape-id #uuid \"aab34f9a-98c1-801a-8006-eae5e8236f1b\", :index 0}]
} }
This structure allows fast lookups of all shapes using the same visual color, This structure allows fast lookups of all shapes using the same visual color,
regardless of whether it comes from local fills, strokes or shadow-colors." regardless of whether it comes from local fills, strokes or shadow-colors."
@ -106,12 +106,11 @@
open? (deref open*) open? (deref open*)
has-colors? (or (some? (seq colors)) (some? (seq library-colors))) has-colors? (or (some? (seq colors)) (some? (seq library-colors)))
toggle-content (mf/use-fn #(swap! open* not)) toggle-content (mf/use-fn #(swap! open* not))
expand-lib-color (mf/use-state false) expand-lib-color (mf/use-state false)
expand-color (mf/use-state false) expand-color (mf/use-state false)
expand-token-color (mf/use-state false) expand-token-color (mf/use-state false)
;; TODO: Review if this is still necessary. ;; TODO: Review if this is still necessary.
prev-colors-ref (mf/use-ref nil) prev-colors-ref (mf/use-ref nil)

View File

@ -194,7 +194,9 @@
[:div {:class (stl/css-case :stroke-content true [:div {:class (stl/css-case :stroke-content true
:stroke-content-empty (not has-strokes?))} :stroke-content-empty (not has-strokes?))}
(cond (cond
(= :multiple strokes) (or (= :multiple (:stroke-color applied-tokens))
(= :multiple (:stroke-width applied-tokens))
(= :multiple strokes))
[:div {:class (stl/css :stroke-multiple)} [:div {:class (stl/css :stroke-multiple)}
[:div {:class (stl/css :stroke-multiple-label)} [:div {:class (stl/css :stroke-multiple-label)}
(tr "settings.multiple")] (tr "settings.multiple")]

View File

@ -71,12 +71,13 @@
[{:keys [active-tokens applied-token-name color on-swatch-click-token detach-token open-modal-from-token]}] [{:keys [active-tokens applied-token-name color on-swatch-click-token detach-token open-modal-from-token]}]
(let [;; `active-tokens` may be provided as a `delay` (lazy computation). (let [;; `active-tokens` may be provided as a `delay` (lazy computation).
;; In that case we must deref it (`@active-tokens`) to force evaluation ;; In that case we must deref it (`@active-tokens`) to force evaluation
;; and obtain the actual value. If its already realized (not a delay), ;; and obtain the actual value. If it's already realized (not a delay),
;; we just use it directly. ;; we just use it directly.
active-tokens (if (delay? active-tokens) active-tokens (if (delay? active-tokens)
@active-tokens @active-tokens
active-tokens) active-tokens)
active-color-tokens (:color active-tokens) active-color-tokens (:color active-tokens)
token (some #(when (= (:name %) applied-token-name) %) active-color-tokens) token (some #(when (= (:name %) applied-token-name) %) active-color-tokens)
@ -354,6 +355,10 @@
:dnd-over-top (= (:over dprops) :top) :dnd-over-top (= (:over dprops) :top)
:dnd-over-bot (= (:over dprops) :bot))] :dnd-over-bot (= (:over dprops) :bot))]
(when (= applied-token :multiple)
;; (js/console.trace "color-row*")
(prn "color-row*" index color applied-token))
(mf/with-effect [color prev-color disable-picker] (mf/with-effect [color prev-color disable-picker]
(when (and (not disable-picker) (not= prev-color color)) (when (and (not disable-picker) (not= prev-color color))
(modal/update-props! :colorpicker {:data (parse-color color)}))) (modal/update-props! :colorpicker {:data (parse-color color)})))

View File

@ -192,6 +192,8 @@
(when (some? on-reorder) (when (some? on-reorder)
[:> reorder-handler* {:ref dref}]) [:> reorder-handler* {:ref dref}])
(prn "stroke-row*" applied-tokens)
;; Stroke Color ;; Stroke Color
;; FIXME: memorize stroke color ;; FIXME: memorize stroke color
[:> color-row* {:color (ctc/stroke->color stroke) [:> color-row* {:color (ctc/stroke->color stroke)

View File

@ -93,11 +93,13 @@
on-delete on-delete
(mf/use-fn (mf/use-fn
(mf/deps id) (mf/deps id)
#(st/emit! (modal/show (fn [event]
{:type :confirm (dom/stop-propagation event)
:title (tr "modals.delete-page.title") (st/emit! (modal/show
:message (tr "modals.delete-page.body") {:type :confirm
:on-accept delete-fn}))) :title (tr "modals.delete-page.title")
:message (tr "modals.delete-page.body")
:on-accept delete-fn}))))
on-double-click on-double-click
(mf/use-fn (mf/use-fn