14615 Commits

Author SHA1 Message Date
alonso.torres
ef4d66c3aa 🐛 Apply remote changes under buffered local edits too
A remote commit undoes the pending local commits, applies the remote
changes and replays the local ones, so the local file ends like the
server will: remote first, local last. Only queued commits took part;
the ones still waiting in the persistence buffer (up to ~3s of edits)
stayed under the remote change. When both touched the same attribute,
the remote value won locally but lost on the server.

The buffer now lives in the store ([:persistence :buffer]) instead of
an rx buffer, so the rebase can reach it. A flush merges it per file
into queue entries that keep the list of commits they carry, and the
leave-page guard reads buffer and queue from the store. A buffer left
by a previous session is queued when persistence starts.
2026-11-05 23:59:32 +01:00
Andrey Antukh
45721bd836 🌐 Rehash and validate translations 2026-11-05 23:21:26 +01:00
Andrey Antukh
7d596f8197
🌐 Add translations for: French (Canada)
Currently translated at 92.5% (2185 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr_CA/
2026-11-05 22:20:21 +00:00
Andrey Antukh
fb49a992b0
🌐 Add translations for: Hindi
Currently translated at 73.3% (1731 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/hi/
2026-11-05 22:20:19 +00:00
Andrey Antukh
ebedd604e8
🌐 Add translations for: Swedish
Currently translated at 94.7% (2238 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/sv/
2026-11-05 22:20:18 +00:00
Andrey Antukh
c5a29c69e8
🌐 Add translations for: Serbian
Currently translated at 48.0% (1135 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/sr/
2026-11-05 22:20:16 +00:00
Andrey Antukh
5fcc1e375e
🌐 Add translations for: Yoruba
Currently translated at 41.1% (972 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/yo/
2026-11-05 22:20:14 +00:00
Andrey Antukh
dda0445314
🌐 Add translations for: Malay
Currently translated at 22.4% (530 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ms/
2026-11-05 22:20:12 +00:00
Andrey Antukh
3576248fb0
🌐 Add translations for: Hausa
Currently translated at 43.7% (1032 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ha/
2026-11-05 22:20:11 +00:00
Andrey Antukh
79b1e6e8ab
🌐 Add translations for: Dutch
Currently translated at 94.7% (2238 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/nl/
2026-11-05 22:20:09 +00:00
Andrey Antukh
21172c4f0e
🌐 Add translations for: Latvian
Currently translated at 67.8% (1603 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/lv/
2026-11-05 22:20:07 +00:00
Andrey Antukh
fa7834c508
🌐 Add translations for: Korean
Currently translated at 73.3% (1731 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ko/
2026-11-05 22:20:05 +00:00
Andrey Antukh
cd2c4332f3
🌐 Add translations for: Ukrainian (ukr_UA)
Currently translated at 75.3% (1779 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ukr_UA/
2026-11-05 22:20:04 +00:00
Andrey Antukh
0d80598ada
🌐 Add translations for: Croatian
Currently translated at 57.0% (1348 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/hr/
2026-11-05 22:20:02 +00:00
Andrey Antukh
24a191edd7
🌐 Add translations for: Portuguese (Portugal)
Currently translated at 56.2% (1327 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/pt_PT/
2026-11-05 22:20:00 +00:00
Andrey Antukh
f5fce6c5c5
🌐 Add translations for: Czech
Currently translated at 56.8% (1342 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/cs/
2026-11-05 22:19:59 +00:00
Andrey Antukh
0b72372e5d
🌐 Add translations for: Basque
Currently translated at 41.6% (984 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/eu/
2026-11-05 22:19:57 +00:00
Andrey Antukh
855352743a
🌐 Add translations for: Japanese
Currently translated at 94.6% (2235 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ja/
2026-11-05 22:19:56 +00:00
Andrey Antukh
50d58566cb
🌐 Add translations for: Polish
Currently translated at 40.9% (967 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/pl/
2026-11-05 22:19:54 +00:00
Andrey Antukh
8651e58aed
🌐 Add translations for: Italian
Currently translated at 79.2% (1870 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/it/
2026-11-05 22:19:52 +00:00
Andrey Antukh
50c716a0ae
🌐 Add translations for: Persian
Currently translated at 93.3% (2205 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fa/
2026-11-05 22:19:50 +00:00
Andrey Antukh
5fa7edb8e3
🌐 Add translations for: Chinese (Traditional Han script)
Currently translated at 92.9% (2194 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/zh_Hant/
2026-11-05 22:19:48 +00:00
Andrey Antukh
fae5036252
🌐 Add translations for: Hebrew
Currently translated at 80.0% (1889 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/he/
2026-11-05 22:19:47 +00:00
Andrey Antukh
cd95407035
🌐 Add translations for: Indonesian
Currently translated at 61.0% (1441 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/id/
2026-11-05 22:19:45 +00:00
Andrey Antukh
82be9680b2
🌐 Add translations for: Arabic
Currently translated at 40.7% (961 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ar/
2026-11-05 22:19:44 +00:00
Andrey Antukh
b27df30e36
🌐 Add translations for: Romanian
Currently translated at 70.5% (1666 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ro/
2026-11-05 22:19:42 +00:00
Andrey Antukh
bca9dfe906
🌐 Add translations for: German
Currently translated at 79.6% (1880 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/de/
2026-11-05 22:19:40 +00:00
Andrey Antukh
7351bac796
🌐 Add translations for: Portuguese (Brazil)
Currently translated at 50.3% (1188 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/pt_BR/
2026-11-05 22:19:39 +00:00
Andrey Antukh
3df670f291
🌐 Add translations for: Chinese (Simplified Han script)
Currently translated at 85.9% (2030 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/zh_Hans/
2026-11-05 22:19:36 +00:00
Andrey Antukh
8292320e30
🌐 Add translations for: Turkish
Currently translated at 94.7% (2238 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/tr/
2026-11-05 22:19:35 +00:00
Andrey Antukh
5c6f3ddb8b
🌐 Add translations for: Russian
Currently translated at 95.4% (2254 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ru/
2026-11-05 22:19:33 +00:00
Andrey Antukh
b58fa9b1bd
🌐 Add translations for: French
Currently translated at 94.7% (2238 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr/
2026-11-05 22:19:31 +00:00
Andrey Antukh
0032642399
🌐 Add translations for: Spanish
Currently translated at 99.6% (2352 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/es/
2026-11-05 22:19:29 +00:00
Andrey Antukh
2f19f68296
🌐 Add translations for: Catalan
Currently translated at 93.2% (2201 of 2361 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/ca/
2026-11-05 22:19:27 +00:00
Hosted Weblate
8a59ffd886
🌐 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/
2026-11-05 22:45:28 +01:00
Hosted Weblate
0c3a5de957
🌐 Merge branch 'origin/develop' into Weblate. 2026-11-05 22:45:23 +01:00
Andrey Antukh
97fe51e08b Merge remote-tracking branch 'origin/staging' into develop 2026-11-05 22:43:31 +01:00
Elena Torró
afc40a3309
🐛 Refresh wasm heap views after allocations and wasm calls (#12833)
Growing the heap detaches typed views taken before an alloc or a call.
Take them after, so reads and writes never hit a detached buffer.
2026-11-05 18:09:59 +01:00
Elena Torró
a32f5a9811
⚡ Index fonts by family when fixing deleted fonts on page load (#12853) 2026-11-05 17:51:42 +01:00
Elena Torró
02223a67fa
🐛 Fix unmoved layout child stretched during wasm gap drag (#12831)
Follow-up to 419513011c: only pure moves pass down to children in wasm.
Remove unused set-wasm-rotation-modifiers.
2026-11-05 17:33:07 +01:00
Eva Marco
eb6e976c01
♻️ Move the dashboard header styles to the DS (#12676)
* ♻️ Move the dashboard header styles to the DS

The page header of the dashboard and settings pages took its styles from
common/refactor/common-dashboard.scss. Move the rules still in use to
dashboard/common/header.scss, written with DS tokens:

- The page titles become heading* (title-large) with a class instead of
  a bare h1; the team section links get a class, and the active class
  moves from the li to the link.
- Drop the rules that matched nothing: .element-name, .context-menu,
  .icon and .btn-secondary inside the header, and the global .btn-primary
  and .btn-secondary (only the fonts page uses them; it keeps the old
  import until its open change lands).
- The sidebar and subscription styles imported the file without using
  it; drop the import.

The header looks the same (0 px in the new visual test). The title line
height goes from 1.15 to 1.4, which does not move the text.

AI-assisted-by: claude-opus-5-5

* ♻️ Move the dashboard libraries and search styles to the DS

Replace the deprecated spacing, size and border variables with DS
tokens and logical properties, and drop the refactor/ import.

- The search placeholder icon gets a class for its color instead of a
  .icon svg rule; its xl size already gives the 32px box.
- Delete the selectors no markup uses: .dashboard-projects in both
  files and .dashboard-shared in search.

No visual change (0 px in the new libraries and search visual test).

AI-assisted-by: claude-opus-5-5

* 🔥 Move the fonts page header to the DS and delete common-dashboard

The fonts page was the last user of common/refactor/common-dashboard.scss:
its header now uses the shared DS header styles and a DS heading, like
the other dashboard pages. Nothing else imports common-dashboard, so it
is deleted.

No visual change.

AI-assisted-by: claude-opus-5-5

* 📎 Remove a double blank line in the dashboard sidebar styles

Prettier rejects the two blank lines left after the imports, which made
the frontend lint fail in CI.

AI-assisted-by: claude-opus-5-5

* 📎 Remove a blank line between the subscription style imports

Stylelint (at-rule-empty-line-before) rejects the blank line left between
the @use rules after the common-dashboard import was dropped.

AI-assisted-by: claude-opus-5-5
2026-11-05 17:01:04 +01:00
Pablo Alba
f4a0d42363
🐛 Keep multi-select variant switches refreshing every instance (#12857)
* 🐛 Keep multi-select variant switches refreshing every instance

Multi variants-switch ended each swap with select-shape, which replaced
the selection, interrupted layout/WASM work, and navigated once per copy
so only one instance looked updated under flex. Skip per-swap select and
layout in the batch, re-read live geometry, coalesce layout ids via a
companion DataEvent, then restore selection once. The same path covers
Assets component-multi-swap. Frontend tests lock select-shape count,
layout coalesce, and mixed no-op selections.

Closes #12829

AI-assisted-by: Composer
2026-11-05 16:52:52 +01:00
Eva Marco
0f7e3fe92e
♻️ Use DS icon buttons in the path editing bar (#12682)
* ♻️ Use DS icon buttons in the path editing bar

The path editing bar now uses DS icon buttons (ghost, tooltip below) and
DS icons, like the top toolbar. The toggles (draw/move mode, handler
types, snap) use aria-pressed, and the handler type trigger uses the DS
flyout indicator, with no tooltip because its menu opens on hover.

This also shows the handler and snap icons again: since #12659 their
SVGs draw with currentColor, and the legacy %button-icon set color to
transparent, so they were invisible.

Add a visual test of the bar, its hover and the handler menu.

AI-assisted-by: claude-opus-5-5

* ♻️ Move the path editing bar styles to the DS

Drop the deprecated styles import, resolve --panel-border-color to
--color-background-quaternary and use logical properties, except top and
height of the bar, which its transition names.

Delete the selectors the DS buttons left unused: .handler-trigger and
.flyout-indicator (the DS icon button draws its own indicator).

No visual change.

AI-assisted-by: claude-opus-5-5

* 📎 Add the blank line stylelint expects in the path bar styles

Stylelint (scss/double-slash-comment-empty-line-before) rejects the
comment right after a declaration, which made the frontend lint fail in
CI.

AI-assisted-by: claude-opus-5-5
2026-11-05 16:28:56 +01:00
Belén Albeza
fa1b3d4708
⚡ Keep only the shape data the worker reads (#12840)
* ⚡ Keep only the shape data the worker reads

The worker kept a full copy of the current page for its selection and
snap indexes. It now keeps only the attributes the indexes and the
change replay read, and re-indexes only the shapes that changed.

On a 52k-shape page the worker heap goes from 698 MB to 286 MB.

Closes #12740

AI-assisted-by: claude-opus-5-5

* ♻️ Share the worker re-trim with its replay test

The worker and its replay test now share `retrim-objects`.

AI-assisted-by: claude-opus-5-5
2026-11-05 16:25:29 +01:00
Alexis Morin
d685163260
🌐 Add translations for: French (Canada)
Currently translated at 97.6% (2222 of 2275 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr_CA/
2026-11-05 14:51:23 +00:00
Nimesh
9d3d6da0d0
♻️ Migrate inspect components to modern syntax (#12435)
Migrate the remaining legacy components in the inspect module to the
modern rumext syntax: typography-block, text-block, svg-attr, svg-block,
selection-rect, selection-feedback, layer-item and left-sidebar.

Rename the ?-suffixed props of layer-item (component-child? to
is-component-child, hide-toggle? to hide-toggle) and drop the unused
sortable? and filtered? props passed from left-sidebar.

Relates to #9260

AI-assisted-by: claude-opus-5-5

Signed-off-by: Nimesh Kulkarni <167794819+GitNimay@users.noreply.github.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-11-05 15:47:59 +01:00
Elena Torró
d82b5a4b1e
🐛 Fix pasted text invisible in new text box (#12859) 2026-11-05 15:00:46 +01:00
Belén Albeza
eae2c5bc95
🐛 Fix flaky plugin creation parent test (#12858)
The svg-with-images case asserted that the stubbed rp/cmd! saw only the
URL upload RPC. clear-thumbnail sends :delete-file-object-thumbnails after
a 200 ms timer, so on slow CI runners that call was recorded too and the
assertion failed.

Count only the :create-file-media-object-from-url calls and expect one,
so unrelated RPCs no longer break the test.

AI-assisted-by: claude-opus-5-5
2026-11-05 13:26:19 +01:00
Belén Albeza
c6a9e62a4a
🐛 Fix typography in Settings (#12841) 2026-11-05 11:39:43 +01:00
Eva Marco
9349c3b778
♻️ Make the workspace logo and project name real links (#12699)
* ♻️ Give the workspace logo a real link and the DS logo asset

The Penpot logo in the workspace header was an <a> without href, so the
keyboard could not reach it and it could not open in a new tab. It now
links to the dashboard Recent page; a plain click still runs the in-app
navigation (prevent default), and Ctrl/Cmd-click opens the link in a
new tab.

The logo uses the DS raw-svg* asset instead of the legacy icon (same
drawing), with its own 32px class. The legacy svg kept its 500px height
attribute, so it overflowed the header by 222px above and below. This
was the last legacy icon in left_header.cljs.

New visual test "Shows the Penpot logo link": 0 px of difference at rest
and on hover.

AI-assisted-by: claude-opus-5-5

* ♻️ Make the workspace project name a real link

The project name in the workspace header was a div with on-click that
opened the project files in a new tab, so the keyboard could not reach
it. It is now a link to the same page with target "_blank": the browser
opens the new tab, and Tab, Enter and "Open link" work as for any link.

The left header visual test gives 0 px of difference.

AI-assisted-by: claude-opus-5-5
2026-11-05 11:32:08 +01:00