mirror of
https://github.com/penpot/penpot.git
synced 2025-06-25 16:17:05 +02:00
✨ Limit the length of property names and values to 60 chars (#6587)
This commit is contained in:
parent
0552ef55cf
commit
ad26efaa5d
8 changed files with 36 additions and 13 deletions
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
(def property-prefix "Property")
|
(def property-prefix "Property")
|
||||||
(def property-regex (re-pattern (str property-prefix "(\\d+)")))
|
(def property-regex (re-pattern (str property-prefix "(\\d+)")))
|
||||||
|
(def property-max-length 60)
|
||||||
(def value-prefix "Value ")
|
(def value-prefix "Value ")
|
||||||
|
|
||||||
|
|
||||||
|
@ -134,7 +135,9 @@
|
||||||
(->> (str/split s ",")
|
(->> (str/split s ",")
|
||||||
(mapv #(str/split % "=" 2))
|
(mapv #(str/split % "=" 2))
|
||||||
(every? #(and (= 2 (count %))
|
(every? #(and (= 2 (count %))
|
||||||
(not (str/blank? (first %)))))))
|
(not (str/blank? (first %)))
|
||||||
|
(< (count (first %)) property-max-length)
|
||||||
|
(< (count (second %)) property-max-length)))))
|
||||||
|
|
||||||
|
|
||||||
(defn find-properties-to-remove
|
(defn find-properties-to-remove
|
||||||
|
|
|
@ -25,11 +25,14 @@
|
||||||
string-valid-with-no-value "border=no, color="
|
string-valid-with-no-value "border=no, color="
|
||||||
string-valid-with-dashes "border=no, color=--"
|
string-valid-with-dashes "border=no, color=--"
|
||||||
string-valid-with-equal "border=yes color=yes"
|
string-valid-with-equal "border=yes color=yes"
|
||||||
string-invalid-1 ""
|
|
||||||
string-invalid-2 "=yes"
|
string-invalid-empty ""
|
||||||
string-invalid-3 "border"
|
string-invalid-no-property-1 "=yes"
|
||||||
string-invalid-4 "border=yes, =gray"
|
string-invalid-no-property-2 "border=yes, =gray"
|
||||||
string-invalid-5 "border=yes, color"]
|
string-invalid-no-equal-1 "border"
|
||||||
|
string-invalid-no-equal-2 "border=yes, color"
|
||||||
|
string-invalid-too-long-1 "this is a too long property name which should throw a validation error=yes"
|
||||||
|
string-invalid-too-long-2 "border=this is a too long property name which should throw a validation error"]
|
||||||
|
|
||||||
(t/testing "convert map to formula"
|
(t/testing "convert map to formula"
|
||||||
(t/is (= (ctv/properties-map->formula map-with-two-props) string-valid-with-two-props))
|
(t/is (= (ctv/properties-map->formula map-with-two-props) string-valid-with-two-props))
|
||||||
|
@ -50,11 +53,13 @@
|
||||||
(t/is (= (ctv/valid-properties-formula? string-valid-with-spaces) true))
|
(t/is (= (ctv/valid-properties-formula? string-valid-with-spaces) true))
|
||||||
(t/is (= (ctv/valid-properties-formula? string-valid-with-no-value) true))
|
(t/is (= (ctv/valid-properties-formula? string-valid-with-no-value) true))
|
||||||
(t/is (= (ctv/valid-properties-formula? string-valid-with-dashes) true))
|
(t/is (= (ctv/valid-properties-formula? string-valid-with-dashes) true))
|
||||||
(t/is (= (ctv/valid-properties-formula? string-invalid-1) false))
|
(t/is (= (ctv/valid-properties-formula? string-invalid-empty) false))
|
||||||
(t/is (= (ctv/valid-properties-formula? string-invalid-2) false))
|
(t/is (= (ctv/valid-properties-formula? string-invalid-no-property-1) false))
|
||||||
(t/is (= (ctv/valid-properties-formula? string-invalid-3) false))
|
(t/is (= (ctv/valid-properties-formula? string-invalid-no-equal-1) false))
|
||||||
(t/is (= (ctv/valid-properties-formula? string-invalid-4) false))
|
(t/is (= (ctv/valid-properties-formula? string-invalid-no-property-2) false))
|
||||||
(t/is (= (ctv/valid-properties-formula? string-invalid-5) false)))))
|
(t/is (= (ctv/valid-properties-formula? string-invalid-no-equal-2) false))
|
||||||
|
(t/is (= (ctv/valid-properties-formula? string-invalid-too-long-1) false))
|
||||||
|
(t/is (= (ctv/valid-properties-formula? string-invalid-too-long-2) false)))))
|
||||||
|
|
||||||
|
|
||||||
(t/deftest find-properties
|
(t/deftest find-properties
|
||||||
|
|
|
@ -259,7 +259,7 @@
|
||||||
:data-testid "combobox-input"
|
:data-testid "combobox-input"
|
||||||
:max-length (d/nilv max-length max-input-length)
|
:max-length (d/nilv max-length max-input-length)
|
||||||
:disabled disabled
|
:disabled disabled
|
||||||
:value selected-value
|
:value (d/nilv selected-value "")
|
||||||
:placeholder placeholder
|
:placeholder placeholder
|
||||||
:on-change on-input-change
|
:on-change on-input-change
|
||||||
:on-click on-input-click
|
:on-click on-input-click
|
||||||
|
|
|
@ -18,10 +18,12 @@ export default {
|
||||||
component: Combobox,
|
component: Combobox,
|
||||||
argTypes: {
|
argTypes: {
|
||||||
disabled: { control: "boolean" },
|
disabled: { control: "boolean" },
|
||||||
|
maxLength: { control: "number" },
|
||||||
hasError: { control: "boolean" },
|
hasError: { control: "boolean" },
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
maxLength: 10,
|
||||||
hasError: false,
|
hasError: false,
|
||||||
placeholder: "Select a month",
|
placeholder: "Select a month",
|
||||||
options: [
|
options: [
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
(:require-macros
|
(:require-macros
|
||||||
[app.main.style :as stl])
|
[app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.main.constants :refer [max-input-length]]
|
||||||
[app.main.ui.ds.controls.input :refer [input*]]
|
[app.main.ui.ds.controls.input :refer [input*]]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
|
@ -17,11 +19,12 @@
|
||||||
[:map
|
[:map
|
||||||
[:value :string]
|
[:value :string]
|
||||||
[:meta {:optional true} :string]
|
[:meta {:optional true} :string]
|
||||||
|
[:max-length {:optional true} :int]
|
||||||
[:on-blur {:optional true} fn?]])
|
[:on-blur {:optional true} fn?]])
|
||||||
|
|
||||||
(mf/defc input-with-meta*
|
(mf/defc input-with-meta*
|
||||||
{::mf/schema schema:input-with-meta}
|
{::mf/schema schema:input-with-meta}
|
||||||
[{:keys [value meta on-blur] :rest props}]
|
[{:keys [value meta max-length on-blur] :rest props}]
|
||||||
(let [editing* (mf/use-state false)
|
(let [editing* (mf/use-state false)
|
||||||
editing? (deref editing*)
|
editing? (deref editing*)
|
||||||
|
|
||||||
|
@ -63,6 +66,7 @@
|
||||||
|
|
||||||
props (mf/spread-props props {:ref input-ref
|
props (mf/spread-props props {:ref input-ref
|
||||||
:default-value value
|
:default-value value
|
||||||
|
:max-length (d/nilv max-length max-input-length)
|
||||||
:auto-focus true
|
:auto-focus true
|
||||||
:on-focus on-focus
|
:on-focus on-focus
|
||||||
:on-blur on-stop-edit
|
:on-blur on-stop-edit
|
||||||
|
|
|
@ -13,11 +13,13 @@ The `input-with-meta*` acts as an input with an optional addition of a meta text
|
||||||
|
|
||||||
* You need to pass the mandatory string property `value`.
|
* You need to pass the mandatory string property `value`.
|
||||||
* You can pass the optional string property `meta`.
|
* You can pass the optional string property `meta`.
|
||||||
|
* You can pass the optional int property `max-length`.
|
||||||
* You can pass a function property `on-blur` that will be called with the blur event when the component loses focus (including when the user presses enter or esc).
|
* You can pass a function property `on-blur` that will be called with the blur event when the component loses focus (including when the user presses enter or esc).
|
||||||
|
|
||||||
```clj
|
```clj
|
||||||
[:> input-with-meta* {:value value
|
[:> input-with-meta* {:value value
|
||||||
:meta meta
|
:meta meta
|
||||||
|
:max-length max-length
|
||||||
:on-blur on-blur}]
|
:on-blur on-blur}]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,14 @@ export default {
|
||||||
meta: {
|
meta: {
|
||||||
control: { type: "text" },
|
control: { type: "text" },
|
||||||
},
|
},
|
||||||
|
maxLength: {
|
||||||
|
control: { type: "number" },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
value: "Property 1",
|
value: "Property 1",
|
||||||
meta: "Value1, Value2",
|
meta: "Value1, Value2",
|
||||||
|
maxLength: 10,
|
||||||
},
|
},
|
||||||
render: ({ ...args }) => <InputWithMeta {...args} />,
|
render: ({ ...args }) => <InputWithMeta {...args} />,
|
||||||
};
|
};
|
||||||
|
|
|
@ -317,6 +317,7 @@
|
||||||
[:*
|
[:*
|
||||||
[:div {:class (stl/css :variant-property-name-wrapper)}
|
[:div {:class (stl/css :variant-property-name-wrapper)}
|
||||||
[:> input-with-meta* {:value (:name prop)
|
[:> input-with-meta* {:value (:name prop)
|
||||||
|
:max-length ctv/property-max-length
|
||||||
:data-position pos
|
:data-position pos
|
||||||
:on-blur update-property-name}]]
|
:on-blur update-property-name}]]
|
||||||
|
|
||||||
|
@ -326,6 +327,7 @@
|
||||||
:default-selected (if mixed-value? "" (:value prop))
|
:default-selected (if mixed-value? "" (:value prop))
|
||||||
:options (clj->js (get-options (:name prop)))
|
:options (clj->js (get-options (:name prop)))
|
||||||
:empty-to-end true
|
:empty-to-end true
|
||||||
|
:max-length ctv/property-max-length
|
||||||
:on-change (partial update-property-value pos)}])]])]
|
:on-change (partial update-property-value pos)}])]])]
|
||||||
|
|
||||||
(when variant-error-msg
|
(when variant-error-msg
|
||||||
|
@ -965,6 +967,7 @@
|
||||||
:class (stl/css :variant-property-row)}
|
:class (stl/css :variant-property-row)}
|
||||||
[:> input-with-meta* {:value (:name property)
|
[:> input-with-meta* {:value (:name property)
|
||||||
:meta meta
|
:meta meta
|
||||||
|
:max-length ctv/property-max-length
|
||||||
:data-position pos
|
:data-position pos
|
||||||
:on-blur update-property-name}]
|
:on-blur update-property-name}]
|
||||||
[:> icon-button* {:variant "ghost"
|
[:> icon-button* {:variant "ghost"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue