10591 Commits

Author SHA1 Message Date
Alejandro Alonso
b82ab0c830 Merge remote-tracking branch 'origin/staging' into develop 2026-07-02 13:52:25 +02:00
RenzoMXD
1c9ab691e6 🐛 Plugin API theme.addSet/removeSet accept proxy or set ID
Signed-off-by: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com>

🐛 Preserve validation errors for theme set APIs

Signed-off-by: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com>

Co-authored-by: Alonso Torres <alonso.torres@kaleidos.net>
2026-07-02 13:32:17 +02:00
Filip Sajdak
5b7447fbe4 🐛 Accept delay 0 in plugin API interaction setter
The InteractionProxy `delay` setter rejected `0` via `(not (pos? value))`,
so an immediate after-delay interaction (`interaction.delay = 0`) was
refused. The model allows it: `set-delay`
(common/.../shape/interactions.cljc) only asserts `check-safe-int`, with
no positivity constraint, and `safe-int` permits 0.

Replace the guard with `(or (not (sm/valid-safe-int? value)) (neg? value))`:
it allows 0 and positive integers, rejects negatives, and rejects
non-integers cleanly (the previous `number?` check let fractional values
through, which then failed the model's `check-safe-int` assertion
downstream).

Adds a regression test (delay round-trips a positive value, then 0).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>
2026-07-02 13:32:17 +02:00
Filip Sajdak
1c5c6ee072 🐛 Accept fractional border radius in plugin API shape setters
The ShapeProxy `borderRadius` setters (`borderRadius` and the four
per-corner variants) validated with `sm/valid-safe-int?`, so a fractional
radius (e.g. `shape.borderRadius = 7.5`) was rejected as invalid. The data
model types `:r1`-`:r4` as `::sm/safe-number` (shape.cljc), the radius
sidebar input only constrains `min 0` (not integer), and `set-radius-*`
store the value verbatim — so the plugin API was stricter than the model.
Same class of defect as the merged #9780.

Switch those 5 guards to `sm/valid-safe-number?`, keeping the existing
non-negative guard on the all-corners setter. Integer-only setters in the
file (`getRange` bounds, `setParentIndex`) keep `valid-safe-int?`.

Adds a regression test asserting fractional radius values are accepted
(with throwValidationErrors enabled).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>
2026-07-02 13:32:17 +02:00
Filip Sajdak
c7ee54e849 🐛 Accept fractional gap and padding in plugin API layout setters
The flex and grid layout proxies validated `rowGap`, `columnGap` and the
four padding setters with `sm/valid-safe-int?`, so a fractional value
(e.g. `flex.rowGap = 10.5`) was rejected as invalid. The data model types
`:row-gap`/`:column-gap` and `:p1`-`:p4` as `::sm/safe-number`
(layout.cljc), and the sidebar accepts decimals, so the plugin API was
stricter than the model — the same class of defect as the merged #9780.

Switch those 16 gap/padding guards (8 in flex.cljs, 8 in grid.cljs) to
`sm/valid-safe-number?`, matching the model and the predicate already used
by the flex-element setters in the same file. Integer-only setters
(`zIndex`, grid track indices/counts and cell positions/spans) keep
`valid-safe-int?`. Also fixes a `:righPadding` typo in two grid
rightPadding error branches.

Adds a regression test asserting fractional gap/padding values are
accepted (with throwValidationErrors enabled) for both flex and grid.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>
2026-07-02 13:32:17 +02:00
mvanhorn
ab623cc02d 🐛 Make overlay position optional in plugin open-overlay/toggle-overlay interactions 2026-07-02 13:32:17 +02:00
Filip Sajdak
76070008c2 🐛 Fix plugin API board.guides invalid-schema on set/clear
Setting or clearing `board.guides` from a plugin threw a malli
`:malli.core/invalid-schema` for every value, including `[]`. Causes:

- `shape.cljs` validated against `[:vector ::ctg/grid]`, but the
  `:app.common.types.grid/grid` reference is no longer registered
  (direct schemas replaced the namespaced-keyword registrations). Use
  the direct var `ctg/schema:grid`, matching every other setter.
- `parser.cljs` `parse-frame-guide` returned the `parse-frame-guide-column`
  / `parse-frame-guide-row` fns instead of calling them with the guide,
  so column/row guides parsed to a vector containing a function.
- `parse-frame-guide-square` used `parse-frame-guide-column-params`
  instead of the dedicated `parse-frame-guide-square-params`.

