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

@ -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