🐛 Accept negative letterSpacing in plugin API text setters

The plugin text API rejected negative letter-spacing even though the
product UI allows -200..200 (typography.cljs). Two defects in
frontend/src/app/plugins/text.cljs:

- `letter-spacing-re` (`#"^\d*\.?\d*$"`) had no provision for a leading
  minus, so any negative value failed validation.
- The text-range `:letterSpacing` setter inverted its guard: it used
  `(or (empty? value) (re-matches ...))` to mean "invalid", which
  rejected matching values and let non-numeric input through. The
  text-shape setter and the sibling `lineHeight` range setter both
  correctly use `(not (re-matches ...))`.

Fix the regex to allow an optional leading minus and add the missing
`not` so the range setter matches the shape setter. Adds regression
coverage for the regex accept/reject contract.

Fixes #9780

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>
This commit is contained in:
Filip Sajdak 2026-06-17 15:27:46 +02:00 committed by Alonso Torres
parent ea20291d2a
commit 66c8ebf198
3 changed files with 40 additions and 1 deletions

View File

@ -33,7 +33,7 @@
(def ^:private font-size-re #"^\d*\.?\d*$")
(def ^:private line-height-re #"^\d*\.?\d*$")
(def ^:private letter-spacing-re #"^\d*\.?\d*$")
(def ^:private letter-spacing-re #"^-?\d*\.?\d*$")
(def ^:private text-transform-re #"uppercase|capitalize|lowercase|none")
(def ^:private text-decoration-re #"underline|line-through|none")
(def ^:private text-direction-re #"ltr|rtl")

View File

@ -0,0 +1,37 @@
;; 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 INC
(ns frontend-tests.plugins.text-test
(:require
[app.plugins.text :as plugins.text]
[cljs.test :as t :include-macros true]))
;; Regression coverage for issue #9780.
;;
;; `letterSpacing` accepts negative tracking in the product UI (-200..200,
;; see typography.cljs), but the plugin validator regex rejected any leading
;; minus, so negative values were refused. `letter-spacing-re` is the shared
;; predicate behind both the shape- and range-level setters; pin its
;; accept/reject contract here.
(def ^:private letter-spacing-re @#'plugins.text/letter-spacing-re)
(defn- valid? [s] (boolean (re-matches letter-spacing-re s)))
(t/deftest letter-spacing-re-accepts-negative-values
(t/is (valid? "-0.56"))
(t/is (valid? "-12"))
(t/is (valid? "-200")))
(t/deftest letter-spacing-re-accepts-non-negative-values
(t/is (valid? "0"))
(t/is (valid? "12"))
(t/is (valid? "1.5")))
(t/deftest letter-spacing-re-rejects-non-numeric
(t/is (not (valid? "abc")))
(t/is (not (valid? "1-2")))
(t/is (not (valid? "--1"))))

View File

@ -33,6 +33,7 @@
[frontend-tests.plugins.page-active-validation-test]
[frontend-tests.plugins.page-test]
[frontend-tests.plugins.parser-test]
[frontend-tests.plugins.text-test]
[frontend-tests.plugins.tokens-test]
[frontend-tests.plugins.utils-test]
[frontend-tests.render-wasm.process-objects-test]
@ -89,6 +90,7 @@
frontend-tests.plugins.format-test
frontend-tests.plugins.page-test
frontend-tests.plugins.parser-test
frontend-tests.plugins.text-test
frontend-tests.plugins.tokens-test
frontend-tests.plugins.utils-test
frontend-tests.svg-fills-test