mirror of
https://github.com/penpot/penpot.git
synced 2025-12-12 06:24:17 +01:00
🚧 Wip
This commit is contained in:
@@ -1318,7 +1318,7 @@ test.describe("Tokens: Apply token", () => {
|
||||
const firstColorValue = await colorInput.inputValue();
|
||||
|
||||
// User adds a second shadow
|
||||
const addButton = firstShadowFields.getByTestId("shadow-add-button-0");
|
||||
const addButton = firstShadowFields.getByTestId("shadow-add-button");
|
||||
await addButton.click();
|
||||
|
||||
const secondShadowFields = tokensUpdateCreateModal.getByTestId(
|
||||
@@ -1327,7 +1327,7 @@ test.describe("Tokens: Apply token", () => {
|
||||
await expect(secondShadowFields).toBeVisible();
|
||||
|
||||
// User adds a third shadow
|
||||
const addButton2 = secondShadowFields.getByTestId("shadow-add-button-1");
|
||||
const addButton2 = secondShadowFields.getByTestId("shadow-add-button");
|
||||
await addButton2.click();
|
||||
|
||||
const thirdShadowFields = tokensUpdateCreateModal.getByTestId(
|
||||
@@ -1353,7 +1353,7 @@ test.describe("Tokens: Apply token", () => {
|
||||
await removeButton2.click();
|
||||
|
||||
// Verify second shadow is removed
|
||||
await expect(secondShadowFields.getByTestId("shadow-add-button-3")).not.toBeVisible();
|
||||
await expect(secondShadowFields.getByTestId("shadow-add-button")).not.toBeVisible();
|
||||
|
||||
// Verify that the first shadow kept its values
|
||||
const firstOffsetXValue = await firstShadowFields.getByLabel("X").inputValue();
|
||||
|
||||
@@ -658,13 +658,13 @@
|
||||
(mf/defc composite-form*
|
||||
"Wrapper around form* that manages composite/reference tab state.
|
||||
Takes the same props as form* plus a function to determine if a token value is a reference."
|
||||
[{:keys [token is-reference-fn composite-tab reference-icon title update-composite-backup-value] :rest props}]
|
||||
[{:keys [token is-reference-fn composite-tab reference-icon title update-composite-backup-value type on-add-shadow] :rest props}]
|
||||
(let [active-tab* (mf/use-state (if (is-reference-fn (:value token)) :reference :composite))
|
||||
active-tab (deref active-tab*)
|
||||
|
||||
custom-input-token-value-props
|
||||
(mf/use-memo
|
||||
(mf/deps active-tab composite-tab reference-icon title update-composite-backup-value is-reference-fn)
|
||||
(mf/deps active-tab composite-tab reference-icon title update-composite-backup-value is-reference-fn type)
|
||||
(fn []
|
||||
{:active-tab active-tab
|
||||
:set-active-tab #(reset! active-tab* %)
|
||||
@@ -672,6 +672,8 @@
|
||||
:reference-icon reference-icon
|
||||
:reference-label (tr "workspace.tokens.reference-composite")
|
||||
:title title
|
||||
:type type
|
||||
:on-add-shadow on-add-shadow
|
||||
:update-composite-backup-value update-composite-backup-value
|
||||
:is-reference-fn is-reference-fn}))
|
||||
|
||||
@@ -728,7 +730,7 @@
|
||||
(mf/defc shadow-form*
|
||||
[{:keys [token] :rest props}]
|
||||
(let [on-get-token-value
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [e prev-composite-value]
|
||||
(let [prev-composite-value (or prev-composite-value [])
|
||||
[idx token-type :as token-type-at-index] (obj/get e "tokenTypeAtIndex")
|
||||
@@ -742,7 +744,7 @@
|
||||
:else (assoc-in prev-composite-value token-type-at-index input-value)))))
|
||||
|
||||
update-composite-backup-value
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(fn [prev-composite-value e]
|
||||
(let [[idx token-type :as token-type-at-index] (obj/get e "tokenTypeAtIndex")
|
||||
token-value (case token-type
|
||||
@@ -754,7 +756,19 @@
|
||||
(if valid?
|
||||
(assoc-in (or prev-composite-value []) token-type-at-index token-value)
|
||||
;; Remove empty values so they don't retrigger validation when switching tabs
|
||||
(update prev-composite-value idx dissoc token-type)))))]
|
||||
(update prev-composite-value idx dissoc token-type)))))
|
||||
|
||||
on-add-shadow
|
||||
#(prn "Add shadow clicked")
|
||||
;; (mf/use-fn
|
||||
;; (mf/deps shadows update-composite-value)
|
||||
;; (fn []
|
||||
;; (update-composite-backup-value
|
||||
;; (fn [state]
|
||||
;; (let [new-state (update state :composite (fnil conj []) {})]
|
||||
;; (reset! shadows* (:composite new-state))
|
||||
;; new-state)))))
|
||||
]
|
||||
[:> composite-form*
|
||||
(mf/spread-props props {:token token
|
||||
:composite-tab shadow-value-inputs*
|
||||
@@ -762,6 +776,8 @@
|
||||
:is-reference-fn cto/typography-composite-token-reference?
|
||||
:title (tr "workspace.tokens.shadow-title")
|
||||
:validate-token validate-shadow-token
|
||||
:type :shadow
|
||||
:on-add-shadow on-add-shadow
|
||||
:on-get-token-value on-get-token-value
|
||||
:update-composite-backup-value update-composite-backup-value})]))
|
||||
|
||||
|
||||
@@ -11,11 +11,9 @@
|
||||
|
||||
[app.common.types.token :as cto]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
|
||||
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
|
||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||
[app.main.ui.ds.controls.select :refer [select*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :as i]
|
||||
|
||||
[app.main.ui.workspace.tokens.management.create.input-tokens-value :refer [input-token*]]
|
||||
[app.main.ui.workspace.tokens.management.create.shared.color-picker :refer [color-picker*]]
|
||||
[app.util.i18n :refer [tr]]
|
||||
@@ -24,7 +22,7 @@
|
||||
|
||||
(mf/defc inset-type-select*
|
||||
{::mf/private true}
|
||||
[{:keys [default-value shadow-idx label on-change]}]
|
||||
[{:keys [default-value shadow-idx on-change]}]
|
||||
(let [selected* (mf/use-state (or (str default-value) "false"))
|
||||
selected (deref selected*)
|
||||
|
||||
@@ -32,25 +30,29 @@
|
||||
(mf/use-fn
|
||||
(mf/deps on-change selected shadow-idx)
|
||||
(fn [value e]
|
||||
(obj/set! e "tokenValue" (if (= "true" value) true false))
|
||||
(on-change e)
|
||||
(reset! selected* (str value))))]
|
||||
#_(obj/set! e "tokenValue" (if (= "true" value) true false))
|
||||
(prn value)
|
||||
;; (on-change e)
|
||||
#_(reset! selected* value)))
|
||||
options
|
||||
(mf/with-memo []
|
||||
[{:id "drop-shadow" :label "drop-shadow" :icon i/drop-shadow}
|
||||
{:id "inner-shadow" :label "inner-shadow" :icon i/inner-shadow}])]
|
||||
|
||||
[:div {:class (stl/css :input-row)}
|
||||
[:div {:class (stl/css :inset-label)} label]
|
||||
[:& radio-buttons {:selected selected
|
||||
:on-change on-change
|
||||
:name (str "inset-select-" shadow-idx)}
|
||||
[:& radio-button {:value "false"
|
||||
:title "false"
|
||||
:icon "❌"
|
||||
:id (str "inset-default-" shadow-idx)}]
|
||||
[:& radio-button {:value "true"
|
||||
:title "true"
|
||||
:icon "✅"
|
||||
:id (str "inset-false-" shadow-idx)}]]]))
|
||||
[:> select* {:default-selected selected
|
||||
:variant "ghost"
|
||||
:options options
|
||||
:on-change on-change}]]))
|
||||
|
||||
(def ^:private shadow-inputs
|
||||
#(d/ordered-map
|
||||
:inset
|
||||
{:label (tr "workspace.tokens.shadow-inset")
|
||||
:placeholder (tr "workspace.tokens.shadow-inset")}
|
||||
:color
|
||||
{:label (tr "workspace.tokens.shadow-color")
|
||||
:placeholder (tr "workspace.tokens.shadow-color")}
|
||||
:offsetX
|
||||
{:label (tr "workspace.tokens.shadow-x")
|
||||
:placeholder (tr "workspace.tokens.shadow-x")}
|
||||
@@ -62,13 +64,11 @@
|
||||
:placeholder (tr "workspace.tokens.shadow-blur")}
|
||||
:spread
|
||||
{:label (tr "workspace.tokens.shadow-spread")
|
||||
:placeholder (tr "workspace.tokens.shadow-spread")}
|
||||
:color
|
||||
{:label (tr "workspace.tokens.shadow-color")
|
||||
:placeholder (tr "workspace.tokens.shadow-color")}
|
||||
:inset
|
||||
{:label (tr "workspace.tokens.shadow-inset")
|
||||
:placeholder (tr "workspace.tokens.shadow-inset")}))
|
||||
:placeholder (tr "workspace.tokens.shadow-spread")}))
|
||||
|
||||
(def ^:private input-icon
|
||||
{:offsetX i/character-x
|
||||
:offsetY i/character-y})
|
||||
|
||||
(mf/defc shadow-color-picker-wrapper*
|
||||
"Wrapper for color-picker* that passes shadow color state from parent.
|
||||
@@ -99,7 +99,6 @@
|
||||
{::mf/private true}
|
||||
[{:keys [default-value label placeholder shadow-idx input-type on-update-value on-external-update-value token-resolve-result errors-by-key shadow-color]}]
|
||||
(let [color-input-ref (mf/use-ref)
|
||||
|
||||
on-change
|
||||
(mf/use-fn
|
||||
(mf/deps shadow-idx input-type on-update-value)
|
||||
@@ -130,24 +129,31 @@
|
||||
:shadow-idx shadow-idx
|
||||
:label label
|
||||
:on-change on-change}]
|
||||
|
||||
:color
|
||||
[:> shadow-color-picker-wrapper*
|
||||
{:placeholder placeholder
|
||||
:label label
|
||||
:aria-label label
|
||||
:default-value default-value
|
||||
:input-ref color-input-ref
|
||||
:on-update-value on-change
|
||||
:on-external-update-value on-external-update-value'
|
||||
:token-resolve-result token-prop
|
||||
:shadow-color shadow-color
|
||||
:shadow-color (or shadow-color nil)
|
||||
:data-testid (str "shadow-color-input-" shadow-idx)}]
|
||||
|
||||
[:div {:class (stl/css :input-row)
|
||||
:data-testid (str "shadow-" (name input-type) "-input-" shadow-idx)}
|
||||
[:> input-token*
|
||||
{:label label
|
||||
{:aria-label label
|
||||
:icon (get input-icon input-type)
|
||||
:placeholder placeholder
|
||||
:default-value default-value
|
||||
:on-change on-change
|
||||
:slot-start (cond (= input-type :blur)
|
||||
(mf/html [:span {:class (stl/css :shadow-prop-label)} "Blur"])
|
||||
(= input-type :spread)
|
||||
(mf/html [:span {:class (stl/css :shadow-prop-label)} "Spread"]))
|
||||
:token-resolve-result token-prop}]])))
|
||||
|
||||
(mf/defc shadow-input-fields*
|
||||
@@ -157,7 +163,8 @@
|
||||
(mf/use-fn
|
||||
(mf/deps shadow-idx on-remove-shadow)
|
||||
#(on-remove-shadow shadow-idx))]
|
||||
[:div {:data-testid (str "shadow-input-fields-" shadow-idx)}
|
||||
[:div {:data-testid (str "shadow-input-fields-" shadow-idx)
|
||||
:class (stl/css :shadow-input-fields)}
|
||||
[:> icon-button* {:icon i/add
|
||||
:type "button"
|
||||
:on-click on-add-shadow
|
||||
|
||||
@@ -15,3 +15,9 @@
|
||||
flex-direction: column;
|
||||
gap: var(--sp-m);
|
||||
}
|
||||
|
||||
.shadow-input-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-m);
|
||||
}
|
||||
@@ -69,7 +69,7 @@
|
||||
(let [{:keys [color on-display-colorpicker]} custom-input-token-value-props
|
||||
color-ramp-open* (mf/use-state false)
|
||||
color-ramp-open? (deref color-ramp-open*)
|
||||
|
||||
_ (.log js/console (clj->js token-resolve-result))
|
||||
on-click-swatch
|
||||
(mf/use-fn
|
||||
(mf/deps color-ramp-open? on-display-colorpicker)
|
||||
@@ -125,4 +125,5 @@
|
||||
[:> ramp*
|
||||
{:color (some-> color (tinycolor/valid-color))
|
||||
:on-change on-change'}])
|
||||
[:> token-value-hint* {:result token-resolve-result}]]))
|
||||
(when token-resolve-result
|
||||
[:> token-value-hint* {:result token-resolve-result}])]))
|
||||
@@ -2,6 +2,8 @@
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
|
||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :as i]
|
||||
[app.main.ui.icons :as deprecated-icon]
|
||||
[app.main.ui.workspace.tokens.management.create.input-tokens-value :refer [input-token*]]
|
||||
[app.util.dom :as dom]
|
||||
@@ -39,6 +41,8 @@
|
||||
reference-label
|
||||
set-active-tab
|
||||
title
|
||||
type
|
||||
on-add-shadow
|
||||
update-composite-backup-value]} custom-input-token-value-props
|
||||
reference-tab-active? (= :reference active-tab)
|
||||
;; Backup value ref
|
||||
@@ -90,7 +94,13 @@
|
||||
[:& radio-button {:icon deprecated-icon/tokens
|
||||
:value "reference"
|
||||
:title (tr "workspace.tokens.use-reference")
|
||||
:id "reference-opt"}]]]
|
||||
:id "reference-opt"}]]
|
||||
(when (= type :shadow)
|
||||
[:> icon-button* {:icon i/add
|
||||
:type "button"
|
||||
:on-click on-add-shadow
|
||||
:data-testid "shadow-add-button"
|
||||
:aria-label (tr "workspace.tokens.shadow-add-shadow")}])]
|
||||
[:div {:class (stl/css :typography-inputs)}
|
||||
(if reference-tab-active?
|
||||
[:> composite-reference-input*
|
||||
|
||||
Reference in New Issue
Block a user