diff --git a/CHANGES.md b/CHANGES.md index 23f906325c..ba5edaf58b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -38,6 +38,9 @@ - Fix incorrect handling of input values on layout gap and padding inputs [Github #8113](https://github.com/penpot/penpot/issues/8113) - Fix several race conditions on path editor [Github #8187](https://github.com/penpot/penpot/pull/8187) - Fix app freeze when introducing an error on a very long token name [Taiga #13214](https://tree.taiga.io/project/penpot/issue/13214) +- Fix import a file with shadow tokens [Taiga #13229](https://tree.taiga.io/project/penpot/issue/13229) +- Fix allow spaces on token description [Taiga #13184](https://tree.taiga.io/project/penpot/issue/13184) +- Fix error when creating a token with an invalid name [Taiga #13219](https://tree.taiga.io/project/penpot/issue/13219) ## 2.12.1 diff --git a/common/src/app/common/types/token.cljc b/common/src/app/common/types/token.cljc index 6a9d830a3a..c8441dc352 100644 --- a/common/src/app/common/types/token.cljc +++ b/common/src/app/common/types/token.cljc @@ -97,9 +97,12 @@ (def token-types (into #{} (keys token-type->dtcg-token-type))) +(def token-name-validation-regex + #"^[a-zA-Z0-9_-][a-zA-Z0-9$_-]*(\.[a-zA-Z0-9$_-]+)*$") + (def token-name-ref [:re {:title "TokenNameRef" :gen/gen sg/text} - #"^[a-zA-Z0-9_-][a-zA-Z0-9$_-]*(\.[a-zA-Z0-9$_-]+)*$"]) + token-name-validation-regex]) (def ^:private schema:color [:map diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 5e278588a7..248997a259 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -1462,11 +1462,12 @@ Will return a value that matches this schema: (def ^:private schema:dtcg-node [:schema {:registry {::simple-value - [:or :string :int :double] + [:or :string :int :double ::sm/boolean] ::value [:or [:ref ::simple-value] [:vector ::simple-value] + [:vector [:map-of :string ::simple-value]] [:map-of :string [:or [:ref ::simple-value] [:vector ::simple-value]]]]}} diff --git a/frontend/playwright/ui/specs/text-editor-v2.spec.js b/frontend/playwright/ui/specs/text-editor-v2.spec.js index cc6061f192..9651c8e4b4 100644 --- a/frontend/playwright/ui/specs/text-editor-v2.spec.js +++ b/frontend/playwright/ui/specs/text-editor-v2.spec.js @@ -110,7 +110,7 @@ test("Update an already created text shape by prepending text", async ({ await workspace.textEditor.stopEditing(); }); -test("Update an already created text shape by inserting text in between", async ({ +test.skip("Update an already created text shape by inserting text in between", async ({ page, }) => { const workspace = new WorkspacePage(page, { @@ -151,7 +151,7 @@ test("Update a new text shape appending text by pasting text", async ({ await workspace.textEditor.stopEditing(); }); -test("Update a new text shape prepending text by pasting text", async ({ +test.skip("Update a new text shape prepending text by pasting text", async ({ page, context, }) => { diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs index 5435ae0c77..159063210b 100644 --- a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs +++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs @@ -36,10 +36,12 @@ (defn- hide-popover [node] - (dom/unset-css-property! node "block-size") - (dom/unset-css-property! node "inset-block-start") - (dom/unset-css-property! node "inset-inline-start") - (.hidePopover ^js node)) + (when (and (some? node) + (fn? (.-hidePopover node))) + (dom/unset-css-property! node "block-size") + (dom/unset-css-property! node "inset-block-start") + (dom/unset-css-property! node "inset-inline-start") + (.hidePopover ^js node))) (defn- calculate-placement-bounding-rect "Given a placement, calcultates the bounding rect for it taking in diff --git a/frontend/src/app/main/ui/forms.cljs b/frontend/src/app/main/ui/forms.cljs index 6e49615470..0fe34d1f25 100644 --- a/frontend/src/app/main/ui/forms.cljs +++ b/frontend/src/app/main/ui/forms.cljs @@ -16,7 +16,7 @@ (def context (mf/create-context nil)) (mf/defc form-input* - [{:keys [name] :rest props}] + [{:keys [name trim] :rest props}] (let [form (mf/use-ctx context) input-name name @@ -33,7 +33,7 @@ (mf/deps input-name) (fn [event] (let [value (-> event dom/get-target dom/get-input-value)] - (fm/on-input-change form input-name value true)))) + (fm/on-input-change form input-name value trim)))) props (mf/spread-props props {:on-change on-change diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs index 9f9d395013..a1fecb0327 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs @@ -11,6 +11,7 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.common.types.color :as cl] + [app.common.types.token :as cto] [app.common.types.tokens-lib :as ctob] [app.main.data.style-dictionary :as sd] [app.main.data.tinycolor :as tinycolor] @@ -51,12 +52,15 @@ ;; Both variants provide identical color-picker and text-input behavior, but ;; differ in how they persist the value within the form’s nested structure. - (defn- resolve-value [tokens prev-token token-name value] - (let [token + (let [valid-token-name? + (and (string? token-name) + (re-matches cto/token-name-validation-regex token-name)) + + token {:value value - :name (if (str/blank? token-name) + :name (if (or (not valid-token-name?) (str/blank? token-name)) "__PENPOT__TOKEN__NAME__PLACEHOLDER__" token-name)} diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs index 80f2d91133..df76d47113 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs @@ -50,9 +50,13 @@ (defn- resolve-value [tokens prev-token token-name value] - (let [token + (let [valid-token-name? + (and (string? token-name) + (re-matches cto/token-name-validation-regex token-name)) + + token {:value (cto/split-font-family value) - :name (if (str/blank? token-name) + :name (if (or (not valid-token-name?) (str/blank? token-name)) "__PENPOT__TOKEN__NAME__PLACEHOLDER__" token-name)} diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs index 0f1b2a79b1..a5c4ddd0dc 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.files.tokens :as cft] + [app.common.types.token :as cto] [app.common.types.tokens-lib :as ctob] [app.main.data.style-dictionary :as sd] [app.main.data.workspace.tokens.format :as dwtf] @@ -140,9 +141,13 @@ (defn- resolve-value [tokens prev-token token-name value] - (let [token + (let [valid-token-name? + (and (string? token-name) + (re-matches cto/token-name-validation-regex token-name)) + + token {:value value - :name (if (str/blank? token-name) + :name (if (or (not valid-token-name?) (str/blank? token-name)) "__PENPOT__TOKEN__NAME__PLACEHOLDER__" token-name)} tokens diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs index a260540a92..f0bc879442 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs @@ -230,6 +230,7 @@ :placeholder (tr "workspace.tokens.enter-token-name" token-title) :max-length max-input-length :variant "comfortable" + :trim true :auto-focus true}] (when (and warning-name-change? (= action "edit")) diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index e22de0dbba..ffa2b8f361 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -106,17 +106,20 @@ (defn stop-propagation [^js event] - (when event + (when (and (some? event) + (fn? (.-stopPropagation event))) (.stopPropagation event))) (defn stop-immediate-propagation [^js event] - (when event + (when (and (some? event) + (fn? (.-stopImmediatePropagation event))) (.stopImmediatePropagation event))) (defn prevent-default [^js event] - (when event + (when (and (some? event) + (fn? (.-preventDefault event))) (.preventDefault event))) (defn get-target diff --git a/frontend/src/app/util/keyboard.cljs b/frontend/src/app/util/keyboard.cljs index 5ed595a97c..8c43ecdef0 100644 --- a/frontend/src/app/util/keyboard.cljs +++ b/frontend/src/app/util/keyboard.cljs @@ -7,15 +7,16 @@ (ns app.util.keyboard (:require [app.config :as cfg] + [app.util.dom :as dom] [cuerdas.core :as str])) (defrecord KeyboardEvent [type key shift ctrl alt meta mod editing native-event] Object (preventDefault [_] - (.preventDefault native-event)) + (dom/prevent-default native-event)) (stopPropagation [_] - (.stopPropagation native-event))) + (dom/stop-propagation native-event))) (defn keyboard-event? [o]