From f3040fc10d911b966fcc417ee8cdeca411b94bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Torr=C3=B3?= Date: Wed, 19 Feb 2025 11:23:52 +0100 Subject: [PATCH] :bug: Pass color format to css formatter (#5890) * :bug: Pass color format to css formatter * :paperclip: Use get method to retrieve format * :paperclip: Add UI test to check background color is correctly copied to clipboard when changing the format --- frontend/playwright.config.js | 2 + .../ui/specs/inspect-layout.spec.js | 38 +++++++++++++++++++ .../app/main/ui/components/copy_button.cljs | 4 +- .../src/app/main/ui/components/select.cljs | 4 ++ .../main/ui/inspect/attributes/common.cljs | 1 + .../app/main/ui/inspect/attributes/fill.cljs | 2 +- .../app/util/code_gen/style_css_formats.cljs | 36 +++++++++--------- frontend/translations/en.po | 8 ++++ frontend/translations/es.po | 8 ++++ 9 files changed, 84 insertions(+), 19 deletions(-) diff --git a/frontend/playwright.config.js b/frontend/playwright.config.js index 03dcb027f..8360cb456 100644 --- a/frontend/playwright.config.js +++ b/frontend/playwright.config.js @@ -34,6 +34,8 @@ export default defineConfig({ trace: "on-first-retry", locale: "en-US", + + permissions: ["clipboard-write", "clipboard-read"], }, /* Configure projects for major browsers */ diff --git a/frontend/playwright/ui/specs/inspect-layout.spec.js b/frontend/playwright/ui/specs/inspect-layout.spec.js index afed6ace0..c5678ae01 100644 --- a/frontend/playwright/ui/specs/inspect-layout.spec.js +++ b/frontend/playwright/ui/specs/inspect-layout.spec.js @@ -32,3 +32,41 @@ test("Bug 9042 - Measurement unit dropdowns for columns are cut off in grid layo await rowsContainer.getByText("FR").nth(2).click(); await expect(rowsContainer.getByText("%")).toBeInViewport(); }); + +test("[Taiga #9116] Copy CSS background color in the selected format in the INSPECT tab", async ({ + page, + context, +}) => { + const workspacePage = new WorkspacePage(page); + await workspacePage.setupEmptyFile(page); + await workspacePage.goToWorkspace(); + + await workspacePage.rectShapeButton.click(); + await workspacePage.clickWithDragViewportAt(128, 128, 200, 100); + await workspacePage.clickLeafLayer("Rectangle"); + + const inspectButton = workspacePage.page.getByRole("tab", { + name: "Inspect", + }); + await inspectButton.click(); + + const colorDropdown = workspacePage.page + .getByRole("combobox") + .getByText("HEX"); + await colorDropdown.click(); + + const rgbaFormatButton = workspacePage.page.getByRole("option", { + name: "RGBA", + }); + await rgbaFormatButton.click(); + + const copyColorButton = workspacePage.page.getByRole("button", { + name: "Copy color", + }); + await copyColorButton.click(); + + const rgbaColorText = await page.evaluate(() => + navigator.clipboard.readText(), + ); + expect(rgbaColorText).toContain("background: rgba("); +}); diff --git a/frontend/src/app/main/ui/components/copy_button.cljs b/frontend/src/app/main/ui/components/copy_button.cljs index a767d931b..f4395bbd4 100644 --- a/frontend/src/app/main/ui/components/copy_button.cljs +++ b/frontend/src/app/main/ui/components/copy_button.cljs @@ -11,13 +11,14 @@ [app.main.data.event :as-alias ev] [app.main.ui.icons :as i] [app.util.dom :as dom] + [app.util.i18n :refer [tr]] [app.util.timers :as tm] [app.util.webapi :as wapi] [rumext.v2 :as mf])) (mf/defc copy-button {::mf/props :obj} - [{:keys [data on-copied children class]}] + [{:keys [data on-copied children class aria-label]}] (let [active* (mf/use-state false) active? (deref active*) @@ -38,6 +39,7 @@ (if (fn? data) (data) data)))))] [:button {:class class + :aria-label (or aria-label (tr "labels.copy")) :data-active (dm/str active?) :on-click on-click} children diff --git a/frontend/src/app/main/ui/components/select.cljs b/frontend/src/app/main/ui/components/select.cljs index fba040fbf..ca99a6263 100644 --- a/frontend/src/app/main/ui/components/select.cljs +++ b/frontend/src/app/main/ui/components/select.cljs @@ -102,6 +102,8 @@ current-icon (:icon selected-option) current-icon-ref (i/key->icon current-icon)] [:div {:on-click open-dropdown + :role "combobox" + :aria-activedescendent current-value :class (dm/str (stl/css-case :custom-select true :disabled disabled :icon (some? current-icon-ref)) @@ -116,11 +118,13 @@ (for [[index item] (d/enumerate options)] (if (= :separator item) [:li {:class (dom/classnames (stl/css :separator) true) + :role "option" :key (dm/str current-id "-" index)}] (let [[value label icon] (as-key-value item) icon-ref (i/key->icon icon)] [:li {:key (dm/str current-id "-" index) + :role "option" :class (stl/css-case :checked-element true :disabled (:disabled item) diff --git a/frontend/src/app/main/ui/inspect/attributes/common.cljs b/frontend/src/app/main/ui/inspect/attributes/common.cljs index 179f1da3f..4b1d095f9 100644 --- a/frontend/src/app/main/ui/inspect/attributes/common.cljs +++ b/frontend/src/app/main/ui/inspect/attributes/common.cljs @@ -117,6 +117,7 @@ [:div {:class (stl/css :format-info)} "rgba"])] [:& copy-button {:data copy-data + :aria-label (tr "labels.copy-color") :class (stl/css-case :color-row-copy-btn true :one-line (not color-library-name) :two-line (some? color-library-name))} diff --git a/frontend/src/app/main/ui/inspect/attributes/fill.cljs b/frontend/src/app/main/ui/inspect/attributes/fill.cljs index e7fa44c6a..7dd90bfb9 100644 --- a/frontend/src/app/main/ui/inspect/attributes/fill.cljs +++ b/frontend/src/app/main/ui/inspect/attributes/fill.cljs @@ -45,7 +45,7 @@ {:color color :format format :on-change-format on-change - :copy-data (css/get-shape-properties-css objects {:fills [shape]} properties)}]])) + :copy-data (css/get-shape-properties-css objects {:fills [shape]} properties {:format format})}]])) (mf/defc fill-panel {::mf/wrap-props false} diff --git a/frontend/src/app/util/code_gen/style_css_formats.cljs b/frontend/src/app/util/code_gen/style_css_formats.cljs index 0a9cdd515..170ac280d 100644 --- a/frontend/src/app/util/code_gen/style_css_formats.cljs +++ b/frontend/src/app/util/code_gen/style_css_formats.cljs @@ -53,28 +53,30 @@ :else value)) (defn format-color - [value _options] - (cond - (:image value) - (let [image-url (cfg/resolve-file-media (:image value)) - opacity-color (when (not= (:opacity value) 1) - (uc/gradient->css {:type :linear - :stops [{:color "#FFFFFF" :opacity (:opacity value)} - {:color "#FFFFFF" :opacity (:opacity value)}]}))] - (if opacity-color - ;; CSS doesn't allow setting directly opacity to background image, we should add a dummy gradient to get it - (dm/fmt "%, url(%) no-repeat center center / cover" opacity-color image-url) - (dm/fmt "url(%) no-repeat center center / cover" image-url))) + [value options] + (let [format (get options :format :hex)] + (cond + (:image value) + (let [image-url (cfg/resolve-file-media (:image value)) + opacity-color (when (not= (:opacity value) 1) + (uc/gradient->css {:type :linear + :stops [{:color "#FFFFFF" :opacity (:opacity value)} + {:color "#FFFFFF" :opacity (:opacity value)}]}))] + (if opacity-color + ;; CSS doesn't allow setting directly opacity to background image, we should add a dummy gradient to get it + (dm/fmt "%, url(%) no-repeat center center / cover" opacity-color image-url) + (dm/fmt "url(%) no-repeat center center / cover" image-url))) - (not= (:opacity value) 1) - (uc/color->background value) + (not= (:opacity value) 1) + (uc/color->format->background value format) - :else - (str/upper (:color value)))) + :else + (uc/color->format->background value format)))) (defmethod format-value :color [_ value options] - (format-color value options)) + (let [format (get options :format :hex)] + (format-color value (assoc options :format format)))) (defmethod format-value :color-array [_ value options] diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 706d77ce4..08dad4c95 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -1807,6 +1807,14 @@ msgstr "You can continue with a Penpot account" msgid "labels.copy-invitation-link" msgstr "Copy link" +#: src/app/main/ui/components/copy_button.cljs:42 +msgid "labels.copy" +msgstr "Copy" + +#: src/app/main/ui/inspect/attributes/common.cljs:120 +msgid "labels.copy-color" +msgstr "Copy color" + #: src/app/main/ui/static.cljs:62 msgid "labels.copyright" msgstr "Kaleidos @2024" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 207cf7d91..729b145cc 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -1817,6 +1817,14 @@ msgstr "Puedes continuar con una cuenta de Penpot" msgid "labels.copy-invitation-link" msgstr "Copiar enlace" +#: src/app/main/ui/components/copy_button.cljs:42 +msgid "labels.copy" +msgstr "Copiar" + +#: src/app/main/ui/inspect/attributes/common.cljs:120 +msgid "labels.copy-color" +msgstr "Copiar color" + #: src/app/main/ui/static.cljs:62 msgid "labels.copyright" msgstr "Kaleidos @2024"