23193 Commits

Author SHA1 Message Date
David Barragán Merino
328fa0559a 🐳 Migrate imagemagick and devenv images to DHI
Move docker/imagemagick/Dockerfile and docker/devenv/Dockerfile from
ubuntu:26.04 to Docker Hardened Images (Debian 13 / trixie).
imagemagick gets a true non-dev runtime with its shared libraries
vendored via ldd; devenv keeps the -dev tag as its final image since
it's an interactive development container, not a production
artifact.
2026-07-31 19:04:33 +02:00
Anonymous
863671135d
🌐 Add translations for: French (Canada)
Currently translated at 95.7% (2329 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr_CA/
2026-07-31 19:03:01 +02:00
Alexis Morin
657b5bd94e
🌐 Add translations for: French (Canada)
Currently translated at 95.7% (2329 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr_CA/
2026-07-31 19:03:00 +02:00
Anonymous
5ea3a2efb8
🌐 Add translations for: Hindi
Currently translated at 81.1% (1974 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/hi/
2026-07-31 19:02:58 +02:00
VKing9
94cfd6e60d
🌐 Add translations for: Hindi
Currently translated at 81.1% (1974 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/hi/
2026-07-31 19:02:58 +02:00
Anonymous
600c573ccd
🌐 Add translations for: Swedish
Currently translated at 96.4% (2345 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/sv/
2026-07-31 19:02:56 +02:00
AntonPalmqvist
4c388f6d8b
🌐 Add translations for: Swedish
Currently translated at 96.4% (2345 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/sv/
2026-07-31 19:02:55 +02:00
Anonymous
4d07510581
🌐 Add translations for: Dutch
Currently translated at 94.4% (2297 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/nl/
2026-07-31 19:02:53 +02:00
Stephan Paternotte
5e8a2b0a03
🌐 Add translations for: Dutch
Currently translated at 94.4% (2297 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/nl/
2026-07-31 19:02:53 +02:00
Anonymous
588222d409
🌐 Add translations for: Latvian
Currently translated at 75.7% (1842 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/lv/
2026-07-31 19:02:51 +02:00
Anonymous
0139c0f0e3
🌐 Add translations for: Korean
Currently translated at 81.5% (1984 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ko/
2026-07-31 19:02:49 +02:00
Denys Kisil
1b69d8c6a2
🌐 Add translations for: Ukrainian (ukr_UA)
Currently translated at 83.5% (2032 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ukr_UA/
2026-07-31 19:02:48 +02:00
Anonymous
d7b55a245a
🌐 Add translations for: Italian
Currently translated at 86.5% (2105 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/it/
2026-07-31 19:02:46 +02:00
Anonymous
fdeff910fe
🌐 Add translations for: Persian
Currently translated at 31.4% (765 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fa/
2026-07-31 19:02:44 +02:00
Anonymous
3fa21180fd
🌐 Add translations for: Hebrew
Currently translated at 83.0% (2020 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/he/
2026-07-31 19:02:42 +02:00
Yaron Shahrabani
ecaf63b204
🌐 Add translations for: Hebrew
Currently translated at 83.0% (2020 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/he/
2026-07-31 19:02:42 +02:00
Anonymous
1074cb376d
🌐 Add translations for: Romanian
Currently translated at 78.3% (1906 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ro/
2026-07-31 19:02:40 +02:00
Anonymous
0aff047301
🌐 Add translations for: German
Currently translated at 79.8% (1942 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/de/
2026-07-31 19:02:38 +02:00
Anonymous
02b0f18a83
🌐 Add translations for: Portuguese (Brazil)
Currently translated at 56.4% (1372 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/pt_BR/
2026-07-31 19:02:36 +02:00
DoubleCat
13b2954cbf
🌐 Add translations for: Chinese (Simplified Han script)
Currently translated at 94.4% (2298 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/zh_Hans/
2026-07-31 19:02:35 +02:00
Anonymous
0703a3fcc1
🌐 Add translations for: Turkish
Currently translated at 96.4% (2345 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/tr/
2026-07-31 19:02:33 +02:00
Oğuz Ersen
b294aecb7c
🌐 Add translations for: Turkish
Currently translated at 96.4% (2345 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/tr/
2026-07-31 19:02:32 +02:00
Anonymous
620c26b304
🌐 Add translations for: Russian
Currently translated at 68.4% (1664 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ru/
2026-07-31 19:02:30 +02:00
Anonymous
1ac000bc27
🌐 Add translations for: French
Currently translated at 82.1% (1999 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr/
2026-07-31 19:02:28 +02:00
Ingrid Pigueron
9042bd5129
🌐 Add translations for: French
Currently translated at 82.1% (1999 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr/
2026-07-31 19:02:27 +02:00
Anonymous
905c230e17
🌐 Add translations for: Spanish
Currently translated at 95.4% (2321 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/es/
2026-07-31 19:02:25 +02:00
Hosted Weblate
552cda9aae
🌐 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/
2026-07-31 18:57:18 +02:00
Andrey Antukh
89029060e0 Merge remote-tracking branch 'weblate/develop' into develop 2026-07-31 18:56:46 +02:00
Andrey Antukh
07efd8fb99
⬆️ Update dependencies (#10982)
* ⬆️ Update root pnpm depdendencies

* ⬆️ Update common pnpm dependencies

* ⬆️ Upgrade docs pnpm dependencies

* ⬆️ Upgrade pnpm deps on library

* ⬆️ Upgrade plugins pnpm dependencies

* ⬆️ Update pnpm dependencies on mcp

* ⬆️ Update pnpm dependencies on frontend

* ⬆️ Update exporter pnpm dependencies

* ⬆️ Update jvm/clojure deps

* ⬆️ Update docker dependencies (jvm and node)

* 📎 Add minor fixes
2026-07-31 18:53:05 +02:00
David Barragán Merino
31158c319a 🔧 Optimize the Docker image build process (avoid rebuilds, make better use of the cache) 2026-07-31 16:57:04 +02:00
Andrey Antukh
ab1c70115b
🐛 Prevent MCP tokens from being used as access tokens (#10962)
MCP tokens now use a separate JWT issuer claim (`urn:penpot:mcp-token`) instead of `access-token`, preventing them from being validated as API access tokens.

Fixes #10960

AI-assisted-by: qwen3.7-plus
2026-07-31 13:19:45 +02:00
Eva Marco
9bb5861322
🐛 Fix undo delete pages change order (#10969) 2026-07-31 13:09:18 +02:00
Eva Marco
36553a7c6f
🐛 Fix reset cancel shortcut (#10980) 2026-07-31 12:51:01 +02:00
Luis de Dios
ff32f104b9
🐛 Fix main menu is covered by the toolbar (#10926)
* 🐛 Fix main menu is covered by the toolbar

* ♻️ Refactor SCSS

* 🐛 Fix adjust z-index of workspace context menu

* ♻️ Refactor SCSS

* 🐛 Fix adjust z-index of tokens context menu

* ♻️ Refactor SCSS

* 🐛 Fix adjust z-index of old context menu

* 📎 PR improvements
2026-07-31 12:48:59 +02:00
María Valderrama
1744d07731
Allow nitrate onboarding to be handled by admin-console (#10936)
*  Allow nitrate onboarding to be handled by admin-console

* 📎 Code review
2026-07-31 12:24:30 +02:00
Marina López
94f51afb20
♻️ Normalize organization naming across Penpot (#10977) 2026-07-31 12:04:10 +02:00
Elena Torró
a2231a8bf9
🐛 Fix text align shown as left in v3 editor (#10973) 2026-07-31 11:48:31 +02:00
Luis de Dios
f5b17a5c75
🐛 Fix toolbar keyboard navigation (#10939)
* 🐛 Fix flyouts are not expanded using just the keyboard

* 🐛 Fix escape key does not close the flyouts
2026-07-31 11:25:46 +02:00
Luis de Dios
e952d9c70a
🐛 Fix draw a line/arrow with a single click (#10974) 2026-07-31 11:25:20 +02:00
Luis de Dios
3fc1e6aadd
🐛 Fix image swatches displays a wrong format in list view (#10975) 2026-07-31 11:24:55 +02:00
Filip Sajdak
0b5db57def
🐛 Highlight first search result in font picker and fix Enter confirm (#10450)
When the user types a search term that filters out the currently-active
font, the picker showed no selection at all and Enter would close without
applying any font. Fix:

- Compute effective-selected (render-only, no state mutation) as the
  first filtered font when the current font is absent from the results.
  The row renderer and recent-fonts list use this for the tick mark, so
  the top match is visually pre-selected while the user types.
- Enter key applies first-result (via on-select then on-close) when the
  current selection is not in the filtered list; otherwise closes as
  before. No font is live-applied on every keystroke.
- on-key-down deps extended to on-select/on-close; effect deps include
  on-key-down so the global listener is always current.

Avoids the live-apply side-effect that caused the revert of #9512.
Fixes #3204.

Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-07-31 10:46:53 +02:00
Belén Albeza
7fa6631005
🐛 Fix collapsed fills section on text shapes (#10972) 2026-07-31 10:29:26 +02:00
Elena Torró
9b0be1c750
🐛 Fix crash when editing justified text in wasm editor (#10945) 2026-07-31 10:20:42 +02:00
Eva Marco
fe85a5717e
♻️ Fixes on shortcuts (#10906)
* 🎉 Improve reset to default flow

* 🎉 Add diff modal

* 🐛 Fix measurement shortcuts

* 🎉 Separate open-sections for each tab

* 🐛 Align button link icon

* 🎉 Reset only works after press save

* 🐛 Fix little things

* 🎉 Make the import export row to be fixed

* ♻️ Fix CI

* 🐛 Cancel shortcut is not appearing on disabled tab

* 🐛 Fix tests

* 🐛 Fix loop on personalized

* 🐛 Fix show measurements shortcut
2026-07-30 16:56:10 +02:00
Pablo Alba
370e91c3e3
🐛 Fix bad error callback on nitrate checkout (#10886) 2026-07-30 16:50:47 +02:00
Marina López
31ccfa546f
Add nitrate audit events 2026-07-30 15:32:45 +02:00
Belén Albeza
91d4b16171
🐛 Fix selrect not being recalculated after pasting properties (#10963) 2026-07-30 15:01:50 +02:00
Eva Marco
c8867f8c3a
🐛 Fix registration mail color (#10965) 2026-07-30 14:51:32 +02:00
Alonso Torres
014ec34249
🐛 Fix system crash on grid element deletion of a component (#10956)
* 🐛 Add regression test: main-side component edits break copy swap slots

Reproduces the :missing-slot referential-integrity failure ("Shape has been
swapped, should have swap slot") that crashes files with component copies.

Root cause: reordering or deleting a nested sub-head IN THE MAIN of a component,
while copies exist, does not propagate swap slots to the copies. find-near-match
matches a copy's sub-heads to the main's children by POSITION, so once the main's
order changes the copies' shape-refs no longer match their position and, lacking a
swap slot, fail referential-integrity validation.

- Copy-side edits are handled correctly (characterization tests, pass today).
- The two main-side tests fail today with :missing-slot and go green once the
  sync assigns swap slots to copies on a main reorder/delete.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* 🐛 Fix integrity crashes from copy/main child-order divergence

Copy sub-heads were matched to their main's children purely by position
(find-near-match), while several code paths reorder or mutilate one side
only. Any of them made file validation fail with :missing-slot ("Shape
has been swapped, should have swap slot"), crashing the workspace on the
next validated commit, or persisting a corrupt file whose later edits
crash. Reproduced live: deleting a sub-head inside a copy (which only
hides it) and then reflowing the copy's grid moved the hidden (cell-less)
child to the front of :shapes, knocking every sibling out of its
positional slot.

Four fixes, one per divergence path:

- validate/check-required-swap-slot: a sub-head whose shape-ref is still
  a child of the near main parent is a REORDER (the component sync
  realigns it), not a swap; a swap slot is required only when the ref
  points outside the near main parent (a real swap). This matches how
  the sync engine itself pairs children (by shape-ref, not by position).
  comp-processors/fix-missing-swap-slots (migration 0019) is aligned:
  adding slots to merely-reordered sub-heads would freeze them out of
  normal synchronization.

- changes/:reorder-children now refuses to alter the child structure of
  component copies unless allow-altering-copies is set, mirroring the
  is-valid-move? rule of :mov-objects; that structure is owned by the
  component sync engine. Grid reflows emitted this change type with no
  guard. pcb/reorder-grid-children also skips copy grids producer-side.

- layout/reorder-grid-children keeps children that participate in no
  cell (hidden or absolute positioned) at their original index instead
  of lumping them at the front: moving them gratuitously changed their
  z-order and, in copies, broke the positional matching. Note :shapes
  stays reversed relative to the sorted cell order for in-cell children.

- logic/generate-delete-shapes: deleting shapes from inside a main
  (without deleting the main root, whose copies keep working against the
  deleted component) now also deletes the copy shapes that reference
  them, transitively (copies of copies) and across all pages of the
  file, so no dangling shape-refs remain. Skipped for
  allow-altering-copies flows (component swap replaces the shape and the
  sync reconciles copies via swap slots). Cross-page removals build
  redo/undo changes against that page's objects directly, since the
  changes-builder mounts only the current page; their undo mov-objects
  carry allow-altering-copies so restoring inside a copy is not rejected
  by the new guard.

The regression tests assert the fixed semantics: main-side reorders and
deletes keep copies valid, the previously crashing full chain (unvalidated
main reorder + later copy edit) stays healthy, :reorder-children cannot
scramble copies, and reorder-grid-children keeps cell-less children in
place. The namespace is now also registered in the JS test runner.

AI-assisted-by: Claude Opus 4.8 (1M context)

*  Extend composable slot cases to the grid-reflow crash sweep

Case D (CopySubheadDeletePreservesSlots) now sweeps which copy sub-head
is deleted (first or last) and whether the copy root is resized
afterwards, forcing a grid reflow: the reflow used to move the hidden
(cell-less) child to the front of the copy's children, shifting every
sibling out of its positional slot. Deleting the FIRST sub-head masked
the bug (moving it to the front is a no-op), which is why the case
passed before this sweep. The foundation layout is grid accordingly.

Case E (MainReorderKeepsCopySlots) no longer hangs the app now that a
main-side reorder leaves a valid file, so its warning docstring is
replaced: it runs as a routine test (verified headless, passing) and is
safe in a "run all".

SlotIntegrity's doc is updated to the new validator semantics (a slot is
required only for real swaps, not reorders); the positional alignment it
asserts remains the correct, stronger steady-state invariant for these
cases. The lockfile change materializes the playwright devDependency
already declared in package.json.

AI-assisted-by: Claude Opus 4.8 (1M context)

* 📚 Record copy/main order-divergence invariants in memories

Swap-slot semantics (membership, not positional; slots only for real
swaps), the copy-structure guards on :mov-objects/:reorder-children, the
grid reorder stability for cell-less children, and the main-side delete
propagation in generate-delete-shapes.

AI-assisted-by: Claude Opus 4.8 (1M context)

* 🐛 Add adjustements to the code

---------

Co-authored-by: Michael Panchenko <michael.panchenko@oraios-ai.de>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-30 13:25:03 +02:00
Eva Marco
e705b6e12c
🎉 Add components library (#10675)
* 🎉 Install react-aria-components

* 🎉 Create modal component in TS using react-aria-component

* 🎉 Create modal ds component

* 🎉 Separate header content and footer components

* 🐛 Remove mf/html macros when not needed

* 🎉 Solve little problems

* ♻️ Format files

* ♻️ Remove ModalCloseBtn

* 🐛 Fix CI

* ♻️ Remove unused files

* 🎉 Make close button not dependant on the modal header

* 🎉 Add footer with two slots

* 🎉 Improvements on modal

* 🐛 Fix package imports and remove login example code

---------

Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-07-30 13:05:28 +02:00