From 6b773d6b74daa89fe900dfce647f1d540ebc3448 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 14 Feb 2025 12:50:56 +0100 Subject: [PATCH] :bug: Dont allow hex values without # prefix --- .../app/main/ui/workspace/tokens/form.cljs | 13 +++++++-- .../main/ui/workspace/tokens/tinycolor.cljs | 28 +++++++++++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs index 42558070c1..61fa8fe99a 100644 --- a/frontend/src/app/main/ui/workspace/tokens/form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs @@ -9,6 +9,7 @@ (:require [app.common.colors :as c] [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.types.tokens-lib :as ctob] [app.main.data.modal :as modal] [app.main.data.tokens :as dt] @@ -321,9 +322,15 @@ on-update-value (mf/use-fn (mf/deps on-update-value-debounced) (fn [e] - (let [value (dom/get-target-val e)] - (reset! value-ref value) - (on-update-value-debounced value)))) + (let [value (dom/get-target-val e) + ;; Automatically add # for hex values + value' (if (and color? (tinycolor/hex-without-hash-prefix? value)) + (let [hex (dm/str "#" value)] + (dom/set-value! (mf/ref-val value-input-ref) hex) + hex) + value)] + (reset! value-ref value') + (on-update-value-debounced value')))) on-update-color (mf/use-fn (mf/deps on-update-value-debounced) (fn [hex-value alpha] diff --git a/frontend/src/app/main/ui/workspace/tokens/tinycolor.cljs b/frontend/src/app/main/ui/workspace/tokens/tinycolor.cljs index 0fb77eff43..10c809e397 100644 --- a/frontend/src/app/main/ui/workspace/tokens/tinycolor.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/tinycolor.cljs @@ -4,14 +4,36 @@ This library was chosen as it is already used by StyleDictionary, so there is no extra dependency cost and there was no clojure alternatives with all the necessary features." (:require - ["tinycolor2$default" :as tinycolor])) + ["tinycolor2$default" :as tinycolor] + [cuerdas.core :as str])) (defn tinycolor? [^js x] (and (instance? tinycolor x) (.isValid x))) -(defn valid-color [color-str] +(defn hex? [^js tc] + (str/starts-with? (.getFormat tc) "hex")) + +(defn valid-color + "Checks if `color-str` is a valid css color." + [color-str] (let [tc (tinycolor color-str)] - (when (.isValid tc) tc))) + (when (and (.isValid tc) + ;; Invalid CSS color strings will return `false` for `.getFormat` + (.getFormat tc) + ;; Values like `1111` will still return `hex8` as format which are non-valid css colors, + ;; so we reject hex values without a # prefix + (if (hex? tc) + (str/starts-with? (.getOriginalInput tc) "#") + true)) + tc))) + +(defn hex-without-hash-prefix? [color-str] + (when (not= "#" (first color-str)) + (let [tc (tinycolor color-str)] + (str/starts-with? (.getFormat tc) "hex")))) + +(defn ->string [^js tc] + (.toString tc)) (defn ->hex-string [^js tc] (assert (tinycolor? tc))