mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 14:00:37 +00:00
🐛 Keep a committed property name from being sent again
When the variant property panel went away (selecting another layer), input-with-meta* sent a blur from the last input it had rendered, to commit an edit still open. After an edit was already committed that input is gone and keeps the text it had: reordering the properties and then selecting a variant renamed the property now in that row after the old one, "Property 1" becoming "Property 2 (1)" (PENPOT-2588). The input is forgotten once its edit is committed, so the blur is sent only for an edit still open. ds-input-with-meta-test mounts the component in a jsdom document: a committed edit is not sent again when the value changes and the input goes away; an edit still open is committed. AI-assisted-by: claude-opus-5-5
This commit is contained in:
parent
03c6e3b006
commit
5fdf0c036f
@ -51,6 +51,8 @@
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(reset! editing* false)
|
||||
;; the edit is committed: the cleanup has nothing left to send
|
||||
(mf/set-ref-val! last-node* nil)
|
||||
(when on-blur
|
||||
(on-blur event))))
|
||||
|
||||
|
||||
@ -140,6 +140,7 @@
|
||||
[frontend-tests.ui.dashboard-import-linking-test]
|
||||
[frontend-tests.ui.drawarea-test]
|
||||
[frontend-tests.ui.ds-controls-numeric-input-test]
|
||||
[frontend-tests.ui.ds-input-with-meta-test]
|
||||
[frontend-tests.ui.error-boundary-test]
|
||||
[frontend-tests.ui.gradient-handlers-test]
|
||||
[frontend-tests.ui.history-test]
|
||||
@ -323,6 +324,7 @@
|
||||
'frontend-tests.ui.dashboard-import-linking-test
|
||||
'frontend-tests.ui.drawarea-test
|
||||
'frontend-tests.ui.ds-controls-numeric-input-test
|
||||
'frontend-tests.ui.ds-input-with-meta-test
|
||||
'frontend-tests.ui.error-boundary-test
|
||||
'frontend-tests.ui.gradient-handlers-test
|
||||
'frontend-tests.ui.history-test
|
||||
|
||||
73
frontend/test/frontend_tests/ui/ds_input_with_meta_test.cljs
Normal file
73
frontend/test/frontend_tests/ui/ds_input_with_meta_test.cljs
Normal file
@ -0,0 +1,73 @@
|
||||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS SUBSIDIARY SL
|
||||
|
||||
(ns frontend-tests.ui.ds-input-with-meta-test
|
||||
"The blur of `input-with-meta*`, mounted in a jsdom document since the
|
||||
runner has no DOM. React loads before the test sets up the document, so
|
||||
it cannot dispatch DOM events here: the container stays out of the
|
||||
document (autofocus does nothing) and a blur calls the input's handler."
|
||||
(:require
|
||||
["jsdom" :refer [JSDOM]]
|
||||
["react" :as react]
|
||||
["react-dom/client" :as rdc]
|
||||
[app.main.ui.ds.product.input-with-meta :refer [input-with-meta*]]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ^:private dom-globals ["window" "document" "IS_REACT_ACT_ENVIRONMENT"])
|
||||
|
||||
(defn- with-dom
|
||||
"Call `f` with a container of a jsdom document set as the global one."
|
||||
[f]
|
||||
(let [window (.-window (JSDOM. "<!DOCTYPE html><body></body>"))
|
||||
previous (into {} (map (fn [k] [k (unchecked-get js/globalThis k)])) dom-globals)]
|
||||
(doseq [[k v] {"window" window
|
||||
"document" (.-document window)
|
||||
"IS_REACT_ACT_ENVIRONMENT" true}]
|
||||
(unchecked-set js/globalThis k v))
|
||||
(try
|
||||
(f (.createElement (.-document window) "div"))
|
||||
(finally
|
||||
(doseq [[k v] previous]
|
||||
(unchecked-set js/globalThis k v))))))
|
||||
|
||||
(defn- blur!
|
||||
"Blur the input of `container` the way React would on a real blur."
|
||||
[container]
|
||||
(let [input (.querySelector container "input")
|
||||
props (->> (js/Object.keys input)
|
||||
(some #(when (str/starts-with? % "__reactProps$") (unchecked-get input %))))]
|
||||
(.onBlur props #js {:target input :currentTarget input :stopPropagation (fn [])})))
|
||||
|
||||
(defn- element
|
||||
[value on-blur]
|
||||
(mf/element input-with-meta* #js {:value value :isEditing true :onBlur on-blur}))
|
||||
|
||||
(t/deftest unmount-after-a-committed-edit-sends-no-blur
|
||||
;; The edit commits on blur; the value then changes (the rows the inputs
|
||||
;; belong to are reordered) and the input goes away. The committed edit
|
||||
;; must not be sent again with the text it had.
|
||||
(with-dom
|
||||
(fn [container]
|
||||
(let [blurs (atom [])
|
||||
on-blur (fn [event] (swap! blurs conj (.. event -target -value)))
|
||||
root (rdc/createRoot container)]
|
||||
(react/act #(.render root (element "Property 2" on-blur)))
|
||||
(react/act #(blur! container))
|
||||
(react/act #(.render root (element "Property 1" on-blur)))
|
||||
(react/act #(.unmount root))
|
||||
(t/is (= ["Property 2"] @blurs))))))
|
||||
|
||||
(t/deftest unmount-during-an-edit-commits-it
|
||||
(with-dom
|
||||
(fn [container]
|
||||
(let [blurs (atom [])
|
||||
on-blur (fn [event] (swap! blurs conj (.. event -target -value)))
|
||||
root (rdc/createRoot container)]
|
||||
(react/act #(.render root (element "Property 1" on-blur)))
|
||||
(react/act #(.unmount root))
|
||||
(t/is (= ["Property 1"] @blurs))))))
|
||||
Loading…
x
Reference in New Issue
Block a user