21605 Commits

Author SHA1 Message Date
Alejandro Alonso
078663b0fa 🔧 Fix rust linter errors 2026-04-24 09:52:51 +02:00
Alejandro Alonso
7532bf411c Merge remote-tracking branch 'origin/develop' into develop 2026-04-24 09:32:35 +02:00
Alejandro Alonso
984d292ab2 Merge remote-tracking branch 'origin/staging' into develop 2026-04-24 09:29:24 +02:00
Full Stack Developer
25e6b939ba
Show detailed messages on file import errors (#9004)
*  Show detailed messages on file import errors

Signed-off-by: jsdevninja <topit89807@gmail.com>

*  Fix test

*  Fix build error

---------

Signed-off-by: jsdevninja <topit89807@gmail.com>
2026-04-24 09:13:46 +02:00
FairyPiggyDev
361c1c574b
🐛 Fix plugin parse-point returning plain map instead of Point record (#9129)
The plugin parser's parse-point returned a plain `{:x … :y …}` map,
but shape interaction schemas (for example schema:open-overlay-interaction)
require the attribute to be a `::gpt/point` record. `(instance? Point {:x 0 :y 0})`
is false, so validation silently rejected plugin `addInteraction` calls
that passed `manualPositionLocation`; only a console warning was produced.

Change parse-point to return a `gpt/point` record via `gpt/point`.
All three call sites (parser.cljs:open-overlay, plugins/page.cljs,
plugins/comments.cljs) continue to work because Point records support
the same `:x`/`:y` access plain maps do.

Add a unit test that covers nil input and verifies the returned value
satisfies `gpt/point?`.

Github #8409

Signed-off-by: FairyPigDev <luislee3108@gmail.com>
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 09:12:13 +02:00
Juan Flores
841b2e156e
🐛 Fix typography style creation with tokenized line-height (#9121)
When a text element has a line-height coming from a design token, the value
may be a number (e.g. 1.5) and fails frontend data validation expecting a
string. Normalize line-height before creating the typography style so the
operation succeeds without throwing an assertion error.

Signed-off-by: juan-flores077 <toptalent399@gmail.com>
2026-04-24 09:11:31 +02:00
boskodev790
6c7843f4b6
🐛 Fix obfuscate-email crashing on malformed email or dotless domain (#9120)
The viewer-side `obfuscate-email` helper used by `anonymize-member` when
building share-link bundles called `clojure.string/split` on the raw
email input and then on the extracted domain. Two failure modes:

1. When the stored email had no `@` (legacy data, LDAP-sourced UIDs, direct
   DB inserts, or fixtures that bypassed `::sm/email`), destructuring
   left `domain` bound to `nil` and the follow-up `(str/split nil "." 2)`
   raised `NullPointerException`. Because `obfuscate-email` runs inside
   `get-view-only-bundle`, the exception aborted the whole RPC response
   for share-link viewers, not just the field.

2. When the stored email used a single-label domain (`alice@localhost`),
   `(str/split "localhost" "." 2)` returned `["localhost"]`; destructuring
   bound `rest` to `nil` and the final `(str name "@****." rest)` produced
   a dangling-dot output `"****@****."` (nil coerces to empty in `str`).

Guard both split calls with `(or x "")` so the chain is nil-safe, and
emit the trailing `.<tld>` segment only when `rest` is present. Add three
`deftest` groups covering the happy path, dotless domains, and malformed
inputs (nil / empty / no-`@`), plus a CHANGES.md entry under the 2.17.0
Unreleased bugs-fixed section.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 09:09:49 +02:00
Renzo
8aacda2249
Add Shift+Numpad0/1/2 zoom shortcut aliases (#2457) (#9063)
Signed-off-by: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com>
2026-04-24 09:08:31 +02:00
wdeveloper16
50bee5e176
Add clipboard:read/write permissions to plugin system (#6980) (#9053)
*  Add clipboard:read/write permissions to plugin system (#6980)

* 🔧 Fix prettier formatting in clipboard permission files

---------

Co-authored-by: wdeveloper16 <wdeveloer16@protonmail.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 09:07:58 +02:00
Andrey Antukh
7135782e7d Merge remote-tracking branch 'origin/main-staging' into staging 2026-04-24 08:19:47 +02:00
Andrey Antukh
fd38f5b431 Merge remote-tracking branch 'origin/main' into main-staging 2026-04-24 08:18:55 +02:00
Andrey Antukh
2d5e50f352 ⬆️ Update root repo deps 2026-04-24 08:17:32 +02:00
wdeveloper16
e280168de9
Add read-only preview mode for saved versions (#7622) (#8976)
*  Add read-only preview mode for saved versions (#7622)

* 🔧 Address review feedback on version preview (#7622)

* 🐛 Fix version preview for WASM renderer (#7622)

* 🐛 Fix stylelint color-named and color-function-notation in preview banner (#7622)

* 🐛 Fix invalid-arity call to initialize-workspace in exit-preview (#7622)

* 🐛 Fix unclosed defn paren in exit-preview (#7622)

* ♻️ Refactor version preview/restore flow

Separate enter-preview and enter-restore flows with dedicated dialogs
instead of a persistent banner. Removes preview-banner component in favor
of inline actions dialog. Uses backup/restore pattern for exit-preview
instead of full workspace reinitialization. Adds analytics events for
preview/restore actions.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>

*  Extract on-name-input-focus as namespace-level private function

The callback had no dependencies on component-local state or props,
making it a pure function that can be hoisted to a defn-. This avoids
recreating the same callback identity on every render of version-entry*.

*  Extract extract-id-from-event helper to deduplicate snapshot callbacks

Three callbacks in snapshot-entry* shared the same DOM extraction logic
(get current target, read data-id, parse UUID). Extracted into a private
defn- to remove the duplication and simplify each callback.

*  Extract pure state-update callbacks from versions-toolbox* to namespace level

Eight callbacks that only emit fixed Potok events with no meaningful
deps were hoisted out of the component as defn- functions:

- on-create-version
- on-edit-version
- on-cancel-version-edition
- on-rename-version
- on-delete-version
- on-pin-version
- on-lock-version
- on-unlock-version

These no longer need mf/use-fn wrappers since namespace-level functions
have stable identity across renders, avoiding unnecessary callback
recreation on each render cycle.

*  Rename filter parameter to filter-value in on-change-filter to avoid core shadowing

The parameter name 'filter' shadowed clojure.core/filter within the
function scope. Renamed to 'filter-value' for clarity and to prevent
potential bugs if core/filter were needed in future changes.

* 🔧 Fix linter warnings and errors across version-related namespaces

frontend/src/app/main/ui/workspace.cljs:
- Remove unused requires: app.common.data, app.main.data.notifications,
  app.main.data.workspace.versions

frontend/src/app/main/data/workspace/versions.cljs:
- Remove unused require: app.common.uuid
- Fix duplicate reify type: enter-restore used ::restore-version
  (same as the private restore-version fn), renamed to ::enter-restore
- Remove unused bindings: state in enter-restore, team-id in
  exit-preview and restore-version-from-plugin

---------

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Signed-off-by: wdeveloper16 <wdeveloer16@protonmail.com>
Co-authored-by: wdeveloper16 <wdeveloer16@protonmail.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 08:13:16 +02:00
Renzo
7c1a29ccf7
🐛 Remove corepack dependency from MCP server for Node.js 25+ (#9119)
* 🐛 Remove corepack dependency from MCP server for Node.js 25+

* 🐛 Update
2026-04-23 22:08:11 +02:00
Luis de Dios
cd417443f6
🐛 Fix layer hierarchy to match old and new SCSS (#9126) 2026-04-23 18:00:40 +02:00
Eva Marco
0c60db56a2
🐛 Fix multiselection error with typography texts (#9071)
* 🐛 Ensure typography-ref attrs are always present and fix nil encoding

Add :typography-ref-file and :typography-ref-id (both defaulting to nil)
to default-text-attrs so these keys are always present in text node maps,
whether or not a typography is attached.

Skip nil values in attrs-to-styles (Draft.js style encoder) and in
attrs->styles (v2 CSS custom-property mapper) so nil typography-ref
entries are never serialised to CSS.

Replace when with if/acc in get-styles-from-style-declaration to prevent
the accumulator from being clobbered to nil when a mixed-value entry is
skipped during style decoding.

* 🎉 Add test

---------

Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-23 16:08:56 +02:00
Marina López
a3c330d6e7 Add downgrade nitrate to unlimited modal 2026-04-23 12:54:42 +02:00
Elena Torro
96722fde4b 🐛 Support EvenOdd SVG attribute across all path operations 2026-04-23 12:02:40 +02:00
Elena Torro
4a549d0907 Drain GPU queue during pan/zoom to avoid render_from_cache hitch 2026-04-23 11:19:51 +02:00
Eva Marco
d6b341c053
🐛 Fix color token (#9095) 2026-04-23 10:51:30 +02:00
Eva Marco
5c9696e20c
🐛 Fix color dropdown option update (#9100) 2026-04-23 10:51:20 +02:00
Eva Marco
28b33b9acc
🐛 Fix props on text components (#9099) 2026-04-23 10:49:48 +02:00
Andrey Antukh
c6b6b9ce00 📎 Update changelog 2.14.4 2026-04-23 09:59:11 +02:00
Yamila Moreno
5f7de04efe
🚑 Fix email blacklisting (#9122) 2026-04-23 09:42:40 +02:00
Elena Torró
d43d1f431f
Merge pull request #9112 from penpot/superalex-improve-atlas-growth
🎉 Improve atlas growth
2026-04-23 09:22:39 +02:00
Yamila Moreno
dc8073f924 🐳 Add PENPOT_PUBLIC_URI to penpot-frontend 2026-04-23 09:06:10 +02:00
Renzo
5bbb2c5cff
🐛 Fix Copy as SVG for multi-shape selection (#838) (#9066)
Signed-off-by: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com>
2026-04-22 19:46:38 +02:00
Alejandro Alonso
9e990a975a 🎉 Improve atlas growth 2026-04-22 17:21:11 +02:00
Andrey Antukh
ba42cc04b7 ♻️ Derive v-sizing from values instead of passing as prop
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-04-22 14:17:15 +00:00
Luis de Dios
b60695f54a 🐛 Fix indicate that the mcp is disabled if the mcp key has expired
If the mcp key has expired, the switch that indicates the status in the dashboard will appear as disabled, and will show a modal for regenerate the key. It will also appear as disabled in the workspace, not allowing the plugin to connect
2026-04-22 16:00:52 +02:00
Yamila Moreno
3c542a1abc
🐛 Fix email validation (#9037) 2026-04-22 15:59:28 +02:00
Dexterity
3fd976c551
🐛 Fix UI bugs in account settings forms (#8997)
Closes #8977
Closes #8979

Signed-off-by: Dexterity <173429049+Dexterity104@users.noreply.github.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-22 15:21:02 +02:00
Edwin Rivera
7dbd602d1e
🐛 Fix text export with custom fonts across SVG, PNG and JPG (#9094)
* 🐛 Fix text export with custom fonts across SVG, PNG and JPG

Text layers using custom or non-standard fonts were rendered incorrectly
on export regardless of the target format. The exporter was not resolving
the font face correctly before rasterization/serialization, causing the
output to fall back to a default glyph set and producing broken or
misaligned text. This fix ensures font data is resolved and embedded
consistently in the export pipeline for all output formats.

Signed-off-by: Edwin Rivera <bytelogic772@gmail.com>

* 📚 Add entry to CHANGES.md under 2.17.0

Signed-off-by: edwin-rivera-dev <bytelogic772@gmail.com>

---------

Signed-off-by: Edwin Rivera <bytelogic772@gmail.com>
Signed-off-by: edwin-rivera-dev <bytelogic772@gmail.com>
2026-04-22 15:19:58 +02:00
Juanfran
7d4092eeba 🐛 Fix column name mismatch when accepting org invitation 2026-04-22 14:24:03 +02:00
Elena Torro
f673b32567 🐛 Fix image loading callback 2026-04-22 14:00:49 +02:00
Full Stack Developer
d384f47253
🐛 Fix internal error on layer prev/next sibling selection (#9003)
Signed-off-by: jsdevninja <topit89807@gmail.com>
2026-04-22 13:59:42 +02:00
Andrey Antukh
8ad30e14b6 Merge remote-tracking branch 'origin/staging' into develop 2026-04-22 13:34:00 +02:00
Andrey Antukh
b0b2c0d264 📎 Update version on mcp/ module 2026-04-22 13:18:24 +02:00
Andrey Antukh
f00ea8789f 📎 Update version on mcp module 2026-04-22 13:16:34 +02:00
Andrey Antukh
112e81c397 📎 Fix the version reference
Caused by the recent version changes
2026-04-22 13:14:04 +02:00
moorsecopers99
b6487015b8
Add loader feedback while importing and exporting files (#9024)
*  Add loader feedback while importing and exporting files

Show a loader icon with a status label ("Importing files…" /
"Exporting files…") in the import and export dialog footers while the
operation is running, so users get clear in-progress feedback and
cannot retrigger the action by mistake.

Closes #9020

Signed-off-by: moorsecopers99 <patellscott18@gmail.com>

*  Address import/export loader feedback PR review

- Show the loader beside file names in the import dialog while files
  are being imported (previously queued entries kept showing the
  Penpot logo until each one moved into :import-progress).
- Drop the loader from the "Importing files…" / "Exporting files…"
  footer status, leaving just the text styled with the modal title
  color, per the design proposal.

Signed-off-by: moorsecopers99 <patellscott18@gmail.com>

*  Match design proposal for import/export progress feedback

- Move the in-progress label from the modal footer into the modal
  body, under the file rows, styled italic with the modal title
  color.
- Rename the labels to match the design wording: "Uploading file…"
  for import and "Downloading file…" for export.
- Restore the disabled "Accept" button in the import footer during
  the import-progress phase, mirroring the disabled "Close" button
  used by export.

Signed-off-by: moorsecopers99 <patellscott18@gmail.com>

* 🐛 Rename deprecated bodySmallTypography mixin to body-small-typography

Signed-off-by: moorsecopers99 <patellscott18@gmail.com>

---------

Signed-off-by: moorsecopers99 <patellscott18@gmail.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-22 13:12:48 +02:00
Andrey Antukh
88008ce16c 📎 Update mcp types yaml file 2.15.0-RC1 2026-04-22 13:11:10 +02:00
Andrey Antukh
75d99a0725 🔧 Add missing public uri handling on nginx entrypoint 2026-04-22 13:11:10 +02:00
Andrey Antukh
09637f9794 Allow render entrypoint load alternative config
The render entrypoint is used by exporter
2026-04-22 13:11:10 +02:00
Andrey Antukh
3225319e0c 🐛 Fix frontend tests 2026-04-22 12:54:07 +02:00
Edwin Rivera
2579527e64
🎉 Add get-file-stats RPC command (#9074)
* 🎉 Add get-file-stats RPC command

Introduce a new lightweight RPC query that returns aggregate statistics
for a single file: page count, shape counts by type, component/color/
typography counts, and inbound and outbound library reference counts.
Mirrors the existing get-file-summary permission and decoding pattern.

Useful for plugin authors enforcing per-file budgets, the
@penpot/library npm SDK, and future admin dashboards. Purely additive
— no migrations, no UI, no breaking changes.

Signed-off-by: edwin-rivera-dev <bytelogic772@gmail.com>

* 🐛 Bind *load-fn* around file data walk in get-file-stats

The binding previously wrapped only  — a plain key
lookup that does not realize any pointers — so by the time
 walked  and accessed  on
each page,  was unbound and every PointerMap
dereference threw , failing the three new  tests.

Move  inside the  form so the walk runs
with  available, matching the existing pattern used in
.

Signed-off-by: Edwin Rivera <bytelogic772@gmail.com>

---------

Signed-off-by: edwin-rivera-dev <bytelogic772@gmail.com>
Signed-off-by: Edwin Rivera <bytelogic772@gmail.com>
2026-04-22 12:49:39 +02:00
Elena Torró
3561b2d1eb
Merge pull request #9078 from penpot/alotor-fix-thumbnail-errors
🐛 Fix errors in thumbnails
2.16.0-RC1
2026-04-22 12:00:56 +02:00
Elena Torró
ba1842792f
Merge pull request #9076 from penpot/alotor-fix-flex-align-self
🐛 Fix default alignself behavior
2026-04-22 11:55:00 +02:00
Eva Marco
09fca1c820
🐛 Fix tooltip appearing two times when nested elements (#9031) 2026-04-22 11:33:43 +02:00
Aitor Moreno
e3981a0cf3
Merge pull request #9077 from penpot/ladybenko-13971-fix-trailing-whitespace
🐛 Fix trailing whitespace behavior in v2 editor
2026-04-22 11:30:01 +02:00