59 Commits

Author SHA1 Message Date
Andrey Antukh
e9603f00b0 Merge remote-tracking branch 'origin/staging' into develop 2026-07-28 12:50:41 +02:00
Andrey Antukh
4b994d20aa
🐛 Fix leaked focus timers in dashboard sidebar navigation (#10715)
* 🐛 Fix leaked deferred DOM ops on dashboard navigation and template clone

The React reconciliation "removeChild" error surfaced during rapid
dashboard navigation because several effects scheduled deferred DOM
operations (focus, CSS positioning) without returning a cleanup that
cancelled them. When the component unmounted before the callback
fired, it ran against stale DOM and desynchronized React fiber tree
from the actual DOM.

- context_menu_a11y.cljs: replace tm/schedule-on-idle (30s idle
  window) with tm/schedule (setTimeout 0) and return a rx/dispose!
  cleanup.
- dropdown.cljs: capture the tm/schedule handle and dispose it in
  the effect cleanup.
- tooltip.cljs: capture the ts/raf handle and cancel it on cleanup.

AI-assisted-by: opencode-go/mimo-v2.5-pro

* 🐛 Fix leaked focus timers in dashboard sidebar navigation

Six sidebar navigation handlers scheduled setTimeout callbacks to mutate
tabindex/focus on React-managed title elements without cancelling prior
pending callbacks. During rapid keyboard navigation (Projects→Fonts→Libs→Drafts)
the stale callbacks fired against unmounted DOM, desyncing React fiber tree
and triggering "removeChild" NotFoundError.

- sidebar-project*: cancel prior timer in on-key-down
- sidebar-search*: cancel prior timer in on-key-press
- sidebar-content*: cancel prior timer in go-projects-with-key,
  go-fonts-with-key, go-drafts-with-key, go-libs-with-key

Each handler now stores the timer handle in a component-level ref and
disposes any pending handle before scheduling a new one.

AI-assisted-by: opencode-go/mimo-v2.5-pro

* ♻️ Refactor sidebar focus timer handling into helpers

Extract the repeated dispose-before-schedule focus idiom into
schedule-focus-by-id! (sidebar.cljs) and focus-and-untabbable!
(app.util.dom). Replaces the six duplicated blocks and adds
mf/use-effect unmount cleanup to dispose any pending timer in the
three sidebar components, closing the remaining leak noted in the
original fix.

AI-assisted-by: opencode/hy3-free

* ♻️ Extract use-focus-timer-ref hook for sidebar components

Replace the duplicated mf/use-ref + mf/use-effect cleanup pairs in
sidebar-project*, sidebar-search*, and sidebar-content* with a shared
use-focus-timer-ref hook (app.main.ui.hooks). The hook creates the ref
and disposes any pending timer on unmount via mf/with-effect, reading the
ref with mf/ref-val instead of deref. mf/use-effect is now a body-level
hook call rather than a let binding.

AI-assisted-by: opencode/hy3-free

* 📎 Add pr feedback fix
2026-07-28 11:06:00 +02:00
Eva Marco
5de06e8f77
🎉 Add customizable shortcuts (#10237)
Co-authored-by: alonso.torres <alonso.torres@kaleidos.net>
2026-07-24 10:36:32 +02:00
Juan de la Cruz
fa996ab240
Add list view toggle for dashboard files (#10692)
*  Add list view toggle for dashboard files

*  Add drop files visual feedback

* ♻️ Use radio buttons component from DS

* ♻️ Use hook to keep layout status

* ♻️ Refactor code and SCSS

---------

Co-authored-by: Luis de Dios <luis.dedios@kaleidos.net>
2026-07-21 13:16:10 +02:00
Andrey Antukh
c39609b991
♻️ Use shared singleton containers for React portals (#8957)
Refactor use-portal-container to allocate one persistent <div> per
logical category (:modal, :popup, :tooltip, :default) instead of
creating a new div for every component instance. This keeps the DOM
clean with at most four fixed portal containers and eliminates the
arbitrary growth of empty <div> elements on document.body while
preserving the removeChild race condition fix.
2026-04-14 10:48:30 +02:00
Andrey Antukh
5fca9457cf
♻️ Extract use-portal-container hook to reduce duplication (#8798)
The dedicated-container portal pattern was repeated across 6 components.
Extract it into a reusable use-portal-container hook under app.main.ui.hooks.
2026-03-26 12:45:42 +01:00
Andrey Antukh
e730e9ee64
🐛 Fix subscribe to undefined stream error in use-stream hook (#8633)
Add a nil guard before subscribing to the stream in the use-stream
hook. When a nil/undefined stream is passed (e.g., from a conditional
expression or timing edge case during React rendering), the subscribe
call on undefined causes a TypeError. The guard ensures we only
subscribe when the stream is defined.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-17 10:06:16 +01:00
Luis de Dios
544bedf7c2
🎉 Reorder properties for a component (#7429)
* 🎉 Reorder properties when a component with variants is selected

* 🎉 Reorder properties when a single variant is selected

* ♻️ Refactor SCSS and component structure

* 📚 Update changelog

* 📎 PR changes (styling)

* 📎 PR changes (functionality)
2025-10-08 11:27:01 +02:00
Andrey Antukh
41994703a9
♻️ Refactor tab-switcher* component (#6815)
* 💄 Add minor style adjustments to workspace sidebar

* 💄 Add style enhacement to sitemap component

* ♻️ Refactor tab-switcher* component
2025-07-02 14:08:47 +02:00
Andrey Antukh
403d92838a
♻️ Add minor refactor to options dropdown options handling and validation (#6739)
* ♻️ Refactor options-dropdown* and related components

* 🐛 Fix props error

* 🐛 Fix test

* 📎 Update rumext

---------

Co-authored-by: Eva Marco <evamarcod@gmail.com>
2025-06-29 11:52:29 +02:00
Alejandro Alonso
a1fc785771 Merge remote-tracking branch 'origin/staging' into superalex-merge-conflicts-2 2024-09-23 10:08:06 +02:00
Andrey Antukh
179d534237 🐛 Fix several issues related to invalid colors inserted on shadows 2024-09-16 18:32:40 +02:00
Andrey Antukh
c8caca77a3 Add storage namespacing
Allows separate global properties from user specific properties
2024-09-13 11:30:55 +02:00
Andrey Antukh
9619fcbc1f Make efficiency improvements to use-shared-state hook 2024-09-04 16:20:00 +02:00
Belén Albeza
78aafa4635 🐛 Fix layer and component names inputs not having their text selectable on Firefox 2024-03-27 12:02:15 +01:00
alonso.torres
497b581576 Change drag component to instantiate on enter the viewport 2024-02-01 10:23:34 +01:00
alonso.torres
4f09688af7 🐛 Fix several SVG upload issues 2024-01-24 10:51:22 +01:00
Andrey Antukh
833871df65 💄 Format frontend code 2024-01-08 09:32:50 +01:00
Andrey Antukh
96f5a33f5f ⬆️ Upgrade to beicon2 (part1) 2023-12-26 14:14:20 +01:00
alonso.torres
030ff398ed Improved dashboard thumbnails 2023-12-13 16:12:41 +01:00
alonso.torres
39b41d7037 Reorder grid tracks moving content 2023-12-07 16:54:48 +01:00
alonso.torres
e9a42bbc69 💄 Small visual fixes 2023-12-01 15:49:41 +01:00
alonso.torres
76a2f9bc8c Dashboard respect ratio for thumbnails 2023-12-01 15:42:13 +01:00
Andrey Antukh
0977799960 💄 Add minor cosmetic changes to the use-dynamic-grid-item-width hook 2023-11-29 09:15:53 +01:00
alonso.torres
58afa7498e ♻️ Move card width calculation to hook 2023-11-28 09:23:38 +01:00
Andrey Antukh
52fbc678f3 ♻️ Move app.common.pages to app.common.files 2023-11-16 11:07:36 +01:00
Pablo Alba
fac72a5874 🎉 Component swap 2023-10-11 12:24:11 +02:00
Andrey Antukh
1b420e55f4 Add more DOM attrs friendly render-id generation hook 2023-09-12 11:40:41 +02:00
Andrey Antukh
1e2603f1f5 Add minor improvements to use-visible hook 2023-09-01 12:50:29 +02:00
Aitor
4b8ee8ef84 Update to React 18 2023-08-21 14:34:54 +02:00
Andrey Antukh
0bc468f434 Optimize layer-item component 2023-07-11 17:27:35 +02:00
Andrey Antukh
405aa66357 🎉 Add new shape & rect data structures
Also optimizes some functions for faster shape and rect props
access (there is still a lot of work ahead optimizing the rest of
the functions)

Also normalizes shape creation and validation for ensuring
correct setup of all the mandatory properties.
2023-07-11 17:27:35 +02:00
Pablo Alba
d8bb62c498 🐛 Fix layer drag enabled on chrome when is readonly 2022-12-05 10:37:56 +01:00
Pablo Alba
cd47c0356a 🎉 Add workspace read-only setting 2022-11-29 17:28:00 +01:00
Pablo Alba
369dc8ffb5 🎉 Basic changes to use penpot as a library 2022-10-18 08:51:28 +02:00
luz paz
e30bea0b6f 🔧 Fix typos in source code
Found via `codespell -q 3 -S *.po,./frontend/yarn.lock -L childs,clen,fpr,inflight,ody,ot,ro,te,trys,ue`
2022-10-04 10:40:34 +02:00
Andrey Antukh
748499a26f 🎉 Add lazy loading of thumbnails on dashboard 2022-09-28 09:47:13 +02:00
Andrey Antukh
8bdfd188d8 ⬆️ Upgrade shadow-cljs and rumext dependency 2022-09-28 09:45:43 +02:00
Eva
6e33d5b311 🐛 Fix library color selector 2022-09-22 15:32:15 +02:00
Andrey Antukh
9950c5dc0f 🎉 Add shared state hook and broadcast channel api 2022-08-12 15:11:20 +02:00
Andrey Antukh
8d06227d1e ♻️ Refactor state management of colorpicker & gradients 2022-08-12 15:11:20 +02:00
alonso.torres
b576ef02af Performance improvements 2022-04-22 11:09:58 +02:00
alonso.torres
78d7fe3e10 New focus mode in workspace 2022-03-02 10:41:13 +01:00
Eva
4285972e41 Add new zoom options in workspace and viewer mode 2022-01-17 17:18:12 +01:00
Josh Soref
589e646023 🐛 Fix typos in frontend 2021-11-15 09:51:34 -05:00
Andrey Antukh
b64d5ef357 🎉 Add unified logging api. 2021-09-30 11:48:14 +02:00
Andrey Antukh
e0846ce00e Fix linter issues on frontend (part 4). 2021-06-18 11:20:25 +02:00
Andrey Antukh
068c94da4e ♻️ Replace frontend transit ns usage with common transit. 2021-05-31 11:04:32 +02:00
alonso.torres
6a68e9c118 ♻️ Refactor embed resouces 2021-05-25 10:12:09 +02:00
Andrey Antukh
4b7f82a9d9 ♻️ Improves shortcuts lifecycle management. 2021-05-13 14:34:31 +02:00