mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
⚡ Memoize static options in vertical-align* component
Wrap the radio-button options vector in `mf/with-memo []` so the vector allocation and `(tr ...)` calls happen once per component mount instead of on every render. Also document the translation memoization rule in frontend/AGENTS.md: `(tr ...)` must never be called at namespace level (locale is runtime-only), and static option lists should always be wrapped in `mf/with-memo []`. Signed-off-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
parent
11c970a945
commit
6c19c7c0c4
@ -329,6 +329,31 @@ CSS modules pattern):
|
|||||||
- [ ] Selectors are flat (no deep nesting).
|
- [ ] Selectors are flat (no deep nesting).
|
||||||
|
|
||||||
|
|
||||||
|
### Translations (`tr`) and Memoization
|
||||||
|
|
||||||
|
`(tr "some.key")` resolves the translation string from the **currently active
|
||||||
|
locale at call time**. This has two consequences:
|
||||||
|
|
||||||
|
- **Never call `(tr ...)` at namespace level** (inside a `def` or `defonce`).
|
||||||
|
Doing so would freeze the label to the locale active at module load time and
|
||||||
|
break runtime language switching.
|
||||||
|
- **Always call `(tr ...)` at render time** — either directly in the component
|
||||||
|
body or inside a `mf/with-memo` / `mf/use-memo` block.
|
||||||
|
|
||||||
|
When a component renders a **static list of options** whose labels come from
|
||||||
|
`(tr ...)` (e.g. radio button options, select options), wrap the vector in
|
||||||
|
`mf/with-memo []` with no dependencies. This ensures the vector and its
|
||||||
|
`(tr ...)` calls are evaluated once per component mount instead of on every
|
||||||
|
render, while still respecting the render-time requirement:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(let [options (mf/with-memo []
|
||||||
|
[{:value "top" :label (tr "some.key.top")}
|
||||||
|
{:value "center" :label (tr "some.key.center")}
|
||||||
|
{:value "bottom" :label (tr "some.key.bottom")}])]
|
||||||
|
...)
|
||||||
|
```
|
||||||
|
|
||||||
### Performance Macros (`app.common.data.macros`)
|
### Performance Macros (`app.common.data.macros`)
|
||||||
|
|
||||||
Always prefer these macros over their `clojure.core` equivalents — they compile to faster JavaScript:
|
Always prefer these macros over their `clojure.core` equivalents — they compile to faster JavaScript:
|
||||||
|
|||||||
@ -102,6 +102,21 @@
|
|||||||
(mf/defc vertical-align*
|
(mf/defc vertical-align*
|
||||||
[{:keys [values on-change on-blur]}]
|
[{:keys [values on-change on-blur]}]
|
||||||
(let [vertical-align (or (:vertical-align values) "top")
|
(let [vertical-align (or (:vertical-align values) "top")
|
||||||
|
options
|
||||||
|
(mf/with-memo []
|
||||||
|
[{:value "top"
|
||||||
|
:id "vertical-text-align-top"
|
||||||
|
:label (tr "workspace.options.text-options.align-top")
|
||||||
|
:icon i/text-top}
|
||||||
|
{:value "center"
|
||||||
|
:id "vertical-text-align-center"
|
||||||
|
:label (tr "workspace.options.text-options.align-middle")
|
||||||
|
:icon i/text-middle}
|
||||||
|
{:value "bottom"
|
||||||
|
:id "vertical-text-align-bottom"
|
||||||
|
:label (tr "workspace.options.text-options.align-bottom")
|
||||||
|
:icon i/text-bottom}])
|
||||||
|
|
||||||
handle-change
|
handle-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps on-change on-blur)
|
(mf/deps on-change on-blur)
|
||||||
@ -113,18 +128,7 @@
|
|||||||
[:> radio-buttons* {:selected vertical-align
|
[:> radio-buttons* {:selected vertical-align
|
||||||
:on-change handle-change
|
:on-change handle-change
|
||||||
:name "vertical-align-text-options"
|
:name "vertical-align-text-options"
|
||||||
:options [{:value "top"
|
:options options}]]))
|
||||||
:id "vertical-text-align-top"
|
|
||||||
:label (tr "workspace.options.text-options.align-top")
|
|
||||||
:icon i/text-top}
|
|
||||||
{:value "center"
|
|
||||||
:id "vertical-text-align-center"
|
|
||||||
:label (tr "workspace.options.text-options.align-middle")
|
|
||||||
:icon i/text-middle}
|
|
||||||
{:value "bottom"
|
|
||||||
:id "vertical-text-align-bottom"
|
|
||||||
:label (tr "workspace.options.text-options.align-bottom")
|
|
||||||
:icon i/text-bottom}]}]]))
|
|
||||||
|
|
||||||
(mf/defc grow-options*
|
(mf/defc grow-options*
|
||||||
[{:keys [ids values on-blur]}]
|
[{:keys [ids values on-blur]}]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user