Adds a regression test parsing column/square guides and validating the
result (and an empty vector) against `ctg/schema:grid`.

Fixes #9773

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>
2026-07-02 13:32:17 +02:00
Filip Sajdak
8fe835a9cc 🐛 Surface real plugin errors instead of bare "Value not valid"
The plugin proxy `:on-error` handler funneled every throwable through
`handle-error`, which only produced a message for malli ExceptionInfo
carrying `::sm/explain`. Two paths lost the real cause and rendered the
unhelpful "[PENPOT PLUGIN] Value not valid. Code: :error":

- A plain JS error (TypeError, etc.) is not an ExceptionInfo, so
  `(ex-data cause)` is nil and the message bound to nil; the real
  `.-message` only reached the host-page console, invisible to the
  plugin sandbox.
- A malli explain whose errors flatten to nothing made `error-messages`
  return "", which rendered as "Value not valid: . Code: :error".

`error-messages` now returns nil (not "") when there is nothing to
render, and `handle-error` falls back to the raw explain, then to the
throwable's `ex-message`/`str`, so a useful message always surfaces.
Working cases (well-formed explain) are unchanged.

Adds regression tests for the plain-JS-error path, the empty-explain
path, and the `error-messages` nil contract.

Fixes #9692

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>
2026-07-02 13:32:17 +02:00
Eva Marco
f1f5a30624
🐛 Fix alignment selector for strokes (#10532) 2026-07-02 13:01:58 +02:00
Belén Albeza
6d458c80a1
🐛 Fix font and variant dropdowns on mixed text styles (#10520)
* 🐛 Fix dropdown shown Mixed Font Families for same family with different variant

* 🐛 Fix variants dropdown appearing blank on mixed variants but same family

*  Add playwright test for mixed font families/variants
2026-07-01 20:15:20 +02:00
Marina López
64ba70e6f3 🐛 Fix border color for selected subscription 2026-07-01 14:42:06 +02:00
Eva Marco
e6a341ff30
🐛 Fix text layout item menu (#10516) 2026-07-01 14:39:34 +02:00
Eva Marco
04254c9fd1
🐛 Fix token tooltips (#10515) 2026-07-01 14:30:18 +02:00
Eva Marco
665e8e018e
🐛 Fix overlay position grid (#10512) 2026-07-01 13:40:12 +02:00
Eva Marco
abbd28d101
🐛 Fix long text inside color tooltip (#10511) 2026-07-01 13:38:51 +02:00
Luis de Dios
7e8590b04c
🐛 Fix inspect in workspace displays shape size twice when selecting a shape (#10507) 2026-07-01 13:08:35 +02:00
Belén Albeza
215de966ae
🐛 Fix extra linebreak on MacOS IME (#10498)
* 🐛 Fix extra linebreak in Japense IME (MacOS)

* ♻️ Remove composing? from the state and query event instead
2026-07-01 12:40:25 +02:00
Elena Torró
c8f586a197
🐛 Fix async text rendering on tiles (#10504) 2026-07-01 11:09:57 +02:00
Alejandro Alonso
05e9c68a74
🐛 Fix preserving empty text fill when editing without changes (#10483) 2026-06-30 17:59:54 +02:00
Eva Marco
920c6d4e76
🐛 Fix token tooltips on numeric-input, color and typography (#10480) 2026-06-30 16:26:49 +02:00
Andrey Antukh
c4e72fd7f9 Merge remote-tracking branch 'origin/staging' into develop 2026-06-30 16:23:23 +02:00
Parinith
8d5b16295f
💄 Center libraries empty state placeholder vertically (#10452)
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-06-30 16:14:24 +02:00
Luis de Dios
28afe223f4
🐛 Invitations to a team can be sent to existing members without displaying any error (#10489)
* 🐛 Fix team invitations can be sent to existing members without displaying any error

*  Add tests
2026-06-30 15:39:59 +02:00
Alonso Torres
8823f7ac4d
Make v2 plugins default throw on error (#10433) 2026-06-30 14:50:50 +02:00
Luis de Dios
46f5346045
♻️ Merge :thumbnails and :thumbnails-meta into single state key (#10021)
* ♻️ Merge :thumbnails and :thumbnails-meta into single state key

♻️ Unify thumbnail refs in a single ref

🐛 Fix test

* ♻️ Update tests
2026-06-30 14:37:27 +02:00
Belén Albeza
e6a49adfbc
🐛 Fix crash on composition update when pressing Esc on a IME (#10479) 2026-06-30 13:55:06 +02:00
Alonso Torres
ca81776d04
🐛 Fix problems when dragging frame with comments (#10460)
* 🐛 Fix undo frame position not undoing comments

* 🐛 Fix problem with hover capturing dragging event

* 🐛 Fix watch updates for comment bubbles

* 🐛 Fix "Maximum update depth" crash on SVG shape transforms

* 🐛 Fix comment geometry problems
2026-06-30 13:33:47 +02:00
Alonso Torres
f993f203bd
🐛 Fix problems with plugins API (#10412)
*  Adds static dispatch safe stubs in tests

* 🐛 Fix shapesColors metadata key to match ColorShapeInfo

* 🐛 Fix CommentThread.remove rejecting the owner's own threads

* 🐛 Fix page.removeCommentThread throwing on a spurious Promise

*  Implement ShapeBase.swapComponent in the plugin API

*  Expose File.revn in the plugin API

* 🐛 Fix FileVersion.createdAt calling Luxon method on a js/Date

* 🐛 Fix plugin font/typography application to text and ranges

* 🐛 Default plugin overlay interaction position for non-manual types

* 🐛 Fix plugin interaction setters passing an id-only shape

* 🐛 Fix grid addColumnAtIndex rejecting valid track types

* 🐛 Expose libraryId on library color/typography/component proxies

*  Implement LibraryTypography.setFont in the plugin API

* 🐛 Fix typography.applyToTextRange reading unexposed range bounds

* 🐛 Fix utils.geometry.center argument mismatch

* 🐛 Fix localStorage.removeItem calling getItem

* 🐛 Fix shape backgroundBlur proxy key casing

* 🐛 Report boolean shape type as 'boolean' in the plugin API

* 🐛 Return the resulting paths from plugin flatten

* 🐛 Make plugin z-order methods act on the target shape

* 🐛 Make is-variant-container? return a boolean

*  Implement Group.isMask in the plugin API

* 🐛 Return a shape proxy from TextRange.shape

* 🐛 Return the duplicated set from TokenSet.duplicate

* 🐛 Fix theme addSet/removeSet reading set name with a keyword

* 🐛 Accept string fontFamilies token value in the plugin API

* 🐛 Fix combineAsVariants ignoring the passed component ids

* 🐛 Fix board removeRulerGuide ignoring its argument

* 🐛 Fix board guides setter schema and parser

* 🐛 Avoid 0-byte allocation when syncing empty grid tracks

* 🐛 Validate grid track indices in the plugin API

* 🐛 Return null for empty input in group() and centerShapes()

* 🐛 Return TokenTypographyValue[] from a typography token's resolvedValue

* 🐛 Return TokenShadowValue[] from a shadow token's resolvedValue

* 🐛 Return string[] from a fontFamilies token's resolvedValue

* 🐛 Clear mutually-exclusive reps when setting LibraryColor gradient/image

* 🐛 Add readonly tags to types, deprecate Image type

* 📚 Update plugins changelog
2026-06-29 17:32:15 +02:00
Aitor Moreno
2d4a24bf97
🐛 Fix stroke to path extra points (#10190)
* 🐛 Fix stroke to path extra points

* 🐛 Set evenodd when needed on stroke to path (#10446)

---------

Co-authored-by: Elena Torró <elenatorro@gmail.com>
2026-06-29 10:34:44 +02:00
Pablo Alba
a9f3949abc
Avoid going to last team on login if it is protected by sso (#10442) 2026-06-29 09:44:16 +02:00
Alonso Torres
a47b0122c7
🐛 Fix problem with measures menu (#10445) 2026-06-29 09:24:37 +02:00
Belén Albeza
e9c0982a94
Disable hot swap of render engines (#10444) 2026-06-26 15:04:52 +02:00
Andrey Antukh
5212e2202b Merge remote-tracking branch 'origin/staging' into develop 2026-06-26 14:34:00 +02:00
Alejandro Alonso
44e39a1008
🐛 Sync WASM viewport when locating board in grid layout editor (#10443) 2026-06-26 14:24:44 +02:00
Eva Marco
6a79383082
🐛 Blur info doesn't show on inspect in certain shapes (#10427)
* 🐛 Blur info doesn't show on inspect in certain shapes

* 🎉 Add test
2026-06-26 14:10:41 +02:00
Belén Albeza
10147b6abd
🐛 Fix pixel grid and board pixel grid shown on top of rulers (#10430)
* 🐛 Fix pixel grid shown on top of rulers

* 🐛 Fix board pixel grid being rendered above rulers
2026-06-26 11:53:11 +02:00
Luis de Dios
8e9fb91959
🐛 Fix view mode is not persisted in color picker (#10369) 2026-06-26 11:38:51 +02:00
Elena Torró
89f882ecda
🐛 Fix viewer rendering on Firefox+NVIDIA setup (#10385) 2026-06-26 10:59:22 +02:00
Luis de Dios
d16a2c93e0
🐛 Fix long typography token name in tooltip in design tab (#10387) 2026-06-26 10:50:19 +02:00
Luis de Dios
66719a14f5
🐛 Fix assets typography container is longer than others (#10406)
* 🐛 Fix assets typography container is longer than others

* ♻️ Use new SCSS guidelines
2026-06-26 09:42:22 +02:00
Alejandro Alonso
345affc687
🐛 Fix premature WASM view-interaction end during pan (#10425) 2026-06-25 15:07:37 +02:00
Juanfran
d328cb4a9e
Enable org owners to view organization teams (#10388) 2026-06-25 13:07:20 +02:00
Andrey Antukh
2eb9423963 Merge remote-tracking branch 'origin/staging' into develop 2026-06-25 09:33:15 +02:00
Andrey Antukh
f50d8edb13 Merge remote-tracking branch 'origin/main' into staging 2026-06-25 09:32:49 +02:00
Alonso Torres
28f3b8048a
Improve MCP handling when tab is frozen in the browser (#10392) 2026-06-25 08:27:33 +02:00
Jack Storment
aedb7f9195
Add dedicated Line and Arrow drawing tools (#9146)
*  Add dedicated Line and Arrow drawing tools

Introduce a Line/Arrow toolbar option and a click-drag drawing
interaction that matches Figma's workflow: select the tool, press and
drag to define the line in one gesture, with Shift snapping to 15°
increments. Arrowhead style can be toggled on either endpoint via the
existing stroke-cap controls.

Signed-off-by: jack-stormentswe <crazycoder131@gmail.com>

* 💄 Fix formatting error

Signed-off-by: jack-stormentswe <crazycoder131@gmail.com>

* 🐛 Translate line and arrow tooltips in top toolbar

Signed-off-by: Luis de Dios <luis.dedios@kaleidos.net>

* 🐛 Add missing namespace

Signed-off-by: Luis de Dios <luis.dedios@kaleidos.net>

* 📚 Update copyright notice

Signed-off-by: Luis de Dios <luis.dedios@kaleidos.net>

* Add translations (EN) for toolbar elements

Signed-off-by: Luis de Dios <luis.dedios@kaleidos.net>

* Add translations (ES) for toolbar elements

Signed-off-by: Luis de Dios <luis.dedios@kaleidos.net>

* ♻️ Improve stroke-cap-end update for arrow handling

Signed-off-by: Luis de Dios <luis.dedios@kaleidos.net>

* 🐛 Fix shortcuts select tool but do not replace it in the toolbar

Refactor tool selection logic in top_toolbar.cljs

Signed-off-by: Luis de Dios <luis.dedios@kaleidos.net>

* ♻️ Remove unnecessary blank line

Signed-off-by: Luis de Dios <luis.dedios@kaleidos.net>

---------

Signed-off-by: jack-stormentswe <crazycoder131@gmail.com>
Signed-off-by: Jack Storment <88656337+jack-stormentswe@users.noreply.github.com>
Signed-off-by: Luis de Dios <luis.dedios@kaleidos.net>
Co-authored-by: Luis de Dios <luis.dedios@kaleidos.net>
2026-06-24 21:32:13 +02:00
Alejandro Alonso
b096832bf5
🐛 Fix v2 text editor detaching typography tokens (#10402) 2026-06-24 18:20:21 +02:00
Luis de Dios
5ef8d35683
🐛 Fix avoid flashing the move tool before activating the selected tool (#10291) 2026-06-24 10:25:37 +02:00
Dexterity
a530cf0dec
♻️ Migrate render-wasm api object-svg to modern component syntax (#9459)
* ♻️ Migrate render-wasm api object-svg to modern component syntax

* 📎 Add minor changes

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

---------

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-06-24 10:24:53 +02:00
Dexterity
d757f96633
♻️ Migrate svg filter components to modern syntax (#9448)
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-06-24 10:21:18 +02:00