mirror of
https://github.com/penpot/penpot.git
synced 2026-05-24 09:23:40 +00:00
🐛 Fix Numeric inputs rejects values with leading whitespaces
This commit is contained in:
parent
d96442483e
commit
857aa4175c
80
frontend/playwright/ui/specs/numeric-input.spec.js
Normal file
80
frontend/playwright/ui/specs/numeric-input.spec.js
Normal file
@ -0,0 +1,80 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await WasmWorkspacePage.init(page);
|
||||
await WasmWorkspacePage.mockConfigFlags(page, ["enable-feature-token-input"]);
|
||||
});
|
||||
|
||||
test("BUG 14226: Numeric inputs in the design panel reject values with leading whitespace", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspacePage = new WasmWorkspacePage(page);
|
||||
await workspacePage.setupEmptyFile(page);
|
||||
await workspacePage.mockRPC(
|
||||
/get\-file\?/,
|
||||
"workspace/get-file-copy-paste.json",
|
||||
);
|
||||
await workspacePage.mockRPC(
|
||||
"get-file-fragment?file-id=*&fragment-id=*",
|
||||
"workspace/get-file-copy-paste-fragment.json",
|
||||
);
|
||||
|
||||
await workspacePage.goToWorkspace({
|
||||
fileId: "870f9f10-87b5-8137-8005-934804124660",
|
||||
pageId: "870f9f10-87b5-8137-8005-934804124661",
|
||||
});
|
||||
|
||||
// Select first shape
|
||||
await page.getByTestId("layer-item").getByRole("button").first().click();
|
||||
await workspacePage.layers.getByTestId("layer-row").nth(0).click();
|
||||
|
||||
// Check if measures section is visible
|
||||
const measuresSection = workspacePage.rightSidebar.getByRole("region", {
|
||||
name: "shape-measures-section",
|
||||
});
|
||||
await expect(measuresSection).toBeVisible();
|
||||
|
||||
// Width
|
||||
const widthInput = measuresSection.getByRole("textbox", {
|
||||
name: "Width",
|
||||
exact: true,
|
||||
});
|
||||
await expect(widthInput).toHaveValue("360");
|
||||
|
||||
await widthInput.fill("100");
|
||||
await widthInput.press("Enter");
|
||||
await expect(widthInput).toHaveValue("100");
|
||||
|
||||
await widthInput.fill(" 100");
|
||||
await widthInput.press("Enter");
|
||||
await expect(widthInput).toHaveValue("100");
|
||||
|
||||
await widthInput.fill(" 100 ");
|
||||
await widthInput.press("Enter");
|
||||
await expect(widthInput).toHaveValue("100");
|
||||
|
||||
await widthInput.fill("100 ");
|
||||
await widthInput.press("Enter");
|
||||
await expect(widthInput).toHaveValue("100");
|
||||
|
||||
await widthInput.fill("98+2");
|
||||
await widthInput.press("Enter");
|
||||
await expect(widthInput).toHaveValue("100");
|
||||
|
||||
await widthInput.fill("98 + 2");
|
||||
await widthInput.press("Enter");
|
||||
await expect(widthInput).toHaveValue("100");
|
||||
|
||||
await widthInput.fill(" 98 + 2 ");
|
||||
await widthInput.press("Enter");
|
||||
await expect(widthInput).toHaveValue("100");
|
||||
|
||||
await widthInput.fill(" 98+2 ");
|
||||
await widthInput.press("Enter");
|
||||
await expect(widthInput).toHaveValue("100");
|
||||
|
||||
await widthInput.fill(" asdasdasdasd ");
|
||||
await widthInput.press("Enter");
|
||||
await expect(widthInput).toHaveValue("100");
|
||||
});
|
||||
@ -291,33 +291,35 @@
|
||||
(mf/use-fn
|
||||
(mf/deps on-change update-input value nillable min max)
|
||||
(fn [raw-value]
|
||||
(if-let [parsed (parse-value raw-value (mf/ref-val last-value*) min max nillable)]
|
||||
(when-not (= parsed (mf/ref-val last-value*))
|
||||
(mf/set-ref-val! last-value* parsed)
|
||||
(reset! token-applied-name* nil)
|
||||
(when (fn? on-change)
|
||||
(on-change parsed))
|
||||
|
||||
(mf/set-ref-val! raw-value* (fmt/format-number parsed))
|
||||
(update-input (fmt/format-number parsed)))
|
||||
|
||||
(if (and nillable (empty? raw-value))
|
||||
(let [raw-value (str/trim (str raw-value))]
|
||||
(if-let [parsed (parse-value raw-value (mf/ref-val last-value*) min max nillable)]
|
||||
(do
|
||||
(mf/set-ref-val! last-value* nil)
|
||||
(mf/set-ref-val! raw-value* "")
|
||||
(reset! token-applied-name* nil)
|
||||
(update-input "")
|
||||
(when (fn? on-change)
|
||||
(on-change nil)))
|
||||
(when-not (= parsed (mf/ref-val last-value*))
|
||||
(mf/set-ref-val! last-value* parsed)
|
||||
(reset! token-applied-name* nil)
|
||||
(when (fn? on-change)
|
||||
(on-change parsed)))
|
||||
|
||||
(let [fallback-value (or (mf/ref-val last-value*) default)]
|
||||
(mf/set-ref-val! raw-value* fallback-value)
|
||||
(mf/set-ref-val! last-value* fallback-value)
|
||||
(reset! token-applied-name* nil)
|
||||
(update-input (fmt/format-number fallback-value))
|
||||
(mf/set-ref-val! raw-value* (fmt/format-number parsed))
|
||||
(update-input (fmt/format-number parsed)))
|
||||
|
||||
(when (and (fn? on-change) (not= fallback-value (str value)))
|
||||
(on-change fallback-value)))))))
|
||||
(if (and nillable (empty? raw-value))
|
||||
(do
|
||||
(mf/set-ref-val! last-value* nil)
|
||||
(mf/set-ref-val! raw-value* "")
|
||||
(reset! token-applied-name* nil)
|
||||
(update-input "")
|
||||
(when (fn? on-change)
|
||||
(on-change nil)))
|
||||
|
||||
(let [fallback-value (or (mf/ref-val last-value*) default)]
|
||||
(mf/set-ref-val! raw-value* fallback-value)
|
||||
(mf/set-ref-val! last-value* fallback-value)
|
||||
(reset! token-applied-name* nil)
|
||||
(update-input (fmt/format-number fallback-value))
|
||||
|
||||
(when (and (fn? on-change) (not= fallback-value (str value)))
|
||||
(on-change fallback-value))))))))
|
||||
|
||||
apply-token
|
||||
(mf/use-fn
|
||||
@ -466,7 +468,7 @@
|
||||
(dom/prevent-default event)
|
||||
(handle-focus-change options focused-id* new-index (mf/ref-val nodes-ref)))
|
||||
|
||||
(let [parsed (parse-value (mf/ref-val raw-value*) (mf/ref-val last-value*) min max nillable)
|
||||
(let [parsed (parse-value (str/trim (mf/ref-val raw-value*)) (mf/ref-val last-value*) min max nillable)
|
||||
current-value (or parsed default)
|
||||
new-val (increment current-value step min max)]
|
||||
(dom/prevent-default event)
|
||||
@ -479,7 +481,7 @@
|
||||
(dom/prevent-default event)
|
||||
(handle-focus-change options focused-id* new-index (mf/ref-val nodes-ref)))
|
||||
|
||||
(let [parsed (parse-value (mf/ref-val raw-value*) (mf/ref-val last-value*) min max nillable)
|
||||
(let [parsed (parse-value (str/trim (mf/ref-val raw-value*)) (mf/ref-val last-value*) min max nillable)
|
||||
current-value (or parsed default)
|
||||
new-val (decrement current-value step min max)]
|
||||
(dom/prevent-default event)
|
||||
@ -508,7 +510,7 @@
|
||||
(let [inc? (->> (dom/get-delta-position event)
|
||||
:y
|
||||
(neg?))
|
||||
parsed (parse-value (mf/ref-val raw-value*) (mf/ref-val last-value*) min max nillable)
|
||||
parsed (parse-value (str/trim (mf/ref-val raw-value*)) (mf/ref-val last-value*) min max nillable)
|
||||
current-value (or parsed default)
|
||||
new-val (if inc?
|
||||
(increment current-value step min max)
|
||||
@ -527,7 +529,7 @@
|
||||
has-token (some? (deref token-applied-name*))]
|
||||
(when-not (or is-focused has-token)
|
||||
(let [client-x (.-clientX event)
|
||||
parsed (parse-value (mf/ref-val raw-value*) (mf/ref-val last-value*) min max nillable)
|
||||
parsed (parse-value (str/trim (mf/ref-val raw-value*)) (mf/ref-val last-value*) min max nillable)
|
||||
start-val (or parsed default 0)]
|
||||
(mf/set-ref-val! drag-state* :maybe-dragging)
|
||||
(mf/set-ref-val! drag-start-x* client-x)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user