* 🐛 Fix setting a font-related properties to nil
* ✨ Repair already-corrupted text nodes
* 🐛 Fix deleted fonts appearing in Recents and as the auto-selected font for new text shapes
* 🐛 Prevent WASM panics during WebGL context restore
Delay context-restored until reload finishes and no-op app
mutations while reloading so resize/modifiers cannot panic
mid-teardown.
* 🐛 Fall back to CLJS bool content when WASM is not ready
Returning nil from calculate-bool would persist empty path content
during context loss/reload; use path/calc-bool-content instead.
* 🔧 Support background blur on PDF render for strokes and text shapes
* ✨ Add LRU eviction to the wasm image store
* ✨ Add RasterFormat to encode png, jpeg and webp from wasm
* 🐛 Fix client-side wasm export encoding jpeg and webp as png
Repair text shapes with empty/broken content at all three levels
(root, paragraph-set, paragraph) in migration 0025 to prevent
workspace update failures. Handle all corner cases: nil/empty/non-
vector children, non-map items, wrong types. Remove geometry-only
validation skip in changes.cljc so all shapes are validated.
AI-assisted-by: qwen3.7-plus
* 🐛 Fix several issues in RPC command handlers
- Reject circular library references in link-file-to-library
- Add explicit team permission check in search-files
- Constrain search-term max length to 250 chars
- Include :deleted-at in file ETag for COND caching
- Move storage I/O outside DB transaction in create-file-thumbnail
AI-assisted-by: deepseek-v4-pro
* 📎 Check perms before circular link checks
* 🐛 Handle circular library reference error
Catch :circular-library-reference error from backend when linking
files to libraries. Show user-friendly toast notification instead of
propagating unhandled error. Add English and Spanish translations.
AI-assisted-by: qwen3.7-plus
* 🐛 Fix area selection aborted by select-shapes interrupt
Only emit :interrupt from select-shapes when edition mode is active.
Unconditional :interrupt (from #10798) made drag-stopper cancel the
marquee mid-drag.
* 🔧 Fix text editor v2 fill e2e test on develop
* 🐛 Fix clipboard crash when copying as SVG
clipboard.write with an image/svg+xml payload throws an unhandled DOMException on browsers that do not support the type. Fall back to writeText for that specific failure.
Fixes#10596
Signed-off-by: Akshit Nassa <akshitnassa412@gmail.com>
* 📎 Update Kaleidos Copyright
Signed-off-by: Akshit Nassa <nassaakshit@gmail.com>
---------
Signed-off-by: Akshit Nassa <akshitnassa412@gmail.com>
Signed-off-by: Akshit Nassa <nassaakshit@gmail.com>
Co-authored-by: Akshit Nassa <akshitnassa412@gmail.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
Holding an arrow key on a selection with a fast OS key-repeat rate
crashed the workspace with React error #185 (Maximum update depth
exceeded): each OS key-repeat event was converted 1:1 into a
`set-modifiers`/`set-wasm-modifiers` store write inside
`nudge-selected-shapes` with no throttle, starving the renderer.
The sibling mouse-driven resize/rotate/move paths got an `rx/sample`
throttle in PR #10560; the keyboard-nudge path was the only transform
stream left un-throttled. This change applies the same `rx/sample`
throttle to the nudge stream, mirroring the drag-path structure, and
adds a regression test guarding the final committed position
invariant under a burst of 20 `move-selected` events for both the WASM
and legacy (non-WASM) branches.
Closes#10726
AI-assisted-by: glm-5.2
* 🎉 Add page multi-selection in the workspace sitemap
* ♻️ Simplify page selection state updates with single assoc
* 🐛 Fix SCSS issue
* ♻️ Update some components to new syntax
* ♻️ Adapt SCSS to the new guidelines
* ♻️ SCSS cleanup
---------
Co-authored-by: Luis de Dios <luis.dedios@kaleidos.net>
* 🐛 Fix geometry sync between mains and rotated component copies
Rotating a copy instance as a whole marked every shape inside it as
touched for geometry, so later geometric changes in the main (e.g. a
resize) were no longer propagated to that copy, while non-geometric
ones (e.g. fills) still were. And on paths where geometry did get
written to a rotated copy (e.g. resetting overrides), the sync engine
compensated only the roots' position delta, so the written values wiped
the copy's rotation back to 0.
Model the instance root's transformation as inherited, overridable
content, asymmetric to position (which remains free per-instance
placement):
- An untouched copy follows the main's transformation verbatim,
including rotation and flips (preserving the BUG #13267 semantics
that rotating a main propagates to its copies).
- Transforming a copy as a whole overrides only its ROOT: check-delta
compares the root's rotation/flips absolutely, but the descendants
relative to their root, so they merely follow and stay untouched.
- When a copy root's geometry is overridden, update-attrs expresses the
main's geometry in the copy's own frame: reposition-shape applies the
roots' relative transformation (rotation/flips) around the dest root
center in addition to the position delta. Geometric changes from the
main then keep propagating to the rotated copy, landing correctly in
its rotated frame instead of destroying its placement.
Covered by the new composable test case
case-n-geometry-sync-with-rotated-instances: an 8-variant sweep over
optional copy rotation, optional main rotation, and one of a fills or
height edit on the main child, asserting the whole model through the
real workspace events (the new rotate operation dispatches
dwt/increase-rotation, whose apply-modifiers step runs the check-delta
classification under test; change-height dispatches
dwt/update-dimensions and implements IPropertyCheck so one-of sweeps
can mix property and geometry edits). Verified by temporarily reverting
the fix: the case then fails with 6 assertion failures and passes again
with the fix restored.
Fixes#10109
AI-assisted-by: claude-fable-5
* 🐛 Fix synchronization problems
---------
Co-authored-by: alonso.torres <alonso.torres@kaleidos.net>
* 🐛 Fix too much recursion when clicking shape in comments mode
Remove `deselect-all` from `handle-interrupt` in comments mode. The
`select-shape` event emits `:interrupt` which the comments stream
watcher routes to `handle-interrupt`. In comments mode, calling
`deselect-all` cleared the selection and emitted a competing
`rt/nav`, creating a synchronous recursion cycle in the potok store
that overflowed the JS call stack.
Fixes#10620
AI-assisted-by: opencode
* 🐛 Add unit tests for comments handle-interrupt
Make `handle-interrupt` public (defn- → defn) and add 4 tests covering
each branch: draft thread, open thread, comments mode, and noop.
AI-assisted-by: opencode
Guard remaining text pipeline locations that accessed :selrect directly
against nil/zero-dimension selrects by using safe-size-rect, which
provides a 4-level fallback chain (selrect -> points -> shape fields ->
empty 0.01x0.01 rect).
Fixes:
- fix-position in viewport_texts_html.cljs: replaced dm/get-prop
:selrect with ctm/safe-size-rect for both old and new shape
- assoc-position-data in modifiers.cljs: replaced (:selrect ...)
with ctm/safe-size-rect for delta computation
- change-orientation-modifiers in modifiers.cljc: replaced raw
:selrect access with safe-size-rect for scale and origin computation
Closes#10617
AI-assisted-by: mimo-v2.5-pro
* ✨ 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
* 🐛 Fix stroke to path extra points
* 🐛 Set evenodd when needed on stroke to path (#10446)
---------
Co-authored-by: Elena Torró <elenatorro@gmail.com>
* ✨ 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>