diff --git a/frontend/playwright/ui/pages/WorkspacePage.js b/frontend/playwright/ui/pages/WorkspacePage.js index e2e12ae2ad..0aab8bdd4d 100644 --- a/frontend/playwright/ui/pages/WorkspacePage.js +++ b/frontend/playwright/ui/pages/WorkspacePage.js @@ -198,10 +198,10 @@ export class WorkspacePage extends BaseWebSocketPage { `[id="shape-00000000-0000-0000-0000-000000000000"]`, ); this.toolbarOptions = page.getByTestId("toolbar-options"); - this.rectShapeButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Rectangle" }); - this.ellipseShapeButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Ellipse" }); - this.moveButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Move" }); - this.boardButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Board" }); + this.rectShapeButton = page.getByRole("button", { name: "Rectangle (R)" }); + this.ellipseShapeButton = page.getByRole("button", { name: "Ellipse (E)" }); + this.moveButton = page.getByRole("button", { name: "Move (V)" }); + this.boardButton = page.getByRole("button", { name: "Board (B)" }); this.toggleToolbarButton = page.getByRole("button", { name: "Toggle toolbar", }); diff --git a/frontend/playwright/ui/specs/design-tab.spec.js b/frontend/playwright/ui/specs/design-tab.spec.js index df12cf9238..489579b844 100644 --- a/frontend/playwright/ui/specs/design-tab.spec.js +++ b/frontend/playwright/ui/specs/design-tab.spec.js @@ -189,8 +189,8 @@ test("BUG 7760 - Layout losing properties when changing parents", async ({ await workspacePage.clickLeafLayer("Flex Board"); // Move the first board into the second - const hAuto = await workspacePage.page.getByTestId("behaviour-h-auto"); - const vAuto = await workspacePage.page.getByTestId("behaviour-v-auto"); + const hAuto = await workspacePage.page.getByTitle("Fit content (Horizontal)"); + const vAuto = await workspacePage.page.getByTitle("Fit content (Vertical)"); await expect(vAuto.locator("input")).toBeChecked(); await expect(hAuto.locator("input")).toBeChecked(); diff --git a/frontend/playwright/ui/specs/tokens/crud.spec.js b/frontend/playwright/ui/specs/tokens/crud.spec.js index 66a3591ee4..b726db042d 100644 --- a/frontend/playwright/ui/specs/tokens/crud.spec.js +++ b/frontend/playwright/ui/specs/tokens/crud.spec.js @@ -1493,10 +1493,8 @@ test.describe("Tokens - creation", () => { const nameField = tokensUpdateCreateModal.getByLabel("Name"); await nameField.fill(newTokenTitle); - const referenceTabButton = tokensUpdateCreateModal.getByRole("button", { - name: "Use a reference", - }); - referenceTabButton.click(); + const referenceTabButton = tokensUpdateCreateModal.getByTestId("reference-opt"); + await referenceTabButton.click(); const referenceField = tokensUpdateCreateModal.getByRole("textbox", { name: "Reference", diff --git a/frontend/playwright/ui/specs/workspace.spec.js b/frontend/playwright/ui/specs/workspace.spec.js index 8c20a9efbe..02cc3958f1 100644 --- a/frontend/playwright/ui/specs/workspace.spec.js +++ b/frontend/playwright/ui/specs/workspace.spec.js @@ -353,33 +353,24 @@ test("Copy/paste properties", async ({ page, context }) => { await page.getByText("Copy/Paste as").hover(); await page.getByText("Paste properties").click(); - await page - .getByTestId("layer-item") - .getByText("Rectangle") - .first() - .click({ button: "right" }); + await page.getByText("Rectangle").first().click({ button: "right" }); + await page.getByText("Copy/Paste as").hover(); + await page.getByText("Paste properties").click(); + + await page.getByText("Board").nth(2).click({ button: "right" }); await page.getByText("Copy/Paste as").hover(); await page.getByText("Paste properties").click(); await page .getByTestId("layer-item") - .getByText("Board") + .locator("div") + .filter({ hasText: "Path" }) .nth(1) .click({ button: "right" }); await page.getByText("Copy/Paste as").hover(); await page.getByText("Paste properties").click(); - await page - .getByTestId("layer-item") - .getByText("Path") - .click({ button: "right" }); - await page.getByText("Copy/Paste as").hover(); - await page.getByText("Paste properties").click(); - - await page - .getByTestId("layer-item") - .getByText("Ellipse") - .click({ button: "right" }); + await page.getByText("Ellipse").click({ button: "right" }); await page.getByText("Copy/Paste as").hover(); await page.getByText("Paste properties").click(); }); diff --git a/frontend/resources/styles/common/refactor/design-tokens.scss b/frontend/resources/styles/common/refactor/design-tokens.scss index 37f6c546f1..2acb81398a 100644 --- a/frontend/resources/styles/common/refactor/design-tokens.scss +++ b/frontend/resources/styles/common/refactor/design-tokens.scss @@ -244,6 +244,13 @@ --assets-component-second-border-selected: var(--color-background-primary); --assets-component-hightlight: var(--color-accent-secondary); + --radio-btns-background-color: var(--color-background-tertiary); + --radio-btn-background-color-selected: var(--color-background-quaternary); + --radio-btn-foreground-color: var(--color-foreground-secondary); + --radio-btn-foreground-color-selected: var(--color-accent-primary); + --radio-btn-border-color: var(--color-background-tertiary); + --radio-btn-border-color-selected: var(--color-background-quaternary); + --library-name-foreground-color: var(--color-foreground-primary); --library-content-foreground-color: var(--color-foreground-secondary); @@ -416,6 +423,13 @@ --tab-border-color: var(--color-background-tertiary); --tab-border-color-selected: var(--color-background-secondary); + --radio-btns-background-color: var(--color-background-tertiary); + --radio-btn-background-color-selected: var(--color-background-primary); + --radio-btn-foreground-color: var(--color-foreground-secondary); + --radio-btn-foreground-color-selected: var(--color-accent-primary); + --radio-btn-border-color: var(--color-background-tertiary); + --radio-btn-border-color-selected: var(--color-background-secondary); + --button-icon-background-color-selected: var(--color-background-primary); --button-icon-border-color-selected: var(--color-background-secondary); diff --git a/frontend/src/app/main/ui/components/file_uploader.cljs b/frontend/src/app/main/ui/components/file_uploader.cljs index b381dc396a..8eebdff516 100644 --- a/frontend/src/app/main/ui/components/file_uploader.cljs +++ b/frontend/src/app/main/ui/components/file_uploader.cljs @@ -10,9 +10,9 @@ [app.util.dom :as dom] [rumext.v2 :as mf])) -(mf/defc file-uploader* +(mf/defc file-uploader {::mf/forward-ref true} - [{:keys [accept multi label-text label-class input-id on-selected data-testid]} input-ref] + [{:keys [accept multi label-text label-class input-id on-selected data-testid] :as props} input-ref] (let [opt-pick-one #(if multi % (first %)) on-files-selected diff --git a/frontend/src/app/main/ui/components/radio_buttons.cljs b/frontend/src/app/main/ui/components/radio_buttons.cljs new file mode 100644 index 0000000000..d8bc4c969e --- /dev/null +++ b/frontend/src/app/main/ui/components/radio_buttons.cljs @@ -0,0 +1,107 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.main.ui.components.radio-buttons + (:require-macros [app.main.style :as stl]) + (:require + [app.common.data :as d] + [app.common.data.macros :as dm] + [app.main.ui.ds.foundations.assets.icon :refer [icon*]] + [app.main.ui.formats :as fmt] + [app.util.dom :as dom] + [rumext.v2 :as mf])) + +(def context + (mf/create-context nil)) + +(mf/defc radio-button + {::mf/props :obj} + [{:keys [icon id value disabled title icon-class type]}] + (let [context (mf/use-ctx context) + allow-empty (unchecked-get context "allow-empty") + type (if ^boolean type + type + (if ^boolean allow-empty + "checkbox" + "radio")) + + on-change (unchecked-get context "on-change") + selected (unchecked-get context "selected") + name (unchecked-get context "name") + + encode-fn (unchecked-get context "encode-fn") + checked? (= selected value) + + value (encode-fn value)] + + + [:label {:html-for id + :data-testid id + :title title + :class (stl/css-case + :radio-icon true + :checked checked? + :disabled disabled)} + + (if (some? icon) + [:> icon* {:icon-id icon :class icon-class :aria-hidden true}] + [:span {:class (stl/css :title-name)} value]) + + [:input {:id id + :on-change on-change + :type type + :name name + :disabled disabled + :value value + :default-checked checked?}]])) + +(mf/defc radio-buttons + {::mf/props :obj} + [{:keys [name children on-change selected class wide encode-fn decode-fn allow-empty] :as props}] + (let [encode-fn (d/nilv encode-fn identity) + decode-fn (d/nilv decode-fn identity) + nitems (if (array? children) + (count (keep identity children)) + 1) + ;; FIXME: we should handle this with CSS + width (mf/with-memo [nitems] + (if (= wide true) + "unset" + (fmt/format-pixels + (+ (* 4 (- nitems 1)) + (* 32 nitems))))) + + on-change' + (mf/use-fn + (mf/deps selected on-change) + (fn [event] + (let [input (dom/get-target event) + value (dom/get-target-val event) + + ;; Only allow null values when the "allow-empty" prop is true + value (when (or (not allow-empty) + (not= value selected)) value)] + (when (fn? on-change) + (on-change (decode-fn value) event)) + (dom/blur! input)))) + + context-value + (mf/spread-object props + ;; We pass a special metadata for disable + ;; key casing transformation in this + ;; concrete case, because this component + ;; uses legacy mode and props are in + ;; kebab-case style + ^{::mf/transform false} + {:on-change on-change' + :encode-fn encode-fn + :decode-fn decode-fn})] + + [:& (mf/provider context) {:value context-value} + [:div {:class (dm/str class " " (stl/css :radio-btn-wrapper)) + :style {:width width} + :key (dm/str name "-" selected)} + children]])) diff --git a/frontend/src/app/main/ui/components/radio_buttons.scss b/frontend/src/app/main/ui/components/radio_buttons.scss new file mode 100644 index 0000000000..6ef73339ad --- /dev/null +++ b/frontend/src/app/main/ui/components/radio_buttons.scss @@ -0,0 +1,79 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) KALEIDOS INC + +@use "refactor/common-refactor.scss" as deprecated; + +.radio-btn-wrapper { + @include deprecated.flexCenter; + border-radius: deprecated.$br-8; + height: deprecated.$s-32; + background-color: var(--input-background-color); + gap: deprecated.$s-4; +} + +.radio-icon { + --radio-icon-border-color: var(--radio-btn-border-color); + + @include deprecated.buttonStyle; + @include deprecated.flexCenter; + @include deprecated.focusRadio; + height: deprecated.$s-32; + flex-grow: 1; + border-radius: deprecated.$s-8; + box-sizing: border-box; + border: deprecated.$br-2 solid var(--radio-icon-border-color); + + input { + display: none; + } + svg { + @extend .button-icon; + stroke: var(--radio-btn-foreground-color); + } + .title-name { + @include deprecated.uppercaseTitleTipography; + color: var(--radio-btn-foreground-color); + } + &:hover { + svg { + stroke: var(--radio-btn-foreground-color-selected); + } + } +} + +.checked { + --radio-icon-border-color: var(--radio-btn-border-color-selected); + + background-color: var(--radio-btn-background-color-selected); + svg { + stroke: var(--radio-btn-foreground-color-selected); + } + .title-name { + color: var(--radio-btn-foreground-color-selected); + } +} + +.disabled { + cursor: default; + background-color: transparent; + border: deprecated.$s-2 solid transparent; + svg { + stroke: var(--button-foreground-color-disabled); + } + .title-name { + color: var(--button-foreground-color-disabled); + } + &:hover { + background-color: transparent; + border: deprecated.$s-2 solid transparent; + svg { + stroke: var(--button-foreground-color-disabled); + } + .title-name { + color: var(--button-foreground-color-disabled); + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/fonts.cljs b/frontend/src/app/main/ui/dashboard/fonts.cljs index c1aa638671..f84d694893 100644 --- a/frontend/src/app/main/ui/dashboard/fonts.cljs +++ b/frontend/src/app/main/ui/dashboard/fonts.cljs @@ -17,7 +17,7 @@ [app.main.repo :as rp] [app.main.store :as st] [app.main.ui.components.context-menu-a11y :refer [context-menu*]] - [app.main.ui.components.file-uploader :refer [file-uploader*]] + [app.main.ui.components.file-uploader :refer [file-uploader]] [app.main.ui.ds.product.empty-placeholder :refer [empty-placeholder*]] [app.main.ui.icons :as deprecated-icon] [app.main.ui.notifications.context-notification :refer [context-notification]] @@ -184,11 +184,11 @@ :on-click on-click :tab-index "0"} [:span (tr "labels.add-custom-font")] - [:> file-uploader* {:input-id "font-upload" - :accept accept-font-types - :multi true - :ref input-ref - :on-selected on-selected}]] + [:& file-uploader {:input-id "font-upload" + :accept accept-font-types + :multi true + :ref input-ref + :on-selected on-selected}]] (when-let [url cf/terms-of-service-uri] [:& context-notification {:content (tr "dashboard.fonts.hero-text2" url) diff --git a/frontend/src/app/main/ui/dashboard/import.cljs b/frontend/src/app/main/ui/dashboard/import.cljs index ea2db3bda2..1510af2455 100644 --- a/frontend/src/app/main/ui/dashboard/import.cljs +++ b/frontend/src/app/main/ui/dashboard/import.cljs @@ -16,7 +16,7 @@ [app.main.data.modal :as modal] [app.main.data.notifications :as ntf] [app.main.store :as st] - [app.main.ui.components.file-uploader :refer [file-uploader*]] + [app.main.ui.components.file-uploader :refer [file-uploader]] [app.main.ui.ds.product.loader :refer [loader*]] [app.main.ui.icons :as deprecated-icon] [app.main.ui.notifications.context-notification :refer [context-notification]] @@ -58,10 +58,10 @@ [{:keys [project-id on-finish-import]} external-ref] (let [on-file-selected (use-import-file project-id on-finish-import)] [:form.import-file {:aria-hidden "true"} - [:> file-uploader* {:accept ".penpot,.zip" - :multi true - :ref external-ref - :on-selected on-file-selected}]])) + [:& file-uploader {:accept ".penpot,.zip" + :multi true + :ref external-ref + :on-selected on-file-selected}]])) (defn- update-entry-name [entries file-id new-name] diff --git a/frontend/src/app/main/ui/dashboard/team.cljs b/frontend/src/app/main/ui/dashboard/team.cljs index 51eab781b2..96afda2563 100644 --- a/frontend/src/app/main/ui/dashboard/team.cljs +++ b/frontend/src/app/main/ui/dashboard/team.cljs @@ -19,7 +19,7 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] - [app.main.ui.components.file-uploader :refer [file-uploader*]] + [app.main.ui.components.file-uploader :refer [file-uploader]] [app.main.ui.components.forms :as fm] [app.main.ui.dashboard.change-owner] [app.main.ui.dashboard.subscription :refer [members-cta* @@ -1315,10 +1315,10 @@ [:img {:class (stl/css :team-image) :src (cfg/resolve-team-photo-url team)}] (when can-edit - [:> file-uploader* {:accept "image/jpeg,image/png" - :multi false - :ref finput - :on-selected on-file-selected}])] + [:& file-uploader {:accept "image/jpeg,image/png" + :multi false + :ref finput + :on-selected on-file-selected}])] [:div {:class (stl/css :block-label)} (tr "dashboard.team-info")] [:div {:class (stl/css :block-text)} diff --git a/frontend/src/app/main/ui/delete_shared.cljs b/frontend/src/app/main/ui/delete_shared.cljs index eb6ffcd35c..51fcb8225e 100644 --- a/frontend/src/app/main/ui/delete_shared.cljs +++ b/frontend/src/app/main/ui/delete_shared.cljs @@ -11,10 +11,8 @@ [app.main.data.modal :as modal] [app.main.repo :as rp] [app.main.store :as st] - [app.main.ui.ds.buttons.button :refer [button*]] - [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.notifications.context-notification :refer [context-notification*]] + [app.main.ui.icons :as deprecated-icon] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.keyboard :as k] @@ -99,11 +97,8 @@ [:div {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-header)} [:h2 {:class (stl/css :modal-title)} title] - [:> icon-button* {:variant "ghost" - :class (stl/css :modal-close-btn) - :icon i/close - :aria-label (tr "labels.close") - :on-click cancel-fn}]] + [:button {:class (stl/css :modal-close-btn) + :on-click cancel-fn} deprecated-icon/close]] [:div {:class (stl/css :modal-content)} (when (and (string? subtitle) (not= subtitle "")) @@ -129,10 +124,14 @@ [:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :action-buttons)} (when-not (= cancel-label :omit) - [:> button* {:variant "secondary" - :on-click cancel-fn} - cancel-label]) + [:input {:class (stl/css :cancel-button) + :type "button" + :value cancel-label + :on-click cancel-fn}]) - [:> button* {:variant (if (= accept-style :danger) "destructive" "primary") - :on-click accept-fn} - accept-label]]]]])) + [:input {:class (stl/css-case :accept-btn true + :danger (= accept-style :danger) + :primary (= accept-style :primary)) + :type "button" + :value accept-label + :on-click accept-fn}]]]]])) diff --git a/frontend/src/app/main/ui/delete_shared.scss b/frontend/src/app/main/ui/delete_shared.scss index e9597009d1..d0f08a50e8 100644 --- a/frontend/src/app/main/ui/delete_shared.scss +++ b/frontend/src/app/main/ui/delete_shared.scss @@ -33,9 +33,7 @@ } .modal-close-btn { - position: absolute; - top: var(--sp-s); - right: var(--sp-s); + @extend .modal-close-btn-base; } .modal-content { @@ -55,6 +53,17 @@ @extend .modal-action-btns; } +.cancel-button { + @extend .modal-cancel-btn; +} + +.accept-btn { + @extend .modal-accept-btn; + &.danger { + @extend .modal-danger-btn; + } +} + .modal-scd-msg { margin-block: 0; } diff --git a/frontend/src/app/main/ui/ds/buttons/button.scss b/frontend/src/app/main/ui/ds/buttons/button.scss index a46f062c5d..dd8c720559 100644 --- a/frontend/src/app/main/ui/ds/buttons/button.scss +++ b/frontend/src/app/main/ui/ds/buttons/button.scss @@ -15,7 +15,6 @@ display: inline-flex; align-items: center; - justify-content: center; column-gap: var(--sp-xs); } diff --git a/frontend/src/app/main/ui/exports/assets.cljs b/frontend/src/app/main/ui/exports/assets.cljs index 7850050c7c..feb7f52906 100644 --- a/frontend/src/app/main/ui/exports/assets.cljs +++ b/frontend/src/app/main/ui/exports/assets.cljs @@ -208,7 +208,7 @@ ;; FIXME: deprecated, should be refactored in two components and use ;; the generic progress reporter -(mf/defc progress-widget* +(mf/defc progress-widget {::mf/wrap [mf/memo]} [] (let [state (mf/deref refs/export) diff --git a/frontend/src/app/main/ui/inspect/code.cljs b/frontend/src/app/main/ui/inspect/code.cljs index 605d8e38ee..661bee9075 100644 --- a/frontend/src/app/main/ui/inspect/code.cljs +++ b/frontend/src/app/main/ui/inspect/code.cljs @@ -19,10 +19,7 @@ [app.main.store :as st] [app.main.ui.components.code-block :refer [code-block]] [app.main.ui.components.copy-button :refer [copy-button*]] - [app.main.ui.ds.buttons.button :refer [button*]] - [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] - [app.main.ui.ds.foundations.assets.icon :as i] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.hooks.resize :refer [use-resize-hook]] [app.main.ui.icons :as deprecated-icon] [app.main.ui.shapes.text.fontfaces :refer [shapes->fonts]] @@ -263,9 +260,8 @@ [:div {:class (stl/css-case :element-options true :viewer-code-block (= :viewer from))} [:div {:class (stl/css :attributes-block)} - [:> button* {:variant "secondary" - :class (stl/css :download-button) - :on-click handle-copy-all-code} + [:button {:class (stl/css :download-button) + :on-click handle-copy-all-code} "Copy all code"]] #_[:div.attributes-block @@ -292,10 +288,10 @@ ;; :options [{:label "CSS" :value "css"}]}] [:div {:class (stl/css :action-btns)} - [:> icon-button* {:variant "ghost" - :aria-label "Expand" - :on-click on-expand - :icon i/code}] + [:button {:class (stl/css :expand-button) + :on-click on-expand} + deprecated-icon/code] + [:> copy-button* {:data copy-css-fn :class (stl/css :css-copy-btn) :on-copied on-style-copied}]]] @@ -322,21 +318,21 @@ :rotated collapsed-markup?)} deprecated-icon/arrow]] - [:> radio-buttons* {:selected markup-type - :on-change set-markup - :name "listing-style" - :options [{:id "html" - :label "HTML" - :value "html"} - {:id "svg" - :label "SVG" - :value "svg"}]}] + [:& radio-buttons {:selected markup-type + :on-change set-markup + :class (stl/css :code-lang-options) + :wide true + :name "listing-style"} + [:& radio-button {:value "html" + :id :html}] + [:& radio-button {:value "svg" + :id :svg}]] [:div {:class (stl/css :action-btns)} - [:> icon-button* {:variant "ghost" - :aria-label "Expand" - :on-click on-expand - :icon i/code}] + [:button {:class (stl/css :expand-button) + :on-click on-expand} + deprecated-icon/code] + [:> copy-button* {:data copy-html-fn :class (stl/css :html-copy-btn) :on-copied on-markup-copied}]]] diff --git a/frontend/src/app/main/ui/inspect/code.scss b/frontend/src/app/main/ui/inspect/code.scss index 93bf3c88e5..7f88871edc 100644 --- a/frontend/src/app/main/ui/inspect/code.scss +++ b/frontend/src/app/main/ui/inspect/code.scss @@ -17,18 +17,16 @@ padding-inline: var(--sp-m); } -.attributes-block { - display: flex; - flex-direction: column; - row-gap: 12px; -} - .viewer-code-block { height: calc(100vh - #{deprecated.$s-108}); // TODO: Fix this hardcoded value } .download-button { - margin: var(--sp-s) 0; + @extend .button-secondary; + @include deprecated.uppercaseTitleTipography; + height: deprecated.$s-32; + width: 100%; + margin: deprecated.$s-8 0; } .code-block { @@ -75,6 +73,7 @@ gap: deprecated.$s-4; } +.expand-button, .css-copy-btn, .html-copy-btn { @extend .button-tertiary; @@ -86,6 +85,9 @@ } } +.code-lang-options { + max-width: deprecated.$s-108; +} .code-lang-select { @include deprecated.uppercaseTitleTipography; width: deprecated.$s-72; diff --git a/frontend/src/app/main/ui/settings/profile.cljs b/frontend/src/app/main/ui/settings/profile.cljs index 30855c2b00..763ee3c836 100644 --- a/frontend/src/app/main/ui/settings/profile.cljs +++ b/frontend/src/app/main/ui/settings/profile.cljs @@ -14,7 +14,7 @@ [app.main.data.profile :as du] [app.main.refs :as refs] [app.main.store :as st] - [app.main.ui.components.file-uploader :refer [file-uploader*]] + [app.main.ui.components.file-uploader :refer [file-uploader]] [app.main.ui.components.forms :as fm] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -110,11 +110,11 @@ [:span {:class (stl/css :update-overlay) :on-click on-image-click} (tr "labels.update")] [:img {:src photo}] - [:> file-uploader* {:accept "image/jpeg,image/png" - :multi false - :ref input-ref - :on-selected on-file-selected - :data-testid "profile-image-input"}]]])) + [:& file-uploader {:accept "image/jpeg,image/png" + :multi false + :ref input-ref + :on-selected on-file-selected + :data-testid "profile-image-input"}]]])) ;; --- Profile Page diff --git a/frontend/src/app/main/ui/viewer/comments.cljs b/frontend/src/app/main/ui/viewer/comments.cljs index 5bc7e4a953..9646c81f8c 100644 --- a/frontend/src/app/main/ui/viewer/comments.cljs +++ b/frontend/src/app/main/ui/viewer/comments.cljs @@ -27,8 +27,9 @@ [okulary.core :as l] [rumext.v2 :as mf])) -(mf/defc comments-menu* - {::mf/memo true} +(mf/defc comments-menu + {::mf/props :obj + ::mf/memo true} [] (let [state (mf/deref refs/comments-local) cmode (:mode state) diff --git a/frontend/src/app/main/ui/viewer/header.cljs b/frontend/src/app/main/ui/viewer/header.cljs index 334c3ac9d2..270e30643b 100644 --- a/frontend/src/app/main/ui/viewer/header.cljs +++ b/frontend/src/app/main/ui/viewer/header.cljs @@ -14,13 +14,10 @@ [app.main.data.viewer.shortcuts :as sc] [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] - [app.main.ui.ds.buttons.button :refer [button*]] - [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.foundations.assets.icon :as i] - [app.main.ui.exports.assets :refer [progress-widget*]] + [app.main.ui.exports.assets :refer [progress-widget]] [app.main.ui.formats :as fmt] [app.main.ui.icons :as deprecated-icon] - [app.main.ui.viewer.comments :refer [comments-menu*]] + [app.main.ui.viewer.comments :refer [comments-menu]] [app.main.ui.viewer.interactions :refer [flows-menu* interactions-menu*]] [app.util.dom :as dom] [app.util.i18n :refer [tr]] @@ -36,12 +33,20 @@ [] (modal/show! :login-register {})) -(mf/defc zoom-widget* - {::mf/memo true} - [{:keys [zoom on-increase on-decrease on-zoom-reset on-fullscreen on-zoom-fit on-zoom-fill]}] - (let [open* (mf/use-state false) - open? (deref open*) +(mf/defc zoom-widget + {::mf/memo true + ::mf/props :obj} + [{:keys [zoom + on-increase + on-decrease + on-zoom-reset + on-fullscreen + on-zoom-fit + on-zoom-fill] + :as props}] + (let [open* (mf/use-state false) + open? (deref open*) open-dropdown (mf/use-fn (fn [event] @@ -70,7 +75,7 @@ [:div {:class (stl/css-case :zoom-widget true :selected open?) - :on-click (if open? close-dropdown open-dropdown) + :on-click open-dropdown :title (tr "workspace.header.zoom")} [:span {:class (stl/css :label)} (fmt/format-percent zoom)] [:& dropdown {:show open? @@ -78,18 +83,18 @@ [:ul {:class (stl/css :dropdown)} [:li {:class (stl/css :basic-zoom-bar)} [:span {:class (stl/css :zoom-btns)} - [:> icon-button* {:variant "ghost" - :aria-label (tr "shortcuts.decrease-zoom") - :on-click on-decrease - :icon i/remove}] - [:p {:class (stl/css :zoom-text)} + [:button {:class (stl/css :zoom-btn) + :on-click on-decrease} + [:span {:class (stl/css :zoom-icon)} + deprecated-icon/remove-icon]] + [:p {:class (stl/css :zoom-text)} (fmt/format-percent zoom)] - [:> icon-button* {:variant "ghost" - :aria-label (tr "shortcuts.increase-zoom") - :on-click on-increase - :icon i/add}]] - [:> button* {:variant "ghost" - :on-click on-zoom-reset} + [:button {:class (stl/css :zoom-btn) + :on-click on-increase} + [:span {:class (stl/css :zoom-icon)} + deprecated-icon/add]]] + [:button {:class (stl/css :reset-btn) + :on-click on-zoom-reset} (tr "workspace.header.reset-zoom")]] [:li {:class (stl/css :zoom-option) @@ -114,7 +119,7 @@ [:span {:class (stl/css :shortcut-key) :key (dm/str "zoom-fullscreen-" sc)} sc])]]]]])) -(mf/defc header-options* +(mf/defc header-options [{:keys [section zoom page file index permissions interactions-mode share]}] (let [fullscreen? (mf/deref fullscreen-ref) @@ -154,7 +159,6 @@ handle-zoom-fit (mf/use-fn #(st/emit! dv/zoom-to-fit))] - (mf/with-effect [permissions share] (when (and (:in-team permissions) @@ -163,7 +167,7 @@ (open-share-dialog))) [:div {:class (stl/css :options-zone)} - [:> progress-widget*] + [:& progress-widget] (case section :interactions [:* @@ -171,41 +175,40 @@ [:> flows-menu* {:page page :index index}]) [:> interactions-menu* {:interactions-mode interactions-mode}]] - :comments [:> comments-menu*] + :comments [:& comments-menu] [:div {:class (stl/css :view-options)}]) - [:> zoom-widget* {:zoom zoom - :on-increase handle-increase - :on-decrease handle-decrease - :on-zoom-reset handle-zoom-reset - :on-zoom-fill handle-zoom-fill - :on-zoom-fit handle-zoom-fit - :on-fullscreen toggle-fullscreen}] + [:& zoom-widget + {:zoom zoom + :on-increase handle-increase + :on-decrease handle-decrease + :on-zoom-reset handle-zoom-reset + :on-zoom-fill handle-zoom-fill + :on-zoom-fit handle-zoom-fit + :on-fullscreen toggle-fullscreen}] (when (:in-team permissions) - [:> icon-button* {:variant "ghost" - :aria-label (tr "viewer.header.edit-in-workspace") - :on-click go-to-workspace - :icon i/curve}]) + [:span {:on-click go-to-workspace + :class (stl/css :edit-btn)} + deprecated-icon/curve]) - [:> icon-button* {:variant "ghost" - :aria-pressed fullscreen? - :aria-label (tr "viewer.header.fullscreen") - :on-click toggle-fullscreen - :icon i/expand}] + [:span {:title (tr "viewer.header.fullscreen") + :class (stl/css-case :fullscreen-btn true + :selected fullscreen?) + :on-click toggle-fullscreen} + deprecated-icon/expand] (when (:in-team permissions) - [:> button* {:variant "primary" - :class (stl/css :share-btn) - :on-click open-share-dialog} + [:button {:on-click open-share-dialog + :class (stl/css :share-btn)} (tr "labels.share")]) (when-not (:is-logged permissions) [:span {:on-click open-login-dialog :class (stl/css :go-log-btn)} (tr "labels.log-or-sign")])])) -(mf/defc header-sitemap* - [{:keys [project file page frame toggle-thumbnails]}] +(mf/defc header-sitemap + [{:keys [project file page frame toggle-thumbnails] :as props}] (let [project-name (:name project) file-name (:name file) page-name (:name page) @@ -314,44 +317,44 @@ :pointer-events (when-not (:in-team permissions) "none")}} penpot-logo-icon] - [:> header-sitemap* {:project project - :file file - :page page - :frame frame - :toggle-thumbnails toggle-thumbnails - :index index}]] + [:& header-sitemap {:project project + :file file + :page page + :frame frame + :toggle-thumbnails toggle-thumbnails + :index index}]] [:div {:class (stl/css :mode-zone)} - [:> icon-button* {:variant "ghost" - :aria-pressed (= section :interactions) - :aria-label (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions)) - :data-value "interactions" - :on-click navigate - :icon i/play}] + [:button {:on-click navigate + :data-value "interactions" + :class (stl/css-case :mode-zone-btn true + :selected (= section :interactions)) + :title (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))} + deprecated-icon/play] (when (or (:in-team permissions) (= (:who-comment permissions) "all")) - [:> icon-button* {:variant "ghost" - :aria-pressed (= section :comments) - :aria-label (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments)) - :data-value "comments" - :on-click navigate - :icon i/comments}]) + [:button {:on-click navigate + :data-value "comments" + :class (stl/css-case :mode-zone-btn true + :selected (= section :comments)) + :title (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments))} + deprecated-icon/comments]) (when (or (:in-team permissions) (and (= (:type permissions) :share-link) (= (:who-inspect permissions) "all"))) - [:> icon-button* {:variant "ghost" - :aria-pressed (= section :inspect) - :aria-label (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect)) - :on-click go-to-inspect - :icon i/code}])] + [:button {:on-click go-to-inspect + :class (stl/css-case :mode-zone-btn true + :selected (= section :inspect)) + :title (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect))} + deprecated-icon/code])] - [:> header-options* {:section section - :permissions permissions - :page page - :file file - :index index - :zoom zoom - :interactions-mode interactions-mode - :share share}]])) + [:& header-options {:section section + :permissions permissions + :page page + :file file + :index index + :zoom zoom + :interactions-mode interactions-mode + :share share}]])) diff --git a/frontend/src/app/main/ui/viewer/header.scss b/frontend/src/app/main/ui/viewer/header.scss index 83a1400033..f9814d3a44 100644 --- a/frontend/src/app/main/ui/viewer/header.scss +++ b/frontend/src/app/main/ui/viewer/header.scss @@ -12,7 +12,7 @@ grid-column: 1 / span 1; grid-row: 1 / span 1; display: grid; - grid-template-columns: 1fr auto 1fr; + grid-template-columns: 1fr deprecated.$s-92 1fr; justify-content: space-between; align-items: center; height: deprecated.$s-48; @@ -130,9 +130,23 @@ // SECTION BUTTONS .mode-zone { - display: flex; - flex-direction: row; - gap: var(--sp-xs); + @include deprecated.flexRow; + height: 100%; +} + +.mode-zone-btn { + @extend .button-tertiary; + @include deprecated.flexCenter; + height: deprecated.$s-32; + width: deprecated.$s-28; + padding: 0; + svg { + @extend .button-icon; + } +} + +.selected { + @extend .button-icon-selected; } // OPTION AREA @@ -151,8 +165,33 @@ cursor: pointer; } +.fullscreen-btn { + @extend .button-tertiary; + @include deprecated.flexCenter; + height: deprecated.$s-32; + width: deprecated.$s-28; + svg { + @extend .button-icon; + stroke: var(--icon-foreground); + } +} + .share-btn { - margin-left: var(--sp-xs); + @extend .button-primary; + height: deprecated.$s-32; + min-width: deprecated.$s-72; + margin-left: deprecated.$s-4; +} + +.edit-btn { + @extend .button-tertiary; + @include deprecated.flexCenter; + height: deprecated.$s-32; + width: deprecated.$s-28; + svg { + @extend .button-icon; + stroke: var(--icon-foreground); + } } .go-log-btn { @@ -206,15 +245,43 @@ display: flex; } +.zoom-btn { + @extend .button-tertiary; + height: deprecated.$s-28; + width: deprecated.$s-28; + border-radius: deprecated.$br-8; + .zoom-icon { + @include deprecated.flexCenter; + width: deprecated.$s-24; + height: deprecated.$s-32; + svg { + @extend .button-icon; + stroke: var(--icon-foreground); + } + } + &:hover { + .zoom-icon svg { + stroke: var(--button-tertiary-foreground-color-hover); + } + } +} + .zoom-text { @include deprecated.flexCenter; height: 100%; - min-width: deprecated.$s-48; + min-width: deprecated.$s-64; padding: 0; margin: 0 deprecated.$s-2; color: var(--modal-title-foreground-color); } +.reset-btn { + @extend .button-tertiary; + color: var(--button-tertiary-foreground-color-hover); + height: deprecated.$s-28; + border-radius: deprecated.$br-8; +} + .zoom-option { @extend .menu-item-base; .shortcuts { diff --git a/frontend/src/app/main/ui/viewer/share_link.cljs b/frontend/src/app/main/ui/viewer/share_link.cljs index 7867a3c200..646405676c 100644 --- a/frontend/src/app/main/ui/viewer/share_link.cljs +++ b/frontend/src/app/main/ui/viewer/share_link.cljs @@ -20,9 +20,6 @@ [app.main.router :as rt] [app.main.store :as st] [app.main.ui.components.select :refer [select]] - [app.main.ui.ds.buttons.button :refer [button*]] - [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.util.clipboard :as clipboard] [app.util.dom :as dom] @@ -174,11 +171,10 @@ [:div {:class (stl/css :share-link-header)} [:h2 {:class (stl/css :share-link-title)} (tr "common.share-link.title")] - [:> icon-button* {:variant "ghost" - :class (stl/css :modal-close-button) - :aria-label (tr "labels.close") - :on-click on-close - :icon i/close}]] + [:button {:class (stl/css :modal-close-button) + :on-click on-close + :title (tr "labels.close")} + deprecated-icon/close]] [:div {:class (stl/css :modal-content)} [:div {:class (stl/css :share-link-section)} (when (and (not confirm?) (some? current-link)) @@ -189,10 +185,10 @@ :placeholder (tr "common.share-link.placeholder") :read-only true}] - [:> icon-button* {:variant "ghost" - :aria-label (tr "viewer.header.share.copy-link") - :on-click copy-link - :icon i/clipboard}]]) + [:button {:class (stl/css :copy-button) + :title (tr "viewer.header.share.copy-link") + :on-click copy-link} + deprecated-icon/clipboard]]) [:div {:class (stl/css :hint-wrapper)} (when (not ^boolean confirm?) @@ -203,22 +199,28 @@ [:div {:class (stl/css :description)} (tr "common.share-link.confirm-deletion-link-description")] [:div {:class (stl/css :actions)} - [:> button* {:variant "secondary" - :on-click #(reset! confirm* false)} - (tr "labels.cancel")] - [:> button* {:variant "destructive" - :on-click delete-link} - (tr "common.share-link.destroy-link")]]] + [:input {:type "button" + :class (stl/css :button-cancel) + :on-click #(reset! confirm* false) + :value (tr "labels.cancel")}] + [:input {:type "button" + :class (stl/css :button-danger) + :on-click delete-link + :value (tr "common.share-link.destroy-link")}]]] (some? current-link) - [:> button* {:variant "destructive" - :on-click try-delete-link} - (tr "common.share-link.destroy-link")] + [:input + {:type "button" + :class (stl/css :button-danger) + :on-click try-delete-link + :value (tr "common.share-link.destroy-link")}] :else - [:> button* {:variant "primary" - :on-click create-link} - (tr "common.share-link.get-link")])]] + [:input + {:type "button" + :class (stl/css :button-active) + :on-click create-link + :value (tr "common.share-link.get-link")}])]] (when (not ^boolean confirm?) @@ -303,7 +305,6 @@ :options [{:value "team" :label (tr "common.share-link.team-members")} {:value "all" :label (tr "common.share-link.all-users")}] :on-change on-comment-change}]]] - [:div {:class (stl/css :inspect-mode)} [:div {:class (stl/css :subtitle)} (tr "common.share-link.permissions-can-inspect")] @@ -314,3 +315,6 @@ :options [{:value "team" :label (tr "common.share-link.team-members")} {:value "all" :label (tr "common.share-link.all-users")}] :on-change on-inspect-change}]]]])])]]])) + + + diff --git a/frontend/src/app/main/ui/viewer/share_link.scss b/frontend/src/app/main/ui/viewer/share_link.scss index b877736d16..2c8bcc60b1 100644 --- a/frontend/src/app/main/ui/viewer/share_link.scss +++ b/frontend/src/app/main/ui/viewer/share_link.scss @@ -30,9 +30,7 @@ } .modal-close-button { - position: absolute; - top: var(--sp-s); - right: var(--sp-s); + @extend .modal-close-btn-base; } .modal-content { @@ -76,6 +74,18 @@ } } +.copy-button { + @extend .button-secondary; + @include deprecated.flexRow; + gap: deprecated.$s-8; + height: deprecated.$s-32; + width: deprecated.$s-28; + svg { + @extend .button-icon; + stroke: var(--icon-foreground-hover); + } +} + .description { @include deprecated.bodySmallTypography; color: var(--modal-text-foreground-color); @@ -87,6 +97,18 @@ justify-content: flex-end; } +.button-active { + @extend .modal-accept-btn; +} + +.button-cancel { + @extend .modal-cancel-btn; +} + +.button-danger { + @extend .modal-danger-btn; +} + .permissions-section { @include deprecated.flexColumn; gap: deprecated.$s-8; diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index 8abd50ba06..3e930e9f81 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -25,11 +25,10 @@ [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] - [app.main.ui.components.file-uploader :refer [file-uploader*]] + [app.main.ui.components.file-uploader :refer [file-uploader]] [app.main.ui.components.numeric-input :refer [numeric-input*]] + [app.main.ui.components.radio-buttons :refer [radio-buttons radio-button]] [app.main.ui.components.select :refer [select]] - [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]] [app.main.ui.hooks :as hooks] @@ -416,25 +415,24 @@ :on-change handle-change-mode}]]) (when (and (= origin :sidebar) show-tokens? token-color) - [:> radio-buttons* {:selected color-style - :on-change toggle-token-color - :name "color-style" - :options [{:id "swap-opt-list" - :icon i/swatches - :label (tr "labels.color") - :value :direct-color} - {:id "swap-opt-grid" - :icon i/tokens - :label (tr "workspace.colorpicker.color-tokens") - :value :token-color}]}])] + [:& radio-buttons {:selected color-style + :on-change toggle-token-color + :name "color-style"} + [:& radio-button {:icon i/swatches + :value :direct-color + :title (tr "labels.color") + :id "opt-color"}] + [:& radio-button {:icon i/tokens + :value :token-color + :title (tr "workspace.colorpicker.color-tokens") + :id "opt-token-color"}]])] (when (and (not= selected-mode :image) (= color-style :direct-color)) - [:> icon-button* {:variant "ghost" - :aria-label (tr "workspace.colorpicker.get-color") - :aria-pressed picking-color? - :on-click handle-click-picker - :icon i/picker}]) + [:button {:class (stl/css-case :picker-btn true + :selected picking-color?) + :on-click handle-click-picker} + deprecated-icon/picker]) (when (= color-style :token-color) [:div {:class (stl/css :token-color-title)} @@ -485,11 +483,12 @@ :aria-label (tr "media.choose-image") :on-click on-fill-image-click} (tr "media.choose-image") - [:> file-uploader* {:input-id "fill-image-upload" - :accept "image/jpeg,image/png" - :multi false - :ref fill-image-ref - :on-selected on-fill-image-selected}]]]) + [:& file-uploader + {:input-id "fill-image-upload" + :accept "image/jpeg,image/png" + :multi false + :ref fill-image-ref + :on-selected on-fill-image-selected}]]]) [:* [:div {:class (stl/css :colorpicker-tabs)} diff --git a/frontend/src/app/main/ui/workspace/colorpicker.scss b/frontend/src/app/main/ui/workspace/colorpicker.scss index d50ed0002c..1d7e303d41 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.scss +++ b/frontend/src/app/main/ui/workspace/colorpicker.scss @@ -46,6 +46,52 @@ width: px2rem(68); } +// TODO: change to DS button component +.picker-btn { + display: flex; + justify-content: center; + align-items: center; + border: none; + background: none; + cursor: pointer; + border-radius: $br-8; + background-color: transparent; + border: $b-1 solid transparent; + height: var(--sp-xl); + width: var(--sp-xl); + border-radius: $br-4; + padding: 0; + margin-top: var(--sp-xs); + svg { + @extend .button-icon; + stroke: var(--button-tertiary-foreground-color-rest); + } + &:hover { + svg { + stroke: var(--button-tertiary-foreground-color-focus); + } + } + &:focus, + &:focus-visible { + outline: none; + svg { + stroke: var(--button-secondary-foreground-color-hover); + } + } + &:active { + outline: none; + border: $b-1 solid transparent; + svg { + stroke: var(--button-tertiary-foreground-color-active); + } + } + &.selected { + svg { + stroke: var(--button-tertiary-foreground-color-active); + } + } +} + .gradient-buttons { display: flex; align-items: center; diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index bede05c92c..18fd87e7c8 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -30,7 +30,6 @@ [app.main.ui.components.search-bar :refer [search-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.context :as ctx] - [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]] @@ -45,6 +44,12 @@ [cuerdas.core :as str] [rumext.v2 :as mf])) +(def ^:private close-icon + (deprecated-icon/icon-xref :close (stl/css :close-icon))) + +(def ^:private add-icon + (deprecated-icon/icon-xref :add (stl/css :add-icon))) + (defn- get-library-summary "Given a library data return a summary representation of this library" [data] @@ -163,10 +168,12 @@ [:div {:class (stl/css :sample-library-item) :key (dm/str id)} [:div {:class (stl/css :sample-library-item-name)} (:name library)] - [:> button* {:variant "secondary" - :on-click import-library - :disabled (some? importing?)} - (if (= importing? id) (tr "labels.adding") (tr "labels.add"))]])) + [:input {:class (stl/css-case :sample-library-button true + :sample-library-add (nil? importing?) + :sample-library-adding (some? importing?)) + :type "button" + :value (if (= importing? id) (tr "labels.adding") (tr "labels.add")) + :on-click import-library}]])) (defn- empty-library? "Check if currentt library summary has elements or not" @@ -315,12 +322,14 @@ [:> library-description* {:summary summary}]]] (if ^boolean is-shared - [:> button* {:variant "secondary" - :on-click unpublish} - (tr "common.unpublish")] - [:> button* {:variant "primary" - :on-click publish} - (tr "common.publish")])] + [:input {:class (stl/css :item-unpublish) + :type "button" + :value (tr "common.unpublish") + :on-click unpublish}] + [:input {:class (stl/css :item-publish) + :type "button" + :value (tr "common.publish") + :on-click publish}])] (for [{:keys [id name data connected-to connected-to-names] :as library} linked-libraries] (let [disabled? (some #(contains? linked-libraries-ids %) connected-to)] @@ -368,11 +377,12 @@ (let [summary (-> (:library-summary library) (adapt-backend-summary))] [:> library-description* {:summary summary}])]] - [:> icon-button* {:variant "secondary" - :aria-label (tr "workspace.libraries.shared-library-btn") - :icon i/add - :data-library-id (dm/str id) - :on-click link-library}]])] + + [:button {:class (stl/css :item-button-shared) + :data-library-id (dm/str id) + :title (tr "workspace.libraries.shared-library-btn") + :on-click link-library} + add-icon]])] (when (empty? shared-libraries) [:div {:class (stl/css :section-list-empty)} @@ -637,13 +647,11 @@ :on-click close-dialog-outside :data-testid "libraries-modal"} [:div {:class (stl/css :modal-dialog)} - [:> icon-button* {:variant "ghost" - :class (stl/css :close-btn) - :icon i/close - :aria-label (tr "labels.close") - :data-testid "close-libraries" - :on-click close-dialog}] - + [:button {:class (stl/css :close-btn) + :on-click close-dialog + :aria-label (tr "labels.close") + :data-testid "close-libraries"} + close-icon] [:div {:class (stl/css :modal-title)} (tr "workspace.libraries.libraries")] diff --git a/frontend/src/app/main/ui/workspace/libraries.scss b/frontend/src/app/main/ui/workspace/libraries.scss index 46a7edca7f..9776c08bad 100644 --- a/frontend/src/app/main/ui/workspace/libraries.scss +++ b/frontend/src/app/main/ui/workspace/libraries.scss @@ -33,7 +33,7 @@ background-color: var(--modal-background-color); border: $b-2 solid var(--modal-border-color); display: grid; - grid-template-rows: 0 auto 1fr; + grid-template-rows: auto 1fr; min-width: $sz-364; min-height: $sz-192; height: $sz-520; @@ -42,10 +42,21 @@ max-width: $sz-712; } +// TODO: Remove this extended creating modal component .close-btn { - position: absolute; - top: var(--sp-s); - right: var(--sp-s); + @extend .modal-close-btn-base; +} + +.close-icon { + display: flex; + justify-content: center; + align-items: center; + height: $sz-16; + width: $sz-16; + color: transparent; + fill: none; + stroke-width: $b-1; + stroke: var(--icon-foreground); } .modal-title { @@ -109,6 +120,46 @@ height: fit-content; } +.item-publish, +.item-unpublish { + // TODO: remove this extended by using DS button component + @extend .button-primary; + @include t.use-typography("headline-small"); + height: $sz-32; + min-width: px2rem(92); + padding: var(--sp-s) var(--sp-xxl); + margin: 0; + border-radius: $br-8; +} + +.item-unpublish { + // TODO: remove this extended by using DS button component + @extend .button-secondary; +} + +.item-button, +.item-button-shared { + // TODO: remove this extended by using DS button component + @extend .button-secondary; + height: $sz-32; + width: $sz-32; + margin-inline-start: var(--sp-xxs); + padding: var(--sp-s); +} + +.detach-icon, +.add-icon { + display: flex; + justify-content: center; + align-items: center; + height: $sz-16; + width: $sz-16; + color: transparent; + fill: none; + stroke-width: $b-1; + stroke: var(--icon-foreground); +} + .section-list-shared { max-height: px2rem(272); } @@ -119,6 +170,26 @@ color: var(--title-foreground-color); } +.search-icon { + display: flex; + justify-content: center; + align-items: center; + width: px2rem(20); + padding: 0 0 0 var(--sp-s); + + svg { + display: flex; + justify-content: center; + align-items: center; + color: transparent; + fill: none; + height: px2rem(12); + width: px2rem(12); + stroke-width: 1.33px; + stroke: var(--icon-foreground); + } +} + // empty state .section-list-empty { display: grid; @@ -357,3 +428,24 @@ text-overflow: ellipsis; max-width: px2rem(232); } + +// TODO: Remove this extended using a DS component +.sample-library-add { + @extend .button-secondary; +} + +// TODO: Remove this extended using a DS component +.sample-library-adding { + @extend .button-disabled; +} + +.sample-library-button { + @include t.use-typography("headline-small"); + height: $sz-32; + width: px2rem(80); + margin: 0; + border-radius: $br-8; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/frontend/src/app/main/ui/workspace/main_menu.cljs b/frontend/src/app/main/ui/workspace/main_menu.cljs index 226d0d0233..a964d27475 100644 --- a/frontend/src/app/main/ui/workspace/main_menu.cljs +++ b/frontend/src/app/main/ui/workspace/main_menu.cljs @@ -853,9 +853,8 @@ [:* [:> icon-button* {:variant "ghost" - :aria-pressed show-menu? :aria-label (tr "shortcut-subsection.main-menu") - :on-click (if show-menu? close-all-menus open-menu) + :on-click open-menu :icon i/menu}] [:> dropdown-menu* {:show show-menu? diff --git a/frontend/src/app/main/ui/workspace/palette.cljs b/frontend/src/app/main/ui/workspace/palette.cljs index dd219410a8..80c396989e 100644 --- a/frontend/src/app/main/ui/workspace/palette.cljs +++ b/frontend/src/app/main/ui/workspace/palette.cljs @@ -18,10 +18,9 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.context :as ctx] - [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.hooks :as h] [app.main.ui.hooks.resize :as r] + [app.main.ui.icons :as deprecated-icon] [app.main.ui.workspace.color-palette :refer [color-palette*]] [app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu*]] [app.main.ui.workspace.text-palette :refer [text-palette]] @@ -179,27 +178,27 @@ [:ul {:class (dm/str size-classname " " (stl/css-case :palette-btn-list true :hidden-bts hide-palettes?))} [:li {:class (stl/css :palette-item)} - [:> icon-button* {:variant "ghost" - :aria-pressed (some? color-palette?) - :aria-label (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette)) - :on-click on-select-color-palette - :icon i/drop}]] + [:button {:title (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette)) + :aria-label (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette)) + :class (stl/css-case :palette-btn true + :selected color-palette?) + :on-click on-select-color-palette} + deprecated-icon/drop-icon]] + [:li {:class (stl/css :palette-item)} - [:> icon-button* {:variant "ghost" - :aria-pressed (some? text-palette?) - :aria-label (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette)) - :on-click on-select-text-palette - :icon i/text-palette}]]] + [:button {:title (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette)) + :aria-label (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette)) + :class (stl/css-case :palette-btn true + :selected text-palette?) + :on-click on-select-text-palette} + deprecated-icon/text-palette]]] + (if any-palette? [:* - [:div {:class (stl/css :menu-btn)} - [:> icon-button* {:variant "ghost" - :aria-pressed show-menu? - :aria-label (tr "labels.options") - :on-click #(swap! state* update :show-menu not) - :icon i/menu}]] - + [:button {:class (stl/css :palette-actions) + :on-click #(swap! state* update :show-menu not)} + deprecated-icon/menu] [:div {:class (stl/css :palette) :ref container} (when text-palette? diff --git a/frontend/src/app/main/ui/workspace/palette.scss b/frontend/src/app/main/ui/workspace/palette.scss index dbdef2a6b2..7dc42ffc37 100644 --- a/frontend/src/app/main/ui/workspace/palette.scss +++ b/frontend/src/app/main/ui/workspace/palette.scss @@ -49,6 +49,7 @@ &.wide { width: 100%; } + .resize-area { grid-area: resize; height: deprecated.$s-8; @@ -71,22 +72,49 @@ &.small-palette { display: flex; } + .palette-item { + @include deprecated.flexCenter; + border-radius: deprecated.$br-8; + opacity: deprecated.$op-10; + transition: opacity 1s ease; + .palette-btn { + @extend .button-tertiary; + height: deprecated.$s-32; + width: deprecated.$s-32; + border-radius: deprecated.$br-8; + background-clip: padding-box; + padding: 0; + svg { + @extend .button-icon-small; + stroke: var(--icon-foreground); + } + &.selected { + @extend .button-icon-selected; + } + } + } + } + + .palette-actions { + @extend .button-tertiary; + grid-area: actions; + height: calc(var(--height) - deprecated.$s-16); + width: deprecated.$s-32; + padding: 0; + margin-left: deprecated.$s-4; + border-radius: deprecated.$br-8; + background-color: var(--palette-background-color); + z-index: deprecated.$z-index-2; + svg { + @extend .button-icon; + stroke: var(--icon-foreground); + } } .palette { grid-area: palette; width: 100%; min-width: 0; } - .palette-item { - display: flex; - align-items: center; - } -} - -.menu-btn { - display: flex; - align-items: center; - margin-left: var(--sp-s); } .handler { diff --git a/frontend/src/app/main/ui/workspace/presence.cljs b/frontend/src/app/main/ui/workspace/presence.cljs index d7bcda046f..38302ed536 100644 --- a/frontend/src/app/main/ui/workspace/presence.cljs +++ b/frontend/src/app/main/ui/workspace/presence.cljs @@ -29,7 +29,7 @@ :style {:background-color color} :src (cfg/resolve-profile-photo-url profile)}]])) -(mf/defc active-sessions* +(mf/defc active-sessions {::mf/memo true} [] (let [profiles (mf/deref refs/profiles) diff --git a/frontend/src/app/main/ui/workspace/right_header.cljs b/frontend/src/app/main/ui/workspace/right_header.cljs index b9867ea6b2..ce10de99cf 100644 --- a/frontend/src/app/main/ui/workspace/right_header.cljs +++ b/frontend/src/app/main/ui/workspace/right_header.cljs @@ -20,19 +20,23 @@ [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.context :as ctx] [app.main.ui.dashboard.team] - [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.foundations.assets.icon :as i] - [app.main.ui.exports.assets :refer [progress-widget*]] + [app.main.ui.exports.assets :refer [progress-widget]] [app.main.ui.formats :as fmt] - [app.main.ui.workspace.presence :refer [active-sessions*]] + [app.main.ui.icons :as deprecated-icon] + [app.main.ui.workspace.presence :refer [active-sessions]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] + [okulary.core :as l] [rumext.v2 :as mf])) +(def ref:persistence-status + (l/derived :status refs/persistence)) + ;; --- Zoom Widget -(mf/defc zoom-widget-workspace* +(mf/defc zoom-widget-workspace {::mf/wrap [mf/memo] ::mf/wrap-props false} [{:keys [zoom on-increase on-decrease on-zoom-reset on-zoom-fit on-zoom-selected]}] @@ -68,12 +72,11 @@ zoom (fmt/format-percent zoom {:precision 0})] [:* - [:div {:on-click (if open? close-dropdown open-dropdown) + [:div {:on-click open-dropdown :class (stl/css-case :zoom-widget true :selected open?) :title (tr "workspace.header.zoom")} [:span {:class (stl/css :label)} zoom]] - [:& dropdown {:show open? :on-close close-dropdown} [:ul {:class (stl/css :dropdown)} [:li {:class (stl/css :basic-zoom-bar)} @@ -87,10 +90,9 @@ :aria-label (tr "shortcuts.increase-zoom") :on-click on-increase :icon i/add}]] - [:> button* {:variant "ghost" - :on-click on-zoom-reset} + [:button {:class (stl/css :reset-btn) + :on-click on-zoom-reset} (tr "workspace.header.reset-zoom")]] - [:li {:class (stl/css :zoom-option) :on-click on-zoom-fit} (tr "workspace.header.zoom-fit-all") @@ -98,7 +100,6 @@ (for [sc (scd/split-sc (sc/get-tooltip :fit-all))] [:span {:class (stl/css :shortcut-key) :key (str "zoom-fit-" sc)} sc])]] - [:li {:class (stl/css :zoom-option) :on-click on-zoom-selected} (tr "workspace.header.zoom-selected") @@ -197,43 +198,51 @@ [:div {:class (stl/css :workspace-header-right)} [:div {:class (stl/css :users-section)} - [:> active-sessions*]] + [:& active-sessions]] - [:> progress-widget*] + [:& progress-widget] [:div {:class (stl/css :separator)}] [:div {:class (stl/css :zoom-section)} - [:> zoom-widget-workspace* {:zoom zoom - :on-increase on-increase - :on-decrease on-decrease - :on-zoom-reset on-zoom-reset - :on-zoom-fit on-zoom-fit - :on-zoom-selected on-zoom-selected}]] + [:& zoom-widget-workspace + {:zoom zoom + :on-increase on-increase + :on-decrease on-decrease + :on-zoom-reset on-zoom-reset + :on-zoom-fit on-zoom-fit + :on-zoom-selected on-zoom-selected}]] - [:div {:class (stl/css :comments-button-wrapper)} - [:> icon-button* {:variant "ghost" - :aria-pressed (= selected-drawtool :comments) - :aria-label (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment)) - :on-click toggle-comments - :icon i/comments}] - (when ^boolean has-unread-comments? - [:div {:class (stl/css :unread)}])] + [:div {:class (stl/css :comments-section)} + [:button {:title (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment)) + :aria-label (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment)) + :class (stl/css-case :comments-btn true + :selected (= selected-drawtool :comments)) + :on-click toggle-comments + :data-tool "comments" + :style {:position "relative"}} + deprecated-icon/comments + (when ^boolean has-unread-comments? + [:div {:class (stl/css :unread)}])]] (when-not ^boolean read-only? - [:> icon-button* {:variant "ghost" - :aria-pressed (contains? layout :document-history) - :aria-label (tr "workspace.sidebar.history") - :on-click toggle-history - :icon i/history}]) + [:div {:class (stl/css :history-section)} + [:button + {:title (tr "workspace.sidebar.history") + :aria-label (tr "workspace.sidebar.history") + :class (stl/css-case :selected (contains? layout :document-history) + :history-button true) + :on-click toggle-history} + deprecated-icon/history]]) (when display-share-button? - [:> icon-button* {:variant "ghost" - :aria-label (tr "workspace.header.share") - :on-click open-share-dialog - :icon i/to-corner}]) + [:a {:class (stl/css :viewer-btn) + :title (tr "workspace.header.share") + :on-click open-share-dialog} + deprecated-icon/share]) + + [:a {:class (stl/css :viewer-btn) + :title (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer)) + :on-click nav-to-viewer} + deprecated-icon/play]])) - [:> icon-button* {:variant "ghost" - :aria-label (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer)) - :on-click nav-to-viewer - :icon i/play}]])) diff --git a/frontend/src/app/main/ui/workspace/right_header.scss b/frontend/src/app/main/ui/workspace/right_header.scss index e49c314ef6..e6d7ea2092 100644 --- a/frontend/src/app/main/ui/workspace/right_header.scss +++ b/frontend/src/app/main/ui/workspace/right_header.scss @@ -11,8 +11,8 @@ justify-content: space-between; align-items: center; min-width: deprecated.$s-256; - padding: deprecated.$s-8 deprecated.$s-12; - gap: deprecated.$s-4; + padding: deprecated.$s-8; + gap: deprecated.$s-8; background-color: var(--panel-background-color); } @@ -28,14 +28,19 @@ } .zoom-widget { + @include deprecated.buttonStyle; display: flex; align-items: center; justify-content: center; + height: deprecated.$s-28; + max-width: deprecated.$s-48; width: deprecated.$s-48; - height: deprecated.$s-32; + border-radius: deprecated.$br-8; .label { @include deprecated.bodySmallTypography; + height: 100%; + padding: deprecated.$s-8 0; color: var(--button-tertiary-foreground-color-rest); } @@ -79,6 +84,13 @@ color: var(--modal-title-foreground-color); } +.reset-btn { + @extend .button-tertiary; + color: var(--button-tertiary-foreground-color-hover); + height: deprecated.$s-28; + border-radius: deprecated.$br-8; +} + .zoom-option { @extend .menu-item-base; @@ -101,11 +113,127 @@ } } -.comments-button-wrapper { - position: relative; +.comments-btn { + @extend .button-tertiary; + border-radius: deprecated.$br-8; + margin: 0; + height: deprecated.$s-28; + width: deprecated.$s-28; + border: none; + + svg { + @extend .button-icon; + stroke: var(--icon-foreground); + height: deprecated.$s-16; + width: deprecated.$s-16; + } + + &:hover { + background-color: transparent; + border: none; + } + + &.selected { + background-color: var(--button-tertiary-background-color-selected); + + svg { + stroke: var(--button-tertiary-foreground-color-active); + } + } } -.comments-button-unread { +.history-button { + @extend .button-tertiary; + border-radius: deprecated.$br-8; + margin: 0; + height: deprecated.$s-28; + width: deprecated.$s-28; + border: none; + + svg { + @extend .button-icon; + stroke: var(--icon-foreground); + height: deprecated.$s-16; + width: deprecated.$s-16; + } + + &:hover { + background-color: transparent; + border: none; + } + + &.selected { + background-color: var(--button-tertiary-background-color-selected); + + svg { + stroke: var(--button-tertiary-foreground-color-active); + } + } +} + +.persistence-status-widget { + @include deprecated.flexCenter; + width: deprecated.$s-28; + height: deprecated.$s-28; +} + +.status-icon { + @include deprecated.flexCenter; + width: deprecated.$s-24; + height: deprecated.$s-24; + margin: 0; + border-radius: deprecated.$br-circle; + + svg { + @extend .button-icon; + stroke: var(--status-widget-icon-foreground-color); + } +} + +.pending-status { + background-color: var(--status-widget-background-color-warning); +} + +.saving-status { + background-color: var(--status-widget-background-color-pending); + + svg { + animation: spin-animation 1s infinite; + animation-timing-function: linear; + } +} + +.saved-status { + background-color: var(--status-widget-background-color-success); +} + +.error-status { + background-color: var(--status-widget-background-color-error); +} + +.share-btn, +.viewer-btn { + @extend .button-tertiary; + border-radius: deprecated.$br-8; + margin: 0; + width: deprecated.$s-28; + height: deprecated.$s-28; + border: none; + + svg { + @extend .button-icon; + height: deprecated.$s-16; + width: deprecated.$s-16; + stroke: var(--icon-foreground); + } + + &:hover { + background-color: transparent; + border: none; + } +} + +.unread { position: absolute; width: 8px; height: 8px; diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 482393e286..d899f20d67 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -17,9 +17,8 @@ [app.main.ui.components.context-menu-a11y :refer [context-menu*]] [app.main.ui.components.search-bar :refer [search-bar*]] [app.main.ui.context :as ctx] - [app.main.ui.ds.buttons.button :refer [button*]] [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.sidebar.assets.common :as cmm] [app.main.ui.workspace.sidebar.assets.file-library :refer [file-library*]] [app.util.dom :as dom] @@ -162,40 +161,43 @@ :id "typographies" :handler on-section-filter-change}])] - [:article {:class (stl/css :assets-bar)} + [:article {:class (stl/css :assets-bar)} [:div {:class (stl/css :assets-header)} (when-not ^boolean read-only? (if (and (= num-libs 1) (empty? components)) - [:> button* {:variant "primary" - :on-click show-libraries-dialog - :data-testid "libraries"} + [:button {:class (stl/css :add-library-button) + :on-click show-libraries-dialog + :data-testid "libraries"} (tr "workspace.assets.add-library")] - [:> button* {:variant "secondary" - :on-click show-libraries-dialog - :data-testid "libraries"} + + [:button {:class (stl/css :libraries-button) + :on-click show-libraries-dialog + :data-testid "libraries"} (tr "workspace.assets.manage-library")])) + [:div {:class (stl/css :search-wrapper)} [:> search-bar* {:on-change on-search-term-change :value term :placeholder (tr "workspace.assets.search")} - [:> icon-button* {:variant "secondary" - :icon i/filter - :class (stl/css :filter-button) - :aria-pressed menu-open? - :aria-label (tr "workspace.assets.filter") - :on-click on-open-menu}]] + [:button + {:on-click on-open-menu + :title (tr "workspace.assets.filter") + :class (stl/css-case :section-button true + :opened menu-open?)} + deprecated-icon/filter-icon]] - [:> context-menu* {:on-close on-menu-close - :selectable true - :selected section - :show menu-open? - :fixed true - :min-width true - :width size - :top 158 - :left 18 - :options options}] + [:> context-menu* + {:on-close on-menu-close + :selectable true + :selected section + :show menu-open? + :fixed true + :min-width true + :width size + :top 158 + :left 18 + :options options}] [:> icon-button* {:variant "ghost" :aria-label (tr "workspace.assets.sort") diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.scss b/frontend/src/app/main/ui/workspace/sidebar/assets.scss index 53cbc98e0e..f89069cca5 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.scss @@ -17,14 +17,89 @@ padding-top: deprecated.$s-8; } -.assets-header { - display: flex; - flex-direction: column; - gap: var(--sp-xxs); +.libraries-button { + @extend .button-secondary; + @include deprecated.uppercaseTitleTipography; + gap: deprecated.$s-2; + height: deprecated.$s-32; + width: 100%; + margin-bottom: deprecated.$s-4; + border-radius: deprecated.$s-8; + + &:hover { + background-color: var(--button-secondary-background-color-hover); + color: var(--button-secondary-foreground-color-hover); + border: deprecated.$s-1 solid var(--button-secondary-border-color-hover); + } + + &:focus { + background-color: var(--button-secondary-background-color-focus); + color: var(--button-secondary-foreground-color-focus); + border: deprecated.$s-1 solid var(--button-secondary-border-color-focus); + } } -.filter-button { - border-radius: deprecated.$br-8 0 0 deprecated.$br-8; +.add-library-button { + @extend .button-primary; + @include deprecated.uppercaseTitleTipography; + gap: deprecated.$s-2; + height: deprecated.$s-32; + width: 100%; + margin-bottom: deprecated.$s-4; + border-radius: deprecated.$s-8; +} + +.section-button { + @include deprecated.flexCenter; + @include deprecated.buttonStyle; + height: deprecated.$s-32; + width: deprecated.$s-32; + margin: 0; + border: deprecated.$s-1 solid var(--input-border-color-rest); + border-radius: deprecated.$br-8 deprecated.$br-2 deprecated.$br-2 deprecated.$br-8; + background-color: var(--input-background-color-rest); + + svg { + height: deprecated.$s-16; + width: deprecated.$s-16; + stroke: var(--icon-foreground); + } + + &:focus { + border: deprecated.$s-1 solid var(--input-border-color-focus); + outline: 0; + background-color: var(--input-background-color-focus); + color: var(--input-foreground-color-focus); + + svg { + background-color: var(--input-background-color-focus); + } + } + + &:hover { + border: deprecated.$s-1 solid var(--input-border-color-hover); + background-color: var(--input-background-color-hover); + + svg { + background-color: var(--input-background-color-hover); + stroke: var(--button-foreground-hover); + } + + &:focus { + border: deprecated.$s-1 solid var(--input-border-color-focus); + outline: 0; + background-color: var(--input-background-color-focus); + color: var(--input-foreground-color-focus); + + svg { + background-color: var(--input-background-color-focus); + } + } + } + + &.opened { + @extend .button-icon-selected; + } } .sections-container { @@ -50,6 +125,10 @@ border-radius: deprecated.$br-8; } +.section-btn { + @include deprecated.buttonStyle; +} + .assets-header { padding: 0 0 deprecated.$s-24 deprecated.$s-12; } diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs index 9aa485d5eb..077742d71d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs @@ -22,10 +22,10 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.editable-label :refer [editable-label*]] - [app.main.ui.components.file-uploader :refer [file-uploader*]] + [app.main.ui.components.file-uploader :refer [file-uploader]] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.context :as ctx] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] [app.main.ui.hooks :as h] [app.main.ui.workspace.sidebar.assets.common :as cmm] @@ -563,27 +563,27 @@ [:> cmm/asset-section-block* {:role :title-button} (when ^boolean is-open [:div - [:> radio-buttons* {:selected (if is-listing-thumbs "grid" "list") - :on-change toggle-list-style - :name "listing-style" - :options [{:id "opt-list" - :icon i/view-as-list - :label (tr "workspace.assets.list-view") - :value "list"} - {:id "opt-grid" - :icon i/flex-grid - :label (tr "workspace.assets.grid-view") - :value "grid"}]}]]) + [:& radio-buttons {:selected (if is-listing-thumbs "grid" "list") + :on-change toggle-list-style + :name "listing-style"} + [:& radio-button {:icon i/view-as-list + :value "list" + :title (tr "workspace.assets.list-view") + :id "opt-list"}] + [:& radio-button {:icon i/flex-grid + :value "grid" + :title (tr "workspace.assets.grid-view") + :id "opt-grid"}]]]) (when (and (not read-only?) is-local) [:> icon-button* {:variant "ghost" :aria-label (tr "workspace.assets.components.add-component") :on-click add-component :icon i/add} - [:> file-uploader* {:accept dwm/accept-image-types - :multi true - :ref input-ref - :on-selected on-file-selected}]])] + [:& file-uploader {:accept dwm/accept-image-types + :multi true + :ref input-ref + :on-selected on-file-selected}]])] [:> cmm/asset-section-block* {:role :content} (when ^boolean is-open diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs index 5d29117036..8ad40c2f4e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs @@ -23,7 +23,7 @@ [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.workspace.sidebar.assets.common :as cmm] [app.main.ui.workspace.sidebar.assets.groups :as grp] - [app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry*]] + [app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [cuerdas.core :as str] @@ -113,17 +113,18 @@ :on-drag-over dom/prevent-default :on-drop on-drop} - [:> typography-entry* {:file-id file-id - :typography typography - :local? local? - :selected? (contains? selected typography-id) - :on-click on-asset-click - :on-change handle-change - :on-context-menu on-context-menu - :editing? editing? - :renaming? renaming? - :focus-name? rename? - :external-open* open*}] + [:& typography-entry + {:file-id file-id + :typography typography + :local? local? + :selected? (contains? selected typography-id) + :on-click on-asset-click + :on-change handle-change + :on-context-menu on-context-menu + :editing? editing? + :renaming? renaming? + :focus-name? rename? + :external-open* open*}] (when ^boolean dragging? [:div {:class (stl/css :dragging)}])])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/layers.cljs b/frontend/src/app/main/ui/workspace/sidebar/layers.cljs index 282eca00e8..dabe7aae77 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/layers.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/layers.cljs @@ -291,12 +291,13 @@ :value current-search :on-clear clear-search-text :placeholder (tr "workspace.sidebar.layers.search")} - [:> icon-button* {:variant "secondary" - :class (stl/css :filter-button) - :aria-pressed show-menu? - :aria-label (tr "workspace.sidebar.layers.filter") - :on-click on-toggle-filters-click - :icon i/filter}]] + [:button {:on-click on-toggle-filters-click + :class (stl/css-case + :filter-button true + :opened show-menu? + :active active?)} + [:> icon* {:icon-id i/filter}]]] + [:> icon-button* {:variant "ghost" :aria-label (tr "labels.close") :on-click toggle-search diff --git a/frontend/src/app/main/ui/workspace/sidebar/layers.scss b/frontend/src/app/main/ui/workspace/sidebar/layers.scss index 9a008fb94a..e89f730323 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/layers.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/layers.scss @@ -19,7 +19,39 @@ padding: 0 deprecated.$s-12 0 deprecated.$s-8; gap: deprecated.$s-4; .filter-button { - border-radius: deprecated.$br-8 0 0 deprecated.$br-8; + @include deprecated.flexCenter; + @include deprecated.buttonStyle; + height: deprecated.$s-32; + width: deprecated.$s-32; + margin: 0; + border: deprecated.$s-1 solid var(--color-background-tertiary); + border-radius: deprecated.$br-8 deprecated.$br-2 deprecated.$br-2 deprecated.$br-8; + background-color: var(--color-background-tertiary); + svg { + height: deprecated.$s-16; + width: deprecated.$s-16; + stroke: var(--icon-foreground); + } + &:focus { + border: deprecated.$s-1 solid var(--input-border-color-focus); + outline: 0; + background-color: var(--input-background-color-active); + color: var(--input-foreground-color-active); + svg { + background-color: var(--input-background-color-active); + } + } + &:hover { + border: deprecated.$s-1 solid var(--input-border-color-hover); + background-color: var(--input-background-color-hover); + svg { + background-color: var(--input-background-color-hover); + stroke: var(--button-foreground-hover); + } + } + &.opened { + @extend .button-icon-selected; + } } } } @@ -111,7 +143,7 @@ .filters-container { @extend .menu-dropdown; position: absolute; - left: deprecated.$s-16; + left: deprecated.$s-20; width: deprecated.$s-192; .filter-menu-item { @include deprecated.bodySmallTypography; diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs index 7bebe451b3..275ad11e8d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs @@ -12,7 +12,7 @@ [app.main.data.workspace.drawing :as dwd] [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.icons :as deprecated-icon] [app.util.dom :as dom] @@ -95,15 +95,15 @@ (when preset-match [:span {:class (stl/css :check-icon)} deprecated-icon/tick])])))]]] - [:> radio-buttons* {:class (stl/css :radio-buttons) - :selected (or (d/name orientation) "") - :on-change on-orientation-change - :name "frame-orientation" - :options [{:id "size-vertical" - :icon i/size-vertical - :label (tr "workspace.options.orientation.vertical") - :value "vertical"} - {:id "size-horizontal" - :icon i/size-horizontal - :label (tr "workspace.options.orientation.horizontal") - :value "horizontal"}]}]])) + [:& radio-buttons {:selected (or (d/name orientation) "") + :on-change on-orientation-change + :name "frame-orientation" + :wide true + :class (stl/css :radio-buttons)} + [:& radio-button {:icon i/size-vertical + :value "vertical" + :id "size-vertical"}] + [:& radio-button {:icon i/size-horizontal + :value "horizontal" + :id "size-horizontal"}]]])) + diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.cljs index aeb1fb8c60..4cf1c6efc4 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.cljs @@ -10,8 +10,7 @@ [app.main.data.workspace :as dw] [app.main.data.workspace.shortcuts :as sc] [app.main.store :as st] - [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.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) @@ -43,59 +42,68 @@ (when-not (and disabled-align disabled-distribute) [:div {:class (stl/css :align-options)} [:div {:class (stl/css :align-group-horizontal)} - [:> icon-button* {:variant "ghost" - :icon i/align-left - :aria-label (tr "workspace.align.hleft" (sc/get-tooltip :align-left)) - :on-click align-objects - :data-value "hleft" - :disabled disabled-align}] + [:button {:class (stl/css-case :align-button true + :disabled disabled-align) + :disabled disabled-align + :title (tr "workspace.align.hleft" (sc/get-tooltip :align-left)) + :data-value "hleft" + :on-click align-objects} + deprecated-icon/align-left] - [:> icon-button* {:variant "ghost" - :icon i/align-horizontal-center - :aria-label (tr "workspace.align.hcenter" (sc/get-tooltip :align-hcenter)) - :on-click align-objects - :data-value "hcenter" - :disabled disabled-align}] + [:button {:class (stl/css-case :align-button true + :disabled disabled-align) + :disabled disabled-align + :title (tr "workspace.align.hcenter" (sc/get-tooltip :align-hcenter)) + :data-value "hcenter" + :on-click align-objects} + deprecated-icon/align-horizontal-center] - [:> icon-button* {:variant "ghost" - :icon i/align-right - :aria-label (tr "workspace.align.hright" (sc/get-tooltip :align-right)) - :on-click align-objects - :data-value "hright" - :disabled disabled-align}] + [:button {:class (stl/css-case :align-button true + :disabled disabled-align) + :disabled disabled-align + :title (tr "workspace.align.hright" (sc/get-tooltip :align-right)) + :data-value "hright" + :on-click align-objects} + deprecated-icon/align-right] - [:> icon-button* {:variant "ghost" - :icon i/distribute-horizontally - :aria-label (tr "workspace.align.hdistribute" (sc/get-tooltip :h-distribute)) - :on-click distribute-objects - :data-value "horizontal" - :disabled disabled-distribute}]] + [:button {:class (stl/css-case :align-button true + :disabled disabled-distribute) + :disabled disabled-distribute + :title (tr "workspace.align.hdistribute" (sc/get-tooltip :h-distribute)) + :data-value "horizontal" + :on-click distribute-objects} + deprecated-icon/distribute-horizontally]] [:div {:class (stl/css :align-group-vertical)} - [:> icon-button* {:variant "ghost" - :icon i/align-top - :aria-label (tr "workspace.align.vtop" (sc/get-tooltip :align-top)) - :on-click align-objects - :data-value "vtop" - :disabled disabled-align}] + [:button {:class (stl/css-case :align-button true + :disabled disabled-align) + :disabled disabled-align + :title (tr "workspace.align.vtop" (sc/get-tooltip :align-top)) + :data-value "vtop" + :on-click align-objects} + deprecated-icon/align-top] - [:> icon-button* {:variant "ghost" - :icon i/align-vertical-center - :aria-label (tr "workspace.align.vcenter" (sc/get-tooltip :align-vcenter)) - :on-click align-objects - :data-value "vcenter" - :disabled disabled-align}] + [:button {:class (stl/css-case :align-button true + :disabled disabled-align) + :disabled disabled-align + :title (tr "workspace.align.vcenter" (sc/get-tooltip :align-vcenter)) + :data-value "vcenter" + :on-click align-objects} + deprecated-icon/align-vertical-center] - [:> icon-button* {:variant "ghost" - :icon i/align-bottom - :aria-label (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom)) - :on-click align-objects - :data-value "vbottom" - :disabled disabled-align}] + [:button {:class (stl/css-case :align-button true + :disabled disabled-align) + :disabled disabled-align + :title (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom)) + :data-value "vbottom" + :on-click align-objects} + deprecated-icon/align-bottom] + + [:button {:title (tr "workspace.align.vdistribute" (sc/get-tooltip :v-distribute)) + :class (stl/css-case :align-button true + :disabled disabled-distribute) + :disabled disabled-distribute + :data-value "vertical" + :on-click distribute-objects} + deprecated-icon/distribute-vertical-spacing]]]))) - [:> icon-button* {:variant "ghost" - :icon i/distribute-vertical-spacing - :aria-label (tr "workspace.align.vdistribute" (sc/get-tooltip :v-distribute)) - :on-click distribute-objects - :data-value "vertical" - :disabled disabled-distribute}]]]))) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.scss index 6b3f27b621..6535f728b4 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.scss @@ -4,10 +4,12 @@ // // Copyright (c) KALEIDOS INC +@use "refactor/common-refactor.scss" as deprecated; @use "../../../sidebar/common/sidebar.scss" as sidebar; .align-options { @include sidebar.option-grid-structure; + height: deprecated.$s-32; } .align-group-horizontal, .align-group-vertical { @@ -24,3 +26,27 @@ .align-group-vertical { grid-column: 5 / span 4; } + +.align-button { + @extend .button-tertiary; + height: deprecated.$s-32; + width: deprecated.$s-32; + padding: 0; + border-radius: deprecated.$br-8; + svg { + @extend .button-icon; + stroke: var(--icon-foreground); + } + &.disabled { + cursor: default; + svg { + stroke: var(--button-foreground-color-disabled); + } + &:hover { + background-color: var(--panel-background-color); + svg { + stroke: var(--button-foreground-color-disabled); + } + } + } +} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs index 7c27041728..52a5570614 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs @@ -15,6 +15,7 @@ [app.main.ui.components.title-bar :refer [title-bar*]] [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.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) @@ -102,12 +103,10 @@ [:div {:class (stl/css-case :first-row true :hidden hidden?)} [:div {:class (stl/css :blur-info)} - [:> icon-button* {:variant "secondary" - :class (stl/css :show-more) - :aria-label (tr "labels.options") - :aria-pressed more-options? - :on-click toggle-more-options - :icon i/menu}] + [:button {:class (stl/css-case :show-more true + :selected more-options?) + :on-click toggle-more-options} + deprecated-icon/menu] [:span {:class (stl/css :label)} (tr "workspace.options.blur-options.title")]] [:div {:class (stl/css :actions)} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.scss index 7623012431..e15a50c83e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.scss @@ -37,7 +37,21 @@ border-radius: deprecated.$br-8; background-color: var(--input-details-color); .show-more { + @extend .button-secondary; + height: deprecated.$s-32; + width: deprecated.$s-28; border-radius: deprecated.$br-8 0 0 deprecated.$br-8; + box-sizing: border-box; + border: deprecated.$s-1 solid var(--button-secondary-background-color-rest); + svg { + @extend .button-icon; + } + &.selected { + background-color: var(--button-radio-background-color-active); + svg { + stroke: var(--button-radio-foreground-color-active); + } + } } .label { @include deprecated.bodySmallTypography; diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs index 9fc8fdc6bb..b2ffa16cb8 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs @@ -15,12 +15,15 @@ [app.main.data.workspace.shortcuts :as sc] [app.main.features :as features] [app.main.store :as st] - [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.ds.foundations.assets.icon :as i] + [app.main.ui.icons :as deprecated-icon] [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) +(def ^:private flatten-icon + (deprecated-icon/icon-xref :boolean-flatten (stl/css :flatten-icon))) + (mf/defc bool-options* [{:keys [total-selected shapes shapes-with-children]}] (let [head (first shapes) @@ -67,40 +70,41 @@ (st/emit! (dwb/change-bool-type head-id bool-type))))))) flatten-objects - (mf/use-fn - #(st/emit! (dwps/convert-selected-to-path)))] + (mf/use-fn #(st/emit! (dwps/convert-selected-to-path)))] (when (not (and disabled-bool-btns disabled-flatten)) [:div {:class (stl/css :boolean-options)} - [:div {:class (stl/css :boolean-group)} - [:> radio-buttons* {:class (stl/css :boolean-radio-btn) - :variant "ghost" - :selected (d/name head-bool-type) - :on-change on-change - :name "bool-options" - :options [{:id "bool-opt-union" - :icon i/boolean-union - :label (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")") - :value "union" - :disabled disabled-bool-btns} - {:id "bool-opt-differente" - :icon i/boolean-difference - :label (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")") - :value "difference" - :disabled disabled-bool-btns} - {:id "bool-opt-intersection" - :icon i/boolean-intersection - :label (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")") - :value "intersection" - :disabled disabled-bool-btns} - {:id "bool-opt-exclude" - :icon i/boolean-exclude - :label (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")") - :value "exclude" - :disabled disabled-bool-btns}]}]] + [:div {:class (stl/css :bool-group)} + [:& radio-buttons {:selected (d/name head-bool-type) + :class (stl/css :boolean-radio-btn) + :on-change on-change + :name "bool-options"} + [:& radio-button {:icon i/boolean-union + :value "union" + :disabled disabled-bool-btns + :title (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")") + :id "bool-opt-union"}] + [:& radio-button {:icon i/boolean-difference + :value "difference" + :disabled disabled-bool-btns + :title (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")") + :id "bool-opt-differente"}] + [:& radio-button {:icon i/boolean-intersection + :value "intersection" + :disabled disabled-bool-btns + :title (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")") + :id "bool-opt-intersection"}] + [:& radio-button {:icon i/boolean-exclude + :value "exclude" + :disabled disabled-bool-btns + :title (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")") + :id "bool-opt-exclude"}]]] - [:> icon-button* {:variant "ghost" - :icon i/boolean-flatten - :aria-label (tr "workspace.shape.menu.flatten") - :on-click flatten-objects - :disabled disabled-flatten}]]))) + [:button + {:title (tr "workspace.shape.menu.flatten") + :class (stl/css-case + :flatten-button true + :disabled disabled-flatten) + :disabled disabled-flatten + :on-click flatten-objects} + flatten-icon]]))) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.scss index babf5564bd..ef69c2dd4e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.scss @@ -4,18 +4,45 @@ // // Copyright (c) KALEIDOS INC +@use "refactor/common-refactor.scss" as deprecated; @use "../../../sidebar/common/sidebar.scss" as sidebar; .boolean-options { @include sidebar.option-grid-structure; + height: var(--sp-xxxl); } -.boolean-group { +.bool-group { display: grid; grid-template-columns: subgrid; grid-column: 1 / span 4; } +.flatten-button { + @extend .button-tertiary; + height: deprecated.$s-32; + width: deprecated.$s-32; + border-radius: deprecated.$br-8; + grid-column: 5 / span 1; + --flatten-icon-foreground-color: var(--icon-foreground); + + &.disabled { + cursor: default; + --flatten-icon-foreground-color: var(--button-foreground-color-disabled); + + &:hover { + background-color: var(--panel-background-color); + --flatten-icon-foreground-color: var(--button-foreground-color-disabled); + } + } +} + +.flatten-icon { + @extend .button-icon; + stroke: var(--flatten-icon-foreground-color); +} + .boolean-radio-btn { background-color: transparent; + gap: var(--sp-xs); } diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs index 7daff9923a..d1d7a55fc5 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs @@ -333,9 +333,9 @@ :on-change on-radius-r3-change :value (:r3 values)}]]])) - [:> icon-button* {:variant "ghost" + [:> icon-button* {:class (stl/css-case :selected radius-expanded) + :variant "ghost" :on-click toggle-radius-mode - :aria-pressed radius-expanded :aria-label (if radius-expanded (tr "workspace.options.radius.hide-all-corners") (tr "workspace.options.radius.show-single-corners")) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.scss index db4cf8f11e..5473314c67 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.scss @@ -36,6 +36,12 @@ color: var(--color-accent-primary); } +.selected { + border-color: var(--button-icon-border-color-selected); + background-color: var(--button-icon-background-color-selected); + color: var(--button-icon-foreground-color-selected); +} + .icon { margin-inline: var(--sp-xs); } diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs index 6a0862379a..eac46af116 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs @@ -13,7 +13,6 @@ [app.main.data.workspace.tokens.application :as dwta] [app.main.store :as st] [app.main.ui.components.title-bar :refer [title-bar*]] - [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]] [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) @@ -50,16 +49,16 @@ • :prop → the property type (:fill, :stroke, :shadow, etc.) • :shape-id → the UUID of the shape using this color • :index → index of the color in the shape's fill/stroke list - + Example of groups: { {:color \"#9f2929\", :opacity 0.3, :token-name \"asd2\" :has-token-applied true} [{:prop :fill, :shape-id #uuid \"d0231035-25c9-80d5-8006-eae4c3dff32e\", :index 0}] - + {:color \"#1b54b6\", :opacity 1} [{:prop :fill, :shape-id #uuid \"aab34f9a-98c1-801a-8006-eae5e8236f1b\", :index 0}] } - + This structure allows fast lookups of all shapes using the same visual color, regardless of whether it comes from local fills, strokes or shadow-colors." @@ -218,8 +217,8 @@ :origin :color-selection :on-close on-close}])) (when (and (false? @expand-lib-color) (< 3 (count library-colors))) - [:> button* {:variant "secondary" - :on-click #(reset! expand-lib-color true)} + [:button {:class (stl/css :more-colors-btn) + :on-click #(reset! expand-lib-color true)} (tr "workspace.options.more-lib-colors")])] [:div {:class (stl/css :selected-color-group)} @@ -236,8 +235,8 @@ :on-close on-close}]) (when (and (false? @expand-color) (< 3 (count colors))) - [:> button* {:variant "secondary" - :on-click #(reset! expand-color true)} + [:button {:class (stl/css :more-colors-btn) + :on-click #(reset! expand-color true)} (tr "workspace.options.more-colors")])] [:div {:class (stl/css :selected-color-group)} @@ -260,6 +259,6 @@ (when (and (false? @expand-token-color) (< 3 (count token-colors))) - [:> button* {:variant "secondary" - :on-click #(reset! expand-token-color true)} + [:button {:class (stl/css :more-colors-btn) + :on-click #(reset! expand-token-color true)} (tr "workspace.options.more-token-colors")])]])])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.scss index f84a46c2a2..7519bcb568 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.scss @@ -40,5 +40,7 @@ } .more-colors-btn { - justify-content: center; + @extend .button-secondary; + @include deprecated.uppercaseTitleTipography; + height: deprecated.$s-32; } diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs index 1a6c61425e..401b01d67b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs @@ -28,6 +28,7 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.reorder-handler :refer [reorder-handler*]] [app.main.ui.components.search-bar :refer [search-bar*]] [app.main.ui.components.select :refer [select]] @@ -36,7 +37,6 @@ [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.controls.combobox :refer [combobox*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.controls.select :refer [select*]] [app.main.ui.ds.controls.switch :refer [switch*]] [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] @@ -794,17 +794,15 @@ [:div {:class (stl/css :swap-library)} [:div {:class (stl/css :swap-library-title)} [:div {:class (stl/css :swap-library-name)} current-lib-name] - [:> radio-buttons* {:selected (if (:listing-thumbs? filters) "grid" "list") - :on-change toggle-list-style - :name "swap-listing-style" - :options [{:id "swap-opt-list" - :icon i/view-as-list - :label (tr "workspace.assets.list-view") - :value "list"} - {:id "swap-opt-grid" - :icon i/flex-grid - :label (tr "workspace.assets.grid-view") - :value "grid"}]}]] + [:& radio-buttons {:selected (if (:listing-thumbs? filters) "grid" "list") + :on-change toggle-list-style + :name "swap-listing-style"} + [:& radio-button {:icon i/view-as-list + :value "list" + :id "swap-opt-list"}] + [:& radio-button {:icon i/flex-grid + :value "grid" + :id "swap-opt-grid"}]]] (when-not (or search? (str/empty? (:path filters))) [:button {:class (stl/css :swap-library-back) @@ -899,13 +897,11 @@ (when menu-entries? [:div {:class (stl/css :pill-actions)} - [:> icon-button* {:variant "secondary" - :class (stl/css-case :pill-actions-btn true - :extended subtext) - :aria-pressed menu-open? - :aria-label (tr "labels.options") - :on-click on-menu-click - :icon i/menu}] + [:button {:class (stl/css-case :pill-actions-btn true + :selected menu-open?) + :on-click on-menu-click} + [:> icon* {:icon-id i/menu}]] + [:& dropdown {:show menu-open? :on-close on-menu-close} [:ul {:class (stl/css-case :pill-actions-dropdown true diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss index e8838fdb77..88ca5dd5b6 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss @@ -587,9 +587,14 @@ } .pill-actions-btn { + @extend .button-secondary; + cursor: unset; + block-size: 100%; + inline-size: 100%; border-radius: 0 $br-8 $br-8 0; - &.extended { - block-size: $sz-48; + + &.selected { + @extend .button-icon-selected; } } diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs index f9368c9a4f..a56843dce2 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs @@ -16,7 +16,7 @@ [app.main.store :as st] [app.main.ui.components.select :refer [select]] [app.main.ui.components.title-bar :refer [title-bar*]] - [app.main.ui.ds.controls.checkbox :refer [checkbox*]] + [app.main.ui.icons :as deprecated-icon] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [cuerdas.core :as str] @@ -61,7 +61,6 @@ constraints-h (or (get values :constraints-h) (gsh/default-constraints-h values)) constraints-v (or (get values :constraints-v) (gsh/default-constraints-v values)) - fixed-scroll? (d/nilv (:fixed-scroll values) false) on-constraint-button-clicked (mf/use-fn @@ -219,8 +218,16 @@ :options options-v :on-change on-constraint-v-select-changed}]] (when first-level? - [:> checkbox* {:id "fixed-on-scroll" - :class (stl/css :checkbox) - :label (tr "workspace.options.constraints.fix-when-scrolling") - :checked fixed-scroll? - :on-change on-fixed-scroll-clicked}])]])]))) + [:div {:class (stl/css :checkbox)} + + [:label {:for "fixed-on-scroll" + :class (stl/css-case :checked (:fixed-scroll values))} + [:span {:class (stl/css-case :check-mark true + :checked (:fixed-scroll values))} + (when (:fixed-scroll values) + deprecated-icon/status-tick)] + (tr "workspace.options.constraints.fix-when-scrolling") + [:input {:type "checkbox" + :id "fixed-on-scroll" + :checked (:fixed-scroll values) + :on-change on-fixed-scroll-clicked}]]])]])]))) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.scss index 3f3fdc5dc1..5f7578afe1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.scss @@ -137,4 +137,36 @@ margin-bottom: deprecated.$s-8; margin-top: deprecated.$s-8; padding-left: 0; + input { + margin: 0; + } + + label { + @include deprecated.bodySmallTypography; + display: flex; + align-items: center; + gap: deprecated.$s-2; + cursor: pointer; + color: var(--input-checkbox-text-foreground-color); + .check-mark { + @include deprecated.flexCenter; + width: deprecated.$s-16; + height: deprecated.$s-16; + border-radius: deprecated.$br-6; + background-color: var(--input-checkbox-inactive-background-color); + &.checked { + background-color: var(--input-checkbox-background-color-active); + svg { + @extend .button-icon-small; + stroke: var(--input-details-color); + } + } + &:hover { + border-color: var(--input-checkbox-border-color-hover); + } + &:focus { + border-color: var(--input-checkbox-border-color-focus); + } + } + } } diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs index 88eca7dcfe..5e7d5c9127 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs @@ -14,7 +14,6 @@ [app.main.store :as st] [app.main.ui.components.select :refer [select]] [app.main.ui.components.title-bar :refer [title-bar*]] - [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.exports.assets] @@ -264,10 +263,12 @@ :icon i/remove}]])]) (when (or (= :multiple exports) (seq exports)) - [:> button* {:variant "secondary" - :class (stl/css :export-btn) - :on-click (when-not in-progress? on-download) - :disabled in-progress?} + [:button + {:on-click (when-not in-progress? on-download) + :class (stl/css-case + :export-btn true + :btn-disabled in-progress?) + :disabled in-progress?} (if in-progress? (tr "workspace.options.exporting-object") (tr "workspace.options.export-object" (c (count shapes-with-exports))))])])])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.scss index a9a4963921..487e4805bc 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.scss @@ -27,7 +27,7 @@ .multiple-exports { @include deprecated.flexRow; - grid-column: 1 / span 8; + grid-column: 1 / span 9; .label { @extend .mixed-bar; } @@ -76,6 +76,8 @@ } .export-btn { - grid-column: 1 / span 8; - justify-content: center; + @extend .button-secondary; + @include deprecated.uppercaseTitleTipography; + grid-column: 1 / span 9; + height: deprecated.$s-32; } diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs index 190c53645f..ba6ea893f2 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs @@ -17,9 +17,9 @@ [app.main.store :as st] [app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.controls.checkbox :refer [checkbox*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.hooks :as h] + [app.main.ui.icons :as deprecated-icon] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -252,9 +252,16 @@ (when (or (= type :frame) (and (= type :multiple) (some? hide-on-export))) - [:> checkbox* {:ref checkbox-ref - :id "show-fill-on-export" - :class (stl/css :fill-checkbox) - :label (tr "workspace.options.show-fill-on-export") - :checked (not hide-on-export) - :on-change on-change-show-on-export}])])])) + [:div {:class (stl/css :fill-checkbox)} + [:label {:for "show-fill-on-export" + :class (stl/css-case :global/checked (not hide-on-export))} + [:span {:class (stl/css-case :check-mark true + :checked (not hide-on-export))} + (when (not hide-on-export) + deprecated-icon/status-tick)] + (tr "workspace.options.show-fill-on-export") + [:input {:type "checkbox" + :id "show-fill-on-export" + :ref checkbox-ref + :checked (not hide-on-export) + :on-change on-change-show-on-export}]]])])])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.scss index 3ca90bb806..28a159b4de 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.scss @@ -50,5 +50,14 @@ } .fill-checkbox { + // TODO create a checkbox component in the DS + @extend .input-checkbox; padding-inline-start: var(--sp-s); + span.checked { + background-color: var(--color-accent-primary); + svg { + @extend .button-icon-small; + stroke: var(--color-background-primary); + } + } } diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs index 6cb6665d56..326b5efa4a 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs @@ -148,13 +148,10 @@ [:div {:class (stl/css :grid-title)} [:div {:class (stl/css-case :option-row true :hidden is-hidden?)} - [:> icon-button* {:variant "secondary" - :icon i/menu - :class (stl/css :show-options) - :aria-pressed open? - :aria-label (tr "labels.options") - :on-click toggle-advanced-options - :disabled is-hidden?}] + [:button {:class (stl/css-case :show-options true + :selected open?) + :on-click toggle-advanced-options} + deprecated-icon/menu] [:div {:class (stl/css :type-select-wrapper)} [:& select {:class (stl/css :grid-type-select) @@ -207,11 +204,10 @@ :origin :guides :on-change handle-change-color :on-detach handle-detach-color}] - [:> icon-button* {:variant "ghost" - :icon i/menu - :aria-pressed show-more-options? - :aria-label (tr "labels.options") - :on-click toggle-more-options}]] + [:button {:class (stl/css-case :show-more-options true + :selected show-more-options?) + :on-click toggle-more-options} + deprecated-icon/menu]] (when show-more-options? [:div {:class (stl/css :second-row)} [:button {:class (stl/css-case :btn-options true @@ -288,12 +284,11 @@ :className (stl/css :numeric-input) :value (or (:margin params) 0)}]] - [:> icon-button* {:variant "ghost" - :icon i/menu - :aria-pressed show-more-options? - :aria-label (tr "labels.options") - :on-click toggle-more-options - :disabled is-default}] + [:button {:class (stl/css-case :show-more-options true + :selected show-more-options?) + :on-click toggle-more-options + :disabled is-default} + deprecated-icon/menu] (when show-more-options? [:div {:class (stl/css :more-options)} [:button {:class (stl/css :option-btn) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.scss index f6ab50dba3..51b82c5434 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.scss @@ -38,7 +38,18 @@ border-radius: deprecated.$br-8; background-color: var(--input-details-color); .show-options { + @extend .button-secondary; + height: deprecated.$s-32; + width: deprecated.$s-28; border-radius: deprecated.$br-8 0 0 deprecated.$br-8; + box-sizing: border-box; + border: deprecated.$s-1 solid var(--input-border-color); + svg { + @extend .button-icon; + } + &.selected { + @extend .button-icon-selected; + } } .type-select-wrapper { flex-grow: 1; @@ -97,6 +108,7 @@ &.hidden { .show-options { + @include deprecated.hiddenElement; border: deprecated.$s-1 solid var(--input-border-color-disabled); } .type-select-wrapper, @@ -164,7 +176,17 @@ .color-wrapper { width: deprecated.$s-156; } - + .show-more-options { + @extend .button-tertiary; + height: deprecated.$s-32; + width: deprecated.$s-32; + svg { + @extend .button-icon; + } + &.selected { + @extend .button-icon-selected; + } + } .height { @extend .input-element; @include deprecated.bodySmallTypography; diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs index 5e9295fe75..8308bae61e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs @@ -16,9 +16,8 @@ [app.main.data.workspace.shape-layout :as dwsl] [app.main.store :as st] [app.main.ui.components.numeric-input :refer [numeric-input*]] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.title-bar :refer [title-bar*]] - [app.main.ui.ds.buttons.button :refer [button*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.hooks :as hooks] [app.main.ui.icons :as deprecated-icon] @@ -36,10 +35,10 @@ :justify-self :area-name]) -(mf/defc set-self-alignment* - [{:keys [is-col alignment set-alignment]}] +(mf/defc set-self-alignment + [{:keys [is-col? alignment set-alignment] :as props}] (let [alignment (or alignment :auto) - type (if is-col "col" "row") + type (if is-col? "col" "row") handle-set-alignment (mf/use-callback @@ -47,35 +46,39 @@ (fn [value] (set-alignment (-> value keyword))))] - [:> radio-buttons* {:class (stl/css :self-align-menu) - :selected (d/name alignment) - :name (dm/str "flex-align-items-" type) - :allow-empty true + [:div {:class (stl/css :self-align-menu)} + [:& radio-buttons {:selected (d/name alignment) :on-change handle-set-alignment - :options [{:id (dm/str "align-self-start-" type) - :icon (if is-col - i/align-self-row-left - i/align-self-column-top) - :label "Align self start" - :value "start"} - {:id (dm/str "align-self-center-" type) - :icon (if is-col - i/align-self-row-center - i/align-self-column-center) - :label "Align self center" - :value "center"} - {:id (dm/str "align-self-end-" type) - :icon (if is-col - i/align-self-row-right - i/align-self-column-bottom) - :label "Align self end" - :value "end"} - {:id (dm/str "align-self-stretch-" type) - :icon (if is-col - i/align-self-row-stretch - i/align-self-column-stretch) - :label "Align self stretch" - :value "stretch"}]}])) + :allow-empty true + :name (dm/str "flex-align-items-" type)} + [:& radio-button {:value "start" + :icon (if is-col? + i/align-self-row-left + i/align-self-column-top) + :title "Align self start" + :id (dm/str "align-self-start-" type)}] + + [:& radio-button {:value "center" + :icon (if is-col? + i/align-self-row-center + i/align-self-column-center) + :title "Align self center" + :id (dm/str "align-self-center-" type)}] + + [:& radio-button {:value "end" + :icon (if is-col? + i/align-self-row-right + i/align-self-column-bottom) + :title "Align self end" + :id (dm/str "align-self-end-" type)}] + + [:& radio-button {:value "stretch" + :icon (if is-col? + i/align-self-row-stretch + i/align-self-column-stretch) + :title "Align self stretch" + :id (dm/str "align-self-stretch-" type)}]]])) + (mf/defc options {::mf/wrap [mf/memo]} @@ -179,19 +182,16 @@ (when open? [:div {:class (stl/css :grid-cell-menu-container)} - [:> radio-buttons* {:selected (d/name cell-mode) - :name "cell-mode" + [:div {:class (stl/css :cell-mode :row)} + [:& radio-buttons {:selected (d/name cell-mode) :on-change set-cell-mode - :options [{:id "auto" - :label "Auto" - :value "auto"} - {:id "manual" - :label "Manual" - :value "manual"} - {:id "area" - :label "Area" - :value "area" - :disabled (not valid-area-cells?)}]}] + :name "cell-mode" + :wide true} + [:& radio-button {:value "auto" :id :auto}] + [:& radio-button {:value "manual" :id :manual}] + [:& radio-button {:value "area" + :id :area + :disabled (not valid-area-cells?)}]]] (when (= :area cell-mode) [:div {:class (stl/css :row)} @@ -261,15 +261,16 @@ :value row-end}]]]]) [:div {:class (stl/css :row)} - [:> set-self-alignment* {:is-col false - :alignment align-self - :set-alignment set-alignment}] - [:> set-self-alignment* {:is-col true - :alignment justify-self - :set-alignment set-justify-self}]] + [:& set-self-alignment {:is-col? false + :alignment align-self + :set-alignment set-alignment}] + [:& set-self-alignment {:is-col? true + :alignment justify-self + :set-alignment set-justify-self}]] [:div {:class (stl/css :row)} - [:> button* {:variant "secondary" - :class (stl/css :edit-grid-btn) - :on-click toggle-edit-mode} + [:button + {:class (stl/css :edit-grid-btn) + :alt (tr "workspace.layout-grid.editor.options.edit-grid") + :on-click toggle-edit-mode} (tr "workspace.layout-grid.editor.options.edit-grid")]]])])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.scss index a9c9814683..5b61b4dabf 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.scss @@ -30,6 +30,17 @@ @include deprecated.flexRow; } +.cell-mode :global(label) { + padding: 0 deprecated.$s-12; +} + +.edit-grid-btn { + @extend .button-secondary; + @include deprecated.uppercaseTitleTipography; + width: 100%; + padding: deprecated.$s-8; +} + .area-input { @extend .input-element; @include deprecated.bodySmallTypography; @@ -55,7 +66,3 @@ border-radius: 0 deprecated.$br-8 deprecated.$br-8 0; border-left: deprecated.$s-1 solid var(--panel-background-color); } - -.edit-grid-btn { - flex-grow: 1; -} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs index 9c2846a614..ac8fdc23cf 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs @@ -17,13 +17,13 @@ [app.main.data.workspace.interactions :as dwi] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.select :refer [select]] [app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.controls.checkbox :refer [checkbox*]] [app.main.ui.ds.controls.input :refer [input*]] [app.main.ui.ds.controls.numeric-input :refer [numeric-input*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.product.empty-state :refer [empty-state*]] [app.util.dom :as dom] @@ -582,43 +582,41 @@ :options animation-opts :on-change change-animation-type}]]] - ;; Way + ;; Direction (when (ctsi/has-way? interaction) [:div {:class (stl/css :interaction-row)} [:div {:class (stl/css :interaction-row-radio)} - [:> radio-buttons* {:selected (d/name way) - :on-change change-way - :name "animation-way" - :options [{:id "animation-way-in" - :label (tr "workspace.options.interaction-animation-direction-in") - :value "in"} - {:id "animation-way-out" - :label (tr "workspace.options.interaction-animation-direction-out") - :value "out"}]}]]]) + [:& radio-buttons {:selected (d/name way) + :on-change change-way + :name "animation-way"} + [:& radio-button {:value "in" + :id "animation-way-in"}] + [:& radio-button {:id "animation-way-out" + :value "out"}]]]]) ;; Direction (when (ctsi/has-direction? interaction) [:div {:class (stl/css :interaction-row)} [:div {:class (stl/css :interaction-row-radio)} - [:> radio-buttons* {:selected (d/name direction) - :on-change change-direction - :name "animation-direction" - :options [{:id "animation-right" - :icon i/row - :label (tr "workspace.options.interaction-animation-direction-right") - :value "right"} - {:id "animation-left" - :icon i/row-reverse - :label (tr "workspace.options.interaction-animation-direction-left") - :value "left"} - {:id "animation-down" - :icon i/column - :label (tr "workspace.options.interaction-animation-direction-down") - :value "down"} - {:id "animation-up" - :icon i/column-reverse - :label (tr "workspace.options.interaction-animation-direction-up") - :value "up"}]}]]]) + [:& radio-buttons {:selected (d/name direction) + :on-change change-direction + :name "animation-direction"} + [:& radio-button {:icon i/row + :icon-class (stl/css :right) + :value "right" + :id "animation-right"}] + [:& radio-button {:icon i/row-reverse + :icon-class (stl/css :left) + :id "animation-left" + :value "left"}] + [:& radio-button {:icon i/column + :icon-class (stl/css :down) + :id "animation-down" + :value "down"}] + [:& radio-button {:icon i/column-reverse + :icon-class (stl/css :up) + :id "animation-up" + :value "up"}]]]]) ;; Duration (when (ctsi/has-duration? interaction) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index 655c00867d..e07c3cd958 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -22,11 +22,10 @@ [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.numeric-input :as deprecated-input] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.select :refer [select]] [app.main.ui.components.title-bar :refer [title-bar*]] - [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.formats :as fmt] [app.main.ui.hooks :as h] @@ -163,118 +162,128 @@ :space-between i/align-content-row-between :stretch i/align-content-row-stretch)))) -(mf/defc direction-row-flex* - {::mf/private true} +(mf/defc direction-row-flex + {::mf/props :obj + ::mf/private true} [{:keys [value on-change]}] - [:> radio-buttons* {:class (stl/css :direction-row-flex) - :selected (d/name value) - :on-change on-change - :name "flex-direction" - :options [{:id "flex-direction-row" - :icon (dir-icons-refactor :row) - :label "Row" - :value "row"} - {:id "flex-direction-row-reverse" - :icon (dir-icons-refactor :row-reverse) - :label "Row reverse" - :value "row-reverse"} - {:id "flex-direction-column" - :icon (dir-icons-refactor :column) - :label "Column" - :value "column"} - {:id "flex-direction-column-reverse" - :icon (dir-icons-refactor :column-reverse) - :label "Column reverse" - :value "column-reverse"}]}]) + [:& radio-buttons {:class (stl/css :direction-row-flex) + :selected (d/name value) + :decode-fn keyword + :on-change on-change + :name "flex-direction"} + [:& radio-button {:value "row" + :id "flex-direction-row" + :title "Row" + :icon (dir-icons-refactor :row)}] + [:& radio-button {:value "row-reverse" + :id "flex-direction-row-reverse" + :title "Row reverse" + :icon (dir-icons-refactor :row-reverse)}] + [:& radio-button {:value "column" + :id "flex-direction-column" + :title "Column" + :icon (dir-icons-refactor :column)}] + [:& radio-button {:value "column-reverse" + :id "flex-direction-column-reverse" + :title "Column reverse" + :icon (dir-icons-refactor :column-reverse)}]]) -(mf/defc wrap-row* +(mf/defc wrap-row + {::mf/props :obj} [{:keys [wrap-type on-click]}] - [:> icon-button* {:variant "ghost" - :aria-label (if (= :wrap wrap-type) "No wrap" "Wrap") - :aria-pressed (= wrap-type :wrap) - :on-click on-click - :icon i/wrap}]) + [:button {:class (stl/css-case :wrap-button true + :selected (= wrap-type :wrap)) + :title (if (= :wrap wrap-type) + "No wrap" + "Wrap") + :on-click on-click} + deprecated-icon/wrap]) -(mf/defc align-row* +(mf/defc align-row + {::mf/props :obj} [{:keys [is-column value on-change]}] - [:> radio-buttons* {:class (stl/css :align-row) - :selected (d/name value) - :on-change on-change - :name "flex-align-items" - :options [{:id "align-items-start" - :icon (get-layout-flex-icon :align-items :start is-column) - :label "Align items start" - :value "start"} - {:id "align-items-center" - :icon (get-layout-flex-icon :align-items :center is-column) - :label "Align items center" - :value "center"} - {:id "align-items-end" - :icon (get-layout-flex-icon :align-items :end is-column) - :label "Align items end" - :value "end"}]}]) + [:& radio-buttons {:class (stl/css :align-row) + :selected (d/name value) + :decode-fn keyword + :on-change on-change + :name "flex-align-items"} + [:& radio-button {:value "start" + :icon (get-layout-flex-icon :align-items :start is-column) + :title "Align items start" + :id "align-items-start"}] + [:& radio-button {:value "center" + :icon (get-layout-flex-icon :align-items :center is-column) + :title "Align items center" + :id "align-items-center"}] + [:& radio-button {:value "end" + :icon (get-layout-flex-icon :align-items :end is-column) + :title "Align items end" + :id "align-items-end"}]]) -(mf/defc align-content-row* +(mf/defc align-content-row + {::mf/props :obj} [{:keys [is-column value on-change]}] - [:> radio-buttons* {:class (stl/css :align-content-row) - :selected (d/name value) - :on-change on-change - :name "flex-align-content" - :options [{:id "align-content-start" - :icon (get-layout-flex-icon :align-content :start is-column) - :label "Align content start" - :value "start"} - {:id "align-content-center" - :icon (get-layout-flex-icon :align-content :center is-column) - :label "Align content center" - :value "center"} - {:id "align-content-end" - :icon (get-layout-flex-icon :align-content :end is-column) - :label "Align content end" - :value "end"} - {:id "align-content-space-between" - :icon (get-layout-flex-icon :align-content :space-between is-column) - :label "Align content space-between" - :value "space-between"} - {:id "align-content-space-around" - :icon (get-layout-flex-icon :align-content :space-around is-column) - :label "Align content space-around" - :value "space-around"} - {:id "align-content-space-evenly" - :icon (get-layout-flex-icon :align-content :space-evenly is-column) - :label "Align content space-evenly" - :value "space-evenly"}]}]) + [:& radio-buttons {:class (stl/css :align-content-row) + :selected (d/name value) + :decode-fn keyword + :on-change on-change + :name "flex-align-content"} + [:& radio-button {:value "start" + :icon (get-layout-flex-icon :align-content :start is-column) + :title "Align content start" + :id "align-content-start"}] + [:& radio-button {:value "center" + :icon (get-layout-flex-icon :align-content :center is-column) + :title "Align content center" + :id "align-content-center"}] + [:& radio-button {:value "end" + :icon (get-layout-flex-icon :align-content :end is-column) + :title "Align content end" + :id "align-content-end"}] + [:& radio-button {:value "space-between" + :icon (get-layout-flex-icon :align-content :space-between is-column) + :title "Align content space-between" + :id "align-content-space-between"}] + [:& radio-button {:value "space-around" + :icon (get-layout-flex-icon :align-content :space-around is-column) + :title "Align content space-around" + :id "align-content-space-around"}] + [:& radio-button {:value "space-evenly" + :icon (get-layout-flex-icon :align-content :space-evenly is-column) + :title "Align content space-evenly" + :id "align-content-space-evenly"}]]) -(mf/defc justify-content-row* +(mf/defc justify-content-row + {::mf/props :obj} [{:keys [is-column justify-content on-change]}] - [:> radio-buttons* {:class (stl/css :justify-content-row) - :selected (d/name justify-content) - :on-change on-change - :name "flex-justify" - :options [{:id "justify-content-start" - :icon (get-layout-flex-icon :justify-content :start is-column) - :label "Justify content start" - :value "start"} - {:id "justify-content-center" - :icon (get-layout-flex-icon :justify-content :center is-column) - :label "Justify content center" - :value "center"} - {:id "justify-content-end" - :icon (get-layout-flex-icon :justify-content :end is-column) - :label "Justify content end" - :value "end"} - {:id "justify-content-space-between" - :icon (get-layout-flex-icon :justify-content :space-between is-column) - :label "Justify content space-between" - :value "space-between"} - {:id "justify-content-space-around" - :icon (get-layout-flex-icon :justify-content :space-around is-column) - :label "Justify content space-around" - :value "space-around"} - {:id "justify-content-space-evenly" - :icon (get-layout-flex-icon :justify-content :space-evenly is-column) - :label "Justify content space-evenly" - :value "space-evenly"}]}]) + [:& radio-buttons {:class (stl/css :justify-content-row) + :selected (d/name justify-content) + :on-change on-change + :name "flex-justify"} + [:& radio-button {:value "start" + :icon (get-layout-flex-icon :justify-content :start is-column) + :title "Justify content start" + :id "justify-content-start"}] + [:& radio-button {:value "center" + :icon (get-layout-flex-icon :justify-content :center is-column) + :title "Justify content center" + :id "justify-content-center"}] + [:& radio-button {:value "end" + :icon (get-layout-flex-icon :justify-content :end is-column) + :title "Justify content end" + :id "justify-content-end"}] + [:& radio-button {:value "space-between" + :icon (get-layout-flex-icon :justify-content :space-between is-column) + :title "Justify content space-between" + :id "justify-content-space-between"}] + [:& radio-button {:value "space-around" + :icon (get-layout-flex-icon :justify-content :space-around is-column) + :title "Justify content space-around" + :id "justify-content-space-around"}] + [:& radio-button {:value "space-evenly" + :icon (get-layout-flex-icon :justify-content :space-evenly is-column) + :title "Justify content space-evenly" + :id "justify-content-space-evenly"}]]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PADDING @@ -665,12 +674,14 @@ (= type :multiple) [:> multiple-padding-selection* props])] - [:> icon-button* {:variant "ghost" - :aria-label (tr "workspace.layout-grid.editor.padding.expand") - :aria-pressed (= type :multiple) - :data-type (d/name type) - :on-click on-type-change' - :icon i/padding-extended}]])) + [:button {:class (stl/css-case + :padding-toggle true + :selected (= type :multiple)) + :title (tr "workspace.layout-grid.editor.padding.expand") + :aria-label (tr "workspace.layout-grid.editor.padding.expand") + :data-type (d/name type) + :on-click on-type-change'} + deprecated-icon/padding-extended]])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; GAP @@ -825,22 +836,25 @@ ;; GRID COMPONENTS -(mf/defc direction-row-grid* +(mf/defc direction-row-grid + {::mf/props :obj} [{:keys [value on-change] :as props}] - [:> radio-buttons* {:class (stl/css :direction-row-grid) - :selected (d/name value) - :on-change on-change - :name "grid-direction" - :options [{:id "grid-direction-row" - :icon (dir-icons-refactor :row) - :label "Row" - :value "row"} - {:id "grid-direction-column" - :icon (dir-icons-refactor :column) - :label "Column" - :value "column"}]}]) + [:& radio-buttons {:class (stl/css :direction-row-grid) + :selected (d/name value) + :decode-fn keyword + :on-change on-change + :name "grid-direction"} + [:& radio-button {:value "row" + :id "grid-direction-row" + :title "Row" + :icon (dir-icons-refactor :row)}] + [:& radio-button {:value "column" + :id "grid-direction-column" + :title "Column" + :icon (dir-icons-refactor :column)}]]) -(mf/defc grid-edit-mode* +(mf/defc grid-edit-mode + {::mf/props :obj} [{:keys [id]}] (let [edition (mf/deref refs/selected-edition) active? (= id edition) @@ -852,65 +866,81 @@ (if-not active? (st/emit! (udw/start-edition-mode id)) (st/emit! :interrupt))))] - - [:> button* {:variant "secondary" - :class (stl/css :edit-mode-btn) - :on-click toggle-edit-mode} + [:button + {:class (stl/css :edit-mode-btn) + :alt "Grid edit mode" + :on-click toggle-edit-mode} (tr "workspace.layout-grid.editor.options.edit-grid")])) -(mf/defc align-grid-row* - {::mf/private true} +(mf/defc align-grid-row + {::mf/props :obj + ::mf/private true} [{:keys [is-column value on-change]}] (let [type (if ^boolean is-column "column" "row")] - [:> radio-buttons* {:class (stl/css :align-grid-row) - :selected (d/name value) - :on-change on-change - :name (dm/str "flex-align-items-" type) - :options [{:id (dm/str "align-items-start-" type) - :icon (get-layout-grid-icon :align-items :start is-column) - :label "Align items start" - :value "start"} - {:id (dm/str "align-items-center-" type) - :icon (get-layout-grid-icon :align-items :center is-column) - :label "Align items center" - :value "center"} - {:id (dm/str "align-items-end-" type) - :icon (get-layout-grid-icon :align-items :end is-column) - :label "Align items end" - :value "end"}]}])) + [:& radio-buttons {:class (stl/css :align-grid-row) + :selected (d/name value) + :decode-fn keyword + :on-change on-change + :name (dm/str "flex-align-items-" type)} + [:& radio-button {:value "start" + :icon (get-layout-grid-icon :align-items :start is-column) + :title "Align items start" + :id (dm/str "align-items-start-" type)}] + [:& radio-button {:value "center" + :icon (get-layout-grid-icon :align-items :center is-column) + :title "Align items center" + :id (dm/str "align-items-center-" type)}] + [:& radio-button {:value "end" + :icon (get-layout-grid-icon :align-items :end is-column) + :title "Align items end" + :id (dm/str "align-items-end-" type)}]])) -(mf/defc justify-grid-row* - {::mf/private true} +(mf/defc justify-grid-row + {::mf/props :obj + ::mf/private :obj} [{:keys [is-column value on-change]}] (let [type (if ^boolean is-column "column" "row")] - [:> radio-buttons* {:class (stl/css :justify-grid-row) - :selected (d/name value) - :on-change on-change - :name (dm/str "grid-justify-items-" type) - :options [{:id (dm/str "justify-items-start-" type) - :icon (get-layout-grid-icon :justify-items :start is-column) - :label "Justify items start" - :value "start"} - {:id (dm/str "justify-items-center-" type) - :icon (get-layout-grid-icon :justify-items :center is-column) - :label "Justify items center" - :value "center"} - {:id (dm/str "justify-items-end-" type) - :icon (get-layout-grid-icon :justify-items :end is-column) - :label "Justify items end" - :value "end"} - {:id (dm/str "justify-items-space-around-" type) - :icon (get-layout-grid-icon :justify-items :space-around is-column) - :label "Justify items space-around" - :value "space-around"} - {:id (dm/str "justify-items-space-between-" type) - :icon (get-layout-grid-icon :justify-items :space-between is-column) - :label "Justify items space-between" - :value "space-between"} - {:id (dm/str "justify-items-stretch-" type) - :icon (get-layout-grid-icon :justify-items :stretch is-column) - :label "Justify items stretch" - :value "stretch"}]}])) + [:& radio-buttons {:class (stl/css :justify-grid-row) + :selected (d/name value) + :on-change on-change + :decode-fn keyword + :name (dm/str "grid-justify-items-" type)} + + [:& radio-button {:key "justify-item-start" + :value "start" + :icon (get-layout-grid-icon :justify-items :start is-column) + :title "Justify items start" + :id (dm/str "justify-items-start-" type)}] + + [:& radio-button {:key "justify-item-center" + :value "center" + :icon (get-layout-grid-icon :justify-items :center is-column) + :title "Justify items center" + :id (dm/str "justify-items-center-" type)}] + + [:& radio-button {:key "justify-item-end" + :value "end" + :icon (get-layout-grid-icon :justify-items :end is-column) + :title "Justify items end" + :id (dm/str "justify-items-end-" type)}] + + [:& radio-button {:key "justify-item-space-around" + :value "space-around" + :icon (get-layout-grid-icon :justify-items :space-around is-column) + :title "Justify items space-around" + :id (dm/str "justify-items-space-around-" type)}] + + [:& radio-button {:key "justify-item-space-between" + :value "space-between" + :icon (get-layout-grid-icon :justify-items :space-between is-column) + :title "Justify items space-between" + :id (dm/str "justify-items-space-between-" type)}] + + [:& radio-button {:key "justify-item-stretch" + :value "stretch" + :icon (get-layout-grid-icon :justify-items :stretch is-column) + :title "Justify items stretch" + :id (dm/str "justify-items-stretch-" type)}]])) (defn- manage-values [{:keys [type value]}] @@ -921,7 +951,8 @@ :fixed (fmt/format-pixels value) value)) -(mf/defc grid-track-info* +(mf/defc grid-track-info + {::mf/props :obj} [{:keys [is-column type index @@ -1004,7 +1035,8 @@ :data-index index :icon i/remove}]])) -(mf/defc grid-columns-row* +(mf/defc grid-columns-row + {::mf/props :obj} [{:keys [is-column expanded? column-values toggle add-new-element set-column-value set-column-type remove-element reorder-track hover-track on-select-track]}] (let [column-num (count column-values) @@ -1025,38 +1057,27 @@ [:div {:class (stl/css :grid-tracks) :data-testid testid} [:div {:class (stl/css :grid-track-header)} - [:> icon-button* {:variant "secondary" - :class (stl/css :expand-icon) - :aria-pressed expanded? - :aria-label (tr "labels.options") - :on-click toggle - :icon i/menu}] - #_[:button {:class (stl/css :expand-icon) :on-click toggle} deprecated-icon/menu] + [:button {:class (stl/css :expand-icon) :on-click toggle} deprecated-icon/menu] [:div {:class (stl/css :track-title) :on-click toggle} [:div {:class (stl/css :track-name) :title track-name} track-name] [:div {:class (stl/css :track-detail) :title track-detail} track-detail]] - [:> icon-button* {:variant "secondary" - :class (stl/css :add-column) - :aria-label (tr "labels.add") - :on-click add-track - :icon i/add}] - #_[:button {:class (stl/css :add-column) :on-click add-track} deprecated-icon/add]] + [:button {:class (stl/css :add-column) :on-click add-track} deprecated-icon/add]] (when expanded? [:> h/sortable-container* {} [:div {:class (stl/css :grid-tracks-info-container)} (for [[index column] (d/enumerate column-values)] - [:> grid-track-info* {:key (dm/str index "-" (d/name type)) - :type type - :is-column is-column - :index index - :column column - :set-column-value set-column-value - :set-column-type set-column-type - :remove-element remove-element - :reorder-track reorder-track - :hover-track hover-track - :on-select-track on-select-track}])]])])) + [:& grid-track-info {:key (dm/str index "-" (d/name type)) + :type type + :is-column is-column + :index index + :column column + :set-column-value set-column-value + :set-column-type set-column-type + :remove-element remove-element + :reorder-track reorder-track + :hover-track hover-track + :on-select-track on-select-track}])]])])) ;; LAYOUT COMPONENT @@ -1192,8 +1213,8 @@ (mf/deps layout-type ids) (fn [dir] (if (= :flex layout-type) - (st/emit! (dwsl/update-layout ids {:layout-flex-dir (keyword dir)})) - (st/emit! (dwsl/update-layout ids {:layout-grid-dir (keyword dir)}))))) + (st/emit! (dwsl/update-layout ids {:layout-flex-dir dir})) + (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))) ;; Align grid align-items-row (:layout-align-items values) @@ -1203,13 +1224,13 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-justify-items (keyword value)})))) + (st/emit! (dwsl/update-layout ids {:layout-justify-items value})))) on-row-align-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-align-items (keyword value)})))) + (st/emit! (dwsl/update-layout ids {:layout-align-items value})))) ;; Justify grid grid-justify-content-row (:layout-justify-content values) @@ -1219,13 +1240,13 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-align-content (keyword value)})))) + (st/emit! (dwsl/update-layout ids {:layout-align-content value})))) on-row-justify-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-justify-content (keyword value)})))) + (st/emit! (dwsl/update-layout ids {:layout-justify-content value})))) on-toggle-dropdown-visibility (mf/use-fn #(swap! show-dropdown* not)) @@ -1298,31 +1319,31 @@ :flex [:div {:class (stl/css :flex-layout-menu)} [:div {:class (stl/css :first-row)} - [:> align-row* {:is-column is-column - :value align-items - :on-change set-align-items}] + [:& align-row {:is-column is-column + :value align-items + :on-change set-align-items}] - [:> direction-row-flex* {:on-change on-direction-change - :value saved-dir}] + [:& direction-row-flex {:on-change on-direction-change + :value saved-dir}] - [:> wrap-row* {:wrap-type wrap-type - :on-click toggle-wrap}]] + [:& wrap-row {:wrap-type wrap-type + :on-click toggle-wrap}]] - [:div {:class (stl/css :middle-row)} - [:div {:class (stl/css :help-button-wrapper)} - [:> justify-content-row* {:is-column is-column - :justify-content justify-content - :on-change set-justify-content}] - [:> icon-button* {:variant "ghost" - :aria-label (tr "labels.help-center") - :on-click open-flex-help - :icon i/help}]] - (when (= :wrap wrap-type) - [:> align-content-row* {:is-column is-column - :value align-content - :on-change on-align-content-change}])] + [:div {:class (stl/css :second-row :help-button-wrapper)} + [:& justify-content-row {:is-column is-column + :justify-content justify-content + :on-change set-justify-content}] - [:div {:class (stl/css :last-row)} + [:> icon-button* {:variant "ghost" + :aria-label (tr "labels.help-center") + :on-click open-flex-help + :icon i/help}]] + (when (= :wrap wrap-type) + [:div {:class (stl/css :third-row)} + [:& align-content-row {:is-column is-column + :value align-content + :on-change on-align-content-change}]]) + [:div {:class (stl/css :forth-row)} [:> gap-section* {:is-column is-column :wrap-type wrap-type :on-change on-gap-change @@ -1340,7 +1361,7 @@ [:div {:class (stl/css :grid-layout-menu)} (when (= 1 (count ids)) [:div {:class (stl/css :edit-grid-wrapper)} - [:> grid-edit-mode* {:id (first ids)}] + [:& grid-edit-mode {:id (first ids)}] [:> icon-button* {:variant "ghost" :aria-label (tr "labels.help-center") :on-click open-grid-help @@ -1349,23 +1370,23 @@ [:div {:class (stl/css :first-row)} [:div {:class (stl/css :direction-edit)} [:div {:class (stl/css :direction)} - [:> direction-row-grid* {:value saved-grid-dir - :on-change on-direction-change}]]] + [:& direction-row-grid {:value saved-grid-dir + :on-change on-direction-change}]]] - [:> align-grid-row* {:is-column false - :value align-items-row - :on-change on-row-align-change}] - [:> align-grid-row* {:is-column true - :value align-items-column - :on-change on-column-align-change}]] + [:& align-grid-row {:is-column false + :value align-items-row + :on-change on-row-align-change}] + [:& align-grid-row {:is-column true + :value align-items-column + :on-change on-column-align-change}]] [:div {:class (stl/css :row :grid-layout-align)} - [:> justify-grid-row* {:is-column true - :value grid-justify-content-column - :on-change on-column-justify-change}] - [:> justify-grid-row* {:is-column false - :value grid-justify-content-row - :on-change on-row-justify-change}]] + [:& justify-grid-row {:is-column true + :value grid-justify-content-column + :on-change on-column-justify-change}] + [:& justify-grid-row {:is-column false + :value grid-justify-content-row + :on-change on-row-justify-change}]] [:div {:class (stl/css :gap-row)} [:> gap-section* {:on-change on-gap-change @@ -1391,7 +1412,7 @@ (mf/use-fn (mf/deps ids) (fn [dir] - (st/emit! (dwsl/update-layout ids {:layout-grid-dir (keyword dir)})))) + (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})))) on-gap-change (mf/use-fn @@ -1430,13 +1451,13 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-justify-items (keyword value)})))) + (st/emit! (dwsl/update-layout ids {:layout-justify-items value})))) on-row-align-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-align-items (keyword value)})))) + (st/emit! (dwsl/update-layout ids {:layout-align-items value})))) ;; Justify grid grid-justify-content-row (:layout-justify-content values) @@ -1446,13 +1467,13 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-align-content (keyword value)})))) + (st/emit! (dwsl/update-layout ids {:layout-align-content value})))) on-row-justify-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-justify-content (keyword value)})))) + (st/emit! (dwsl/update-layout ids {:layout-justify-content value})))) columns-open? (mf/use-state false) rows-open? (mf/use-state false) @@ -1533,32 +1554,31 @@ :aria-label (tr "labels.help-center") :on-click open-grid-help :icon i/help}] - [:> button* {:variant "secondary" - :class (stl/css :exit-btn) - :on-click #(st/emit! (udw/clear-edition-mode))} + [:button {:class (stl/css :exit-btn) + :on-click #(st/emit! (udw/clear-edition-mode))} (tr "workspace.layout-grid.editor.options.exit")]] [:div {:class (stl/css :row :first-row)} [:div {:class (stl/css :direction-edit)} [:div {:class (stl/css :direction)} - [:> direction-row-grid* {:value saved-grid-dir - :on-change on-direction-change}]]] + [:& direction-row-grid {:value saved-grid-dir + :on-change on-direction-change}]]] - [:> align-grid-row* {:is-column false - :value align-items-row - :on-change on-row-align-change}] + [:& align-grid-row {:is-column false + :value align-items-row + :on-change on-row-align-change}] - [:> align-grid-row* {:is-column true - :value align-items-column - :on-change on-column-align-change}]] + [:& align-grid-row {:is-column true + :value align-items-column + :on-change on-column-align-change}]] [:div {:class (stl/css :row :grid-layout-align)} - [:> justify-grid-row* {:is-column true - :value grid-justify-content-column - :on-change on-column-justify-change}] - [:> justify-grid-row* {:is-column false - :value grid-justify-content-row - :on-change on-row-justify-change}] + [:& justify-grid-row {:is-column true + :value grid-justify-content-column + :on-change on-column-justify-change}] + [:& justify-grid-row {:is-column false + :value grid-justify-content-row + :on-change on-row-justify-change}] [:> icon-button* {:variant "ghost" :class (stl/css :locate-button) @@ -1572,33 +1592,33 @@ :applied-tokens applied-tokens :value (:layout-gap values)}]] - [:div {:class (stl/css :padding-row)} + [:div {:class (stl/css :padding-row :padding-section)} [:> padding-section* {:value (:layout-padding values) :type (:layout-padding-type values) :on-type-change on-padding-type-change :on-change on-padding-change}]] [:div {:class (stl/css :grid-tracks-row)} - [:> grid-columns-row* {:is-column true - :expanded? @columns-open? - :toggle toggle-columns-open - :column-values column-values - :add-new-element add-new-element - :set-column-value set-column-value - :set-column-type set-column-type - :remove-element remove-element - :reorder-track reorder-track - :hover-track hover-track - :on-select-track handle-select-track}] + [:& grid-columns-row {:is-column true + :expanded? @columns-open? + :toggle toggle-columns-open + :column-values column-values + :add-new-element add-new-element + :set-column-value set-column-value + :set-column-type set-column-type + :remove-element remove-element + :reorder-track reorder-track + :hover-track hover-track + :on-select-track handle-select-track}] - [:> grid-columns-row* {:is-column false - :expanded? @rows-open? - :toggle toggle-rows-open - :column-values rows-values - :add-new-element add-new-element - :set-column-value set-column-value - :set-column-type set-column-type - :remove-element remove-element - :reorder-track reorder-track - :hover-track hover-track - :on-select-track handle-select-track}]]])) + [:& grid-columns-row {:is-column false + :expanded? @rows-open? + :toggle toggle-rows-open + :column-values rows-values + :add-new-element add-new-element + :set-column-value set-column-value + :set-column-type set-column-type + :remove-element remove-element + :reorder-track reorder-track + :hover-track hover-track + :on-select-track handle-select-track}]]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss index c835494e8a..10247a86b1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss @@ -42,7 +42,6 @@ .flex-layout-menu { @include sidebar.option-grid-structure; - row-gap: var(--sp-s); margin-block-end: var(--sp-s); } @@ -50,6 +49,8 @@ grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; + margin-block-end: var(--sp-m); + margin-block-start: var(--sp-xs); } .align-row { @@ -60,11 +61,27 @@ grid-column: span 4; } -.middle-row { - grid-column: span 8; - display: flex; - flex-direction: column; - row-gap: var(--sp-xs); +// TODO: Replace this buttons with DS buttons +.wrap-button { + @extend .button-tertiary; + border-radius: $br-8; + block-size: $sz-32; + inline-size: $sz-32; + svg { + @extend .button-icon; + stroke: var(--color-foreground-secondary); + } + &.selected { + @extend .button-icon-selected; + } +} + +.second-row, +.third-row { + grid-column: 1 / -1; + display: grid; + grid-template-columns: subgrid; + margin-block-end: var(--sp-m); } .align-content-row, @@ -72,7 +89,7 @@ grid-column: span 6; } -.last-row { +.forth-row { display: grid; grid-template-columns: var(--grid-exception-input-width) /* first input block */ @@ -83,7 +100,9 @@ } .help-button-wrapper { + grid-column: 1 / -1; display: flex; + flex-direction: row; justify-content: space-between; } @@ -130,10 +149,23 @@ gap: var(--sp-xs); } +// TODO: Replace this buttons with DS buttons +.padding-toggle { + @extend .button-tertiary; + block-size: $sz-32; + inline-size: $sz-32; + border-radius: $br-8; + svg { + @extend .button-icon; + stroke: var(--color-foreground-secondary); + } + &.selected { + @extend .button-icon-selected; + } +} + .grid-layout-menu { @include sidebar.option-grid-structure; - margin-top: var(--sp-xs); - row-gap: var(--sp-s); } .edit-grid-wrapper, @@ -145,6 +177,7 @@ } .first-row { + margin-block-end: var(--sp-s); display: grid; grid-template-columns: subgrid; } @@ -169,12 +202,20 @@ grid-column: span 5; } +// TODO: Replace this buttons with DS buttons .edit-mode-btn { - justify-content: center; + @extend .button-secondary; + @include t.use-typography("headline-small"); + inline-size: 100%; + padding: var(--sp-s); grid-column: span 7; } +// TODO: Replace this buttons with DS buttons .exit-btn { + @extend .button-secondary; + @include t.use-typography("headline-small"); + padding: var(--sp-s) var(--sp-xl); grid-column: span 2; } @@ -186,11 +227,14 @@ margin-block-start: var(--sp-xs); } +.padding-section { + margin-block-start: var(--sp-s); +} + .grid-tracks-row { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; - row-gap: var(--sp-s); } .edit-grid-wrapper { @@ -249,6 +293,7 @@ display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; + margin-block-start: var(--sp-s); } .grid-track-header { @@ -259,7 +304,7 @@ border-radius: $br-8; overflow: hidden; background: var(--color-background-tertiary); - block-size: $sz-48; + block-size: px2rem(52); grid-column: 1 / -1; } @@ -283,14 +328,44 @@ color: var(--color-foreground-secondary); } +// TODO: Replace this buttons with DS buttons .expand-icon { - block-size: $sz-48; + @extend .button-secondary; + block-size: px2rem(52); + border-radius: $br-8 0 0 $br-8; + border-inline-end: $b-1 solid var(--color-background-primary); + svg { + @extend .button-icon; + stroke: var(--color-foreground-secondary); + fill: var(--color-foreground-secondary); + } + &:hover, + &:active { + svg { + stroke: var(--color-accent-primary); + fill: var(--color-accent-primary); + } + } } +// TODO: Replace this buttons with DS buttons .add-column { - block-size: $sz-48; - border-radius: 0 $br-8 $br-8 0; + @extend .button-tertiary; + block-size: px2rem(52); + + svg { + display: flex; + justify-content: center; + align-items: center; + color: transparent; + fill: none; + stroke-width: px2rem(1); + block-size: $sz-12; + inline-size: $sz-12; + stroke: var(--color-foreground-secondary); + fill: var(--color-foreground-secondary); + } } .layout-options { diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs index c7c2bd9193..dd6c661030 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs @@ -17,9 +17,8 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.numeric-input :as deprecated-input] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.title-bar :refer [title-bar*]] - [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.icons :as deprecated-icon] [app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]] @@ -417,85 +416,104 @@ (= type :multiple) [:> margin-multiple* props])] - [:> icon-button* {:variant "ghost" - :aria-pressed (= type :multiple) - :aria-label (tr "workspace.layout-grid.editor.margin.expand") - :on-click on-type-change' - :icon i/margin}]])) + [:button {:class (stl/css-case + :margin-mode true + :selected (= type :multiple)) + :title "Margin - multiple" + :on-click on-type-change'} + deprecated-icon/margin]])) -(mf/defc element-behaviour-horizontal* - {::mf/private true} +(mf/defc element-behaviour-horizontal + {::mf/props :obj + ::mf/private true} [{:keys [^boolean is-auto ^boolean has-fill value on-change]}] - [:div {:class (stl/css-case :horizontal-behaviour true - :one-element (and (not has-fill) (not is-auto)) - :two-element (or has-fill is-auto) - :three-element (and has-fill is-auto))} - [:> radio-buttons* {:selected (d/name value) - :on-change on-change - :name "flex-behaviour-h" - :options (remove nil? - [{:id "behaviour-h-fix" - :icon i/fixed-width - :label (tr "workspace.layout-item.fix-width") - :value "fix"} - (when has-fill - {:id "behaviour-h-fill" - :icon i/fill-content - :label (tr "workspace.layout-item.width-100") - :value "fill"}) - (when is-auto - {:id "behaviour-h-auto" - :icon i/hug-content - :label (tr "workspace.layout-item.fit-content-horizontal") - :value "auto"})])}]]) + [:div {:class (stl/css-case + :horizontal-behaviour true + :one-element (and (not has-fill) (not is-auto)) + :two-element (or has-fill is-auto) + :three-element (and has-fill is-auto))} + [:& radio-buttons + {:selected (d/name value) + :decode-fn keyword + :on-change on-change + :name "flex-behaviour-h"} -(mf/defc element-behaviour-vertical* - {::mf/private true} + [:& radio-button + {:value "fix" + :icon i/fixed-width + :title "Fix width" + :id "behaviour-h-fix"}] + + (when has-fill + [:& radio-button + {:value "fill" + :icon i/fill-content + :title "Width 100%" + :id "behaviour-h-fill"}]) + (when is-auto + [:& radio-button + {:value "auto" + :icon i/hug-content + :title "Fit content (Horizontal)" + :id "behaviour-h-auto"}])]]) + +(mf/defc element-behaviour-vertical + {::mf/props :obj + ::mf/private true} [{:keys [^boolean is-auto ^boolean has-fill value on-change]}] - [:div {:class (stl/css-case :vertical-behaviour true - :one-element (and (not has-fill) (not is-auto)) - :two-element (or has-fill is-auto) - :three-element (and has-fill is-auto))} - [:> radio-buttons* {:selected (d/name value) - :on-change on-change - :name "flex-behaviour-v" - :options (remove nil? - [{:id "behaviour-v-fix" - :icon i/fixed-width - :label (tr "workspace.layout-item.fix-height") - :class (stl/css :rotated) - :value "fix"} - (when has-fill - {:id "behaviour-v-fill" - :icon i/fill-content - :label (tr "workspace.layout-item.height-100") - :class (stl/css :rotated) - :value "fill"}) - (when is-auto - {:id "behaviour-v-auto" - :icon i/hug-content - :label (tr "workspace.layout-item.fit-content-vertical") - :class (stl/css :rotated) - :value "auto"})])}]]) + [:div {:class (stl/css-case + :vertical-behaviour true + :one-element (and (not has-fill) (not is-auto)) + :two-element (or has-fill is-auto) + :three-element (and has-fill is-auto))} + [:& radio-buttons + {:selected (d/name value) + :decode-fn keyword + :on-change on-change + :name "flex-behaviour-v"} + [:& radio-button + {:value "fix" + :icon i/fixed-width + :icon-class (stl/css :rotated) + :title "Fix height" + :id "behaviour-v-fix"}] -(mf/defc align-self-row* + (when has-fill + [:& radio-button + {:value "fill" + :icon i/fill-content + :icon-class (stl/css :rotated) + :title "Height 100%" + :id "behaviour-v-fill"}]) + (when is-auto + [:& radio-button + {:value "auto" + :icon i/hug-content + :icon-class (stl/css :rotated) + :title "Fit content (Vertical)" + :id "behaviour-v-auto"}])]]) + +(mf/defc align-self-row + {::mf/props :obj} [{:keys [^boolean is-col value on-change]}] - [:> radio-buttons* {:selected (d/name value) - :name "flex-align-self" - :on-change on-change - :allow-empty true - :options [{:id "align-self-start" - :icon (get-layout-flex-icon :align-self :start is-col) - :label "Align self start" - :value "start"} - {:id "align-self-center" - :icon (get-layout-flex-icon :align-self :center is-col) - :label "Align self center" - :value "center"} - {:id "align-self-end" - :icon (get-layout-flex-icon :align-self :end is-col) - :label "Align self end" - :value "end"}]}]) + [:& radio-buttons {:selected (d/name value) + :decode-fn keyword + :on-change on-change + :name "flex-align-self" + :allow-empty true} + [:& radio-button {:value "start" + :icon (get-layout-flex-icon :align-self :start is-col) + :title "Align self start" + :id "align-self-start"}] + [:& radio-button {:value "center" + :icon (get-layout-flex-icon :align-self :center is-col) + :title "Align self center" + :id "align-self-center"}] + [:& radio-button {:value "end" + :icon (get-layout-flex-icon :align-self :end is-col) + :title "Align self end" + :id "align-self-end"}]]) + (def ^:private schema:layout-item-props-schema [:map @@ -772,10 +790,9 @@ (mf/use-fn (mf/deps ids align-self) (fn [value] - (let [value (keyword value)] - (if (= align-self value) - (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil})) - (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value})))))) + (if (= align-self value) + (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil})) + (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value}))))) ;; Margin on-margin-type-change @@ -803,23 +820,22 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing (keyword value)})))) + (st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value})))) on-behaviour-v-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing (keyword value)})))) + (st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value})))) ;; Position on-change-position (mf/use-fn (mf/deps ids) (fn [value] - (let [value (keyword value)] - (when (= value :static) - (st/emit! (dwsl/update-layout-child ids {:layout-item-z-index nil}))) - (st/emit! (dwsl/update-layout-child ids {:layout-item-absolute (= value :absolute)}))))) + (when (= value :static) + (st/emit! (dwsl/update-layout-child ids {:layout-item-z-index nil}))) + (st/emit! (dwsl/update-layout-child ids {:layout-item-absolute (= value :absolute)})))) ;; Z Index on-change-z-index @@ -841,17 +857,16 @@ [:div {:class (stl/css :flex-element-menu)} (when (or is-layout-child? is-absolute?) [:div {:class (stl/css :position-row)} - [:> radio-buttons* {:class (stl/css :position-options) - :selected (if is-absolute? "absolute" "static") + [:div {:class (stl/css :position-options)} + [:& radio-buttons {:selected (if is-absolute? "absolute" "static") + :decode-fn keyword :on-change on-change-position :name "layout-style" - :extended true - :options [{:id "static-position" - :label "Static" - :value "static"} - {:id "absolute-position" - :label "Absolute" - :value "absolute"}]}] + :wide true} + [:& radio-button {:value "static" + :id :static-position}] + [:& radio-button {:value "absolute" + :id :absolute-position}]]] [:div {:class (stl/css :z-index-wrapper) :title "z-index"} @@ -870,20 +885,22 @@ :behaviour-menu true :wrap (and ^boolean is-layout-child? ^boolean is-layout-container?))} - [:> element-behaviour-horizontal* {:is-auto is-layout-container? - :has-fill is-layout-child? - :value (:layout-item-h-sizing values) - :on-change on-behaviour-h-change}] - [:> element-behaviour-vertical* {:is-auto is-layout-container? - :has-fill is-layout-child? - :value (:layout-item-v-sizing values) - :on-change on-behaviour-v-change}]]] + [:& element-behaviour-horizontal + {:is-auto is-layout-container? + :has-fill is-layout-child? + :value (:layout-item-h-sizing values) + :on-change on-behaviour-h-change}] + [:& element-behaviour-vertical + {:is-auto is-layout-container? + :has-fill is-layout-child? + :value (:layout-item-v-sizing values) + :on-change on-behaviour-v-change}]]] (when (and is-layout-child? is-flex-parent?) [:div {:class (stl/css :align-row)} - [:> align-self-row* {:is-col is-col? - :value align-self - :on-change on-align-self-change}]]) + [:& align-self-row {:is-col is-col? + :value align-self + :on-change on-align-self-change}]]) (when is-layout-child? [:> margin-section* {:value (:layout-item-margin values) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.scss index de7d7e542e..d54b68e918 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.scss @@ -34,8 +34,10 @@ grid-template-columns: auto auto; } -.rotated { - transform: rotate(90deg); +.vertical-behaviour { + .rotated { + transform: rotate(90deg); + } } .z-index-wrapper { @@ -72,6 +74,18 @@ gap: var(--sp-xs); } +.margin-mode { + @extend .button-tertiary; + grid-column: 3; + height: deprecated.$s-32; + svg { + @extend .button-icon; + } + &.selected { + @extend .button-icon-selected; + } +} + .margin-simple { display: grid; gap: var(--sp-xs); diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index 85000c49e9..769f7910f1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -25,9 +25,9 @@ [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.numeric-input :as deprecated-input] + [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.radio-buttons :refer [radio-buttons*]] - [app.main.ui.ds.foundations.assets.icon :as i] + [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] [app.main.ui.icons :as deprecated-icon] [app.main.ui.workspace.sidebar.options.menus.border-radius :refer [border-radius-menu*]] [app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]] @@ -209,6 +209,12 @@ proportion-lock (get values :proportion-lock) + clip-content-ref + (mf/use-ref nil) + + show-in-viewer-ref + (mf/use-ref nil) + ;; PRESETS preset-state* (mf/use-state false) @@ -327,19 +333,19 @@ ;; CLIP CONTENT AND SHOW IN VIEWER on-change-clip-content (mf/use-fn - (mf/deps ids values) - (fn [] - (let [value (not (:show-content values))] - (st/emit! (dwsh/update-shapes ids (fn [shape] (assoc shape :show-content value))))))) + (mf/deps ids) + (fn [event] + (let [value (-> event dom/get-target dom/checked?)] + (st/emit! (dwsh/update-shapes ids (fn [shape] (assoc shape :show-content (not value)))))))) on-change-show-in-viewer (mf/use-fn - (mf/deps ids values) - (fn [] - (let [value (not (:hide-in-viewer values)) + (mf/deps ids) + (fn [event] + (let [value (-> event dom/get-target dom/checked?) undo-id (js/Symbol)] (st/emit! (dwu/start-undo-transaction undo-id) - (dwsh/update-shapes ids (fn [shape] (cls/change-show-in-viewer shape value)))) + (dwsh/update-shapes ids (fn [shape] (cls/change-show-in-viewer shape (not value))))) (when-not value ;; when a frame is no longer shown in view mode, cannot @@ -388,23 +394,22 @@ (when preset-match [:span {:class (stl/css :check-icon)} deprecated-icon/tick])])))]]] - [:> radio-buttons* {:class (stl/css :radio-buttons) - :selected (or (d/name orientation) "") - :on-change on-orientation-change - :name "frame-orientation" - :options [{:id "size-vertical" - :icon i/size-vertical - :label (tr "workspace.options.orientation.vertical") - :value "vert"} - {:id "size-horizontal" - :icon i/size-horizontal - :label (tr "workspace.options.orientation.horizontal") - :value "horiz"}]}] - - [:> icon-button* {:variant "ghost" - :aria-label (tr "workspace.options.fit-content") - :on-pointer-down handle-fit-content - :icon i/fit-content}]]) + [:& radio-buttons {:selected (or (d/name orientation) "") + :on-change on-orientation-change + :name "frame-orientation" + :wide true + :class (stl/css :radio-buttons)} + [:& radio-button {:icon i/size-vertical + :value "vert" + :id "size-vertical"}] + [:& radio-button {:icon i/size-horizontal + :value "horiz" + :id "size-horizontal"}]] + [:> icon-button* + {:variant "ghost" + :aria-label (tr "workspace.options.fit-content") + :on-pointer-down handle-fit-content + :icon i/fit-content}]]) (when (options :size) [:div {:class (stl/css :size)} @@ -464,8 +469,8 @@ [:> icon-button* {:variant "ghost" :tooltip-placement "top-left" :icon (if proportion-lock "lock" "unlock") + :class (stl/css-case :selected (true? proportion-lock)) :disabled (= proportion-lock :multiple) - :aria-pressed (true? proportion-lock) :aria-label (if proportion-lock (tr "workspace.options.size.unlock") (tr "workspace.options.size.lock")) :on-click on-proportion-lock-change}]]) @@ -553,24 +558,41 @@ :on-change on-rotation-change :class (stl/css :numeric-input) :value (:rotation values)}]])) + (when (options :radius) [:> border-radius-menu* {:class (stl/css :border-radius) :ids ids :values values :applied-tokens applied-tokens}])]) - (when (or (options :clip-content) - (options :show-in-viewer)) + + (when (or (options :clip-content) (options :show-in-viewer)) [:div {:class (stl/css :clip-show)} (when (options :clip-content) - [:> icon-button* {:variant "ghost" - :aria-pressed (not (:show-content values)) - :aria-label (tr "workspace.options.clip-content") - :on-click on-change-clip-content - :icon i/clip-content}]) + [:div {:class (stl/css :clip-content)} + [:input {:type "checkbox" + :id "clip-content" + :ref clip-content-ref + :class (stl/css :clip-content-input) + :checked (not (:show-content values)) + :on-change on-change-clip-content}] + [:label {:for "clip-content" + :title (tr "workspace.options.clip-content") + :class (stl/css-case :clip-content-label true + :selected (not (:show-content values)))} + + [:> icon* {:icon-id i/clip-content}]]]) (when (options :show-in-viewer) - [:> icon-button* {:variant "ghost" - :aria-pressed (not (:hide-in-viewer values)) - :aria-label (tr "workspace.options.show-in-viewer") - :on-click on-change-show-in-viewer - :icon i/play}])])])) + [:div {:class (stl/css :show-in-viewer)} + [:input {:type "checkbox" + :id "show-in-viewer" + :ref show-in-viewer-ref + :class (stl/css :clip-content-input) + :checked (not (:hide-in-viewer values)) + :on-change on-change-show-in-viewer}] + + [:label {:for "show-in-viewer" + :title (tr "workspace.options.show-in-viewer") + :class (stl/css-case :clip-content-label true + :selected (not (:hide-in-viewer values)))} + [:> icon* {:icon-id i/play}]]])])])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.scss index dbc3074281..e214e0f636 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.scss @@ -145,6 +145,16 @@ grid-column: 2/-1; } +.lock-size-btn { + @extend .button-tertiary; + border-radius: deprecated.$br-8; + height: deprecated.$s-32; + width: deprecated.$s-28; + &.selected { + @extend .button-icon-selected; + } +} + .lock-ratio-icon { @extend .button-icon; stroke: var(--icon-foreground); @@ -156,3 +166,30 @@ justify-content: flex-start; gap: deprecated.$s-4; } + +.clip-content, +.show-in-viewer { + .clip-content-input { + display: none; + } +} + +.clip-content-label { + @extend .button-tertiary; + height: var(--sp-xxxl); + width: var(--sp-xxxl); + border-radius: deprecated.$br-8; +} + +.selected { + @extend .button-icon-selected; +} + +.checkbox-button { + @extend .button-icon; +} + +// TODO: Add a proper variable to this sizing +.numeric-input-measures { + --dropdown-width: var(--7-columns-dropdown-width); +} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs index bdb948cc22..3135a815bc 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs @@ -19,15 +19,15 @@ [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.context :as ctx] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.hooks :as hooks] [app.main.ui.icons :as deprecated-icon] - [app.main.ui.workspace.sidebar.options.menus.typography :refer [text-options* - typography-entry*]] + [app.main.ui.workspace.sidebar.options.menus.typography :refer [text-options + typography-entry]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.text.content :as content] @@ -37,99 +37,96 @@ [potok.v2.core :as ptk] [rumext.v2 :as mf])) -(mf/defc text-align-options* - [{:keys [values on-change on-blur]}] +(mf/defc text-align-options + [{:keys [values on-change on-blur] :as props}] (let [{:keys [text-align]} values - handle-change (mf/use-fn (mf/deps on-change on-blur) (fn [value] (on-change {:text-align value}) - (when (some? on-blur) - (on-blur))))] + (when (some? on-blur) (on-blur))))] - [:> radio-buttons* {:class (stl/css :align-options) - :selected text-align + ;; --- Align + [:div {:class (stl/css :align-options)} + [:& radio-buttons {:selected text-align :on-change handle-change - :name "align-text-options" - :options [{:id "text-align-left" - :icon i/text-align-left - :label (tr "workspace.options.text-options.text-align-left") - :value "left"} - {:id "text-align-center" - :icon i/text-align-center - :label (tr "workspace.options.text-options.text-align-center") - :value "center"} - {:id "text-align-right" - :icon i/text-align-right - :label (tr "workspace.options.text-options.text-align-right") - :value "right"} - {:id "text-align-justify" - :icon i/text-justify - :label (tr "workspace.options.text-options.text-align-justify") - :value "justify"}]}])) + :name "align-text-options"} + [:& radio-button {:value "left" + :id "text-align-left" + :title (tr "workspace.options.text-options.text-align-left") + :icon i/text-align-left}] + [:& radio-button {:value "center" + :id "text-align-center" + :title (tr "workspace.options.text-options.text-align-center") + :icon i/text-align-center}] + [:& radio-button {:value "right" + :id "text-align-right" + :title (tr "workspace.options.text-options.text-align-right") + :icon i/text-align-right}] + [:& radio-button {:value "justify" + :id "text-align-justify" + :title (tr "workspace.options.text-options.text-align-justify") + :icon i/text-justify}]]])) -(mf/defc text-direction-options* - [{:keys [values on-change on-blur]}] +(mf/defc text-direction-options + [{:keys [values on-change on-blur] :as props}] (let [direction (:text-direction values) - handle-change (mf/use-fn (mf/deps on-change on-blur direction) (fn [value] - (let [dir (if (= value direction) "none" value)] + (let [dir (if (= value direction) + "none" + value)] (on-change {:text-direction dir}) - (when (some? on-blur) - (on-blur)))))] + (when (some? on-blur) (on-blur)))))] - [:> radio-buttons* {:class (stl/css :text-direction-options) - :selected direction + [:div {:class (stl/css :text-direction-options)} + [:& radio-buttons {:selected direction :on-change handle-change - :allow-empty true - :name "text-direction-options" - :options [{:id "ltr-text-direction" - :icon i/text-ltr - :label (tr "workspace.options.text-options.direction-ltr") - :value "ltr"} - {:id "rtl-text-direction" - :icon i/text-rtl - :label (tr "workspace.options.text-options.direction-rtl") - :value "rtl"}]}])) + :name "text-direction-options"} + [:& radio-button {:value "ltr" + :type "checkbox" + :id "ltr-text-direction" + :title (tr "workspace.options.text-options.direction-ltr") + :icon i/text-ltr}] + [:& radio-button {:value "rtl" + :type "checkbox" + :id "rtl-text-direction" + :title (tr "workspace.options.text-options.direction-rtl") + :icon i/text-rtl}]]])) -(mf/defc vertical-align* - [{:keys [values on-change on-blur]}] +(mf/defc vertical-align + [{:keys [values on-change on-blur] :as props}] (let [{:keys [vertical-align]} values - vertical-align (or vertical-align "top") - handle-change (mf/use-fn (mf/deps on-change on-blur) (fn [value] (on-change {:vertical-align value}) - (when (some? on-blur) - (on-blur))))] + (when (some? on-blur) (on-blur))))] - [:> radio-buttons* {:class (stl/css :vertical-align-options) - :selected vertical-align + [:div {:class (stl/css :vertical-align-options)} + [:& radio-buttons {:selected vertical-align :on-change handle-change - :name "vertical-align-text-options" - :options [{:id "vertical-text-align-top" - :icon i/text-top - :label (tr "workspace.options.text-options.align-top") - :value "top"} - {:id "vertical-text-align-center" - :icon i/text-middle - :label (tr "workspace.options.text-options.align-middle") - :value "center"} - {:id "vertical-text-align-bottom" - :icon i/text-bottom - :label (tr "workspace.options.text-options.align-bottom") - :value "bottom"}]}])) + :name "vertical-align-text-options"} + [:& radio-button {:value "top" + :id "vertical-text-align-top" + :title (tr "workspace.options.text-options.align-top") + :icon i/text-top}] + [:& radio-button {:value "center" + :id "vertical-text-align-center" + :title (tr "workspace.options.text-options.align-middle") + :icon i/text-middle}] + [:& radio-button {:value "bottom" + :id "vertical-text-align-bottom" + :title (tr "workspace.options.text-options.align-bottom") + :icon i/text-bottom}]]])) -(mf/defc grow-options* - [{:keys [ids values on-blur]}] +(mf/defc grow-options + [{:keys [ids values on-blur] :as props}] (let [grow-type (:grow-type values) editor-instance (mf/deref refs/workspace-editor) @@ -152,56 +149,55 @@ (st/emit! (dwwt/resize-wasm-text-all ids))) ;; We asynchronously commit so every sychronous event is resolved first and inside the transaction (ts/schedule #(st/emit! (dwu/commit-undo-transaction uid)))) - (when (some? on-blur) - (on-blur))))] + (when (some? on-blur) (on-blur))))] - [:> radio-buttons* {:class (stl/css :grow-options) - :selected (d/name grow-type) + [:div {:class (stl/css :grow-options)} + [:& radio-buttons {:selected (d/name grow-type) :on-change handle-change-grow - :name "grow-text-options" - :options [{:id "text-fixed-grow" - :icon i/text-fixed - :label (tr "workspace.options.text-options.grow-fixed") - :value "fixed"} - {:id "text-auto-width-grow" - :icon i/text-auto-width - :label (tr "workspace.options.text-options.grow-auto-width") - :value "auto-width"} - {:id "text-auto-height-grow" - :icon i/text-auto-height - :label (tr "workspace.options.text-options.grow-auto-height") - :value "auto-height"}]}])) + :name "grow-text-options"} + [:& radio-button {:value "fixed" + :id "text-fixed-grow" + :title (tr "workspace.options.text-options.grow-fixed") + :icon i/text-fixed}] + [:& radio-button {:value "auto-width" + :id "text-auto-width-grow" + :title (tr "workspace.options.text-options.grow-auto-width") + :icon i/text-auto-width}] + [:& radio-button {:value "auto-height" + :id "text-auto-height-grow" + :title (tr "workspace.options.text-options.grow-auto-height") + :icon i/text-auto-height}]]])) -(mf/defc text-decoration-options* - [{:keys [values on-change on-blur]}] +(mf/defc text-decoration-options + [{:keys [values on-change on-blur] :as props}] (let [text-decoration (or (:text-decoration values) "none") - handle-change (mf/use-fn (mf/deps on-change on-blur text-decoration) (fn [value] - (let [decoration (if (= value text-decoration) "none" value)] + (let [decoration (if (= value text-decoration) + "none" + value)] (on-change {:text-decoration decoration}) - (when (some? on-blur) - (on-blur)))))] - - [:> radio-buttons* {:class (stl/css :text-decoration-options) - :selected text-decoration + (when (some? on-blur) (on-blur)))))] + [:div {:class (stl/css :text-decoration-options)} + [:& radio-buttons {:selected text-decoration :on-change handle-change - :name "grow-text-options" - :allow-empty true - :options [{:id "underline-text-decoration" - :icon i/text-underlined - :label (tr "workspace.options.text-options.underline" (sc/get-tooltip :underline)) - :value "underline"} - {:id "line-through-text-decoration" - :icon i/text-stroked - :label (tr "workspace.options.text-options.strikethrough" (sc/get-tooltip :line-through)) - :value "line-through"}]}])) + :name "text-decoration-options"} + [:& radio-button {:value "underline" + :type "checkbox" + :id "underline-text-decoration" + :title (tr "workspace.options.text-options.underline" (sc/get-tooltip :underline)) + :icon i/text-underlined}] + [:& radio-button {:value "line-through" + :type "checkbox" + :id "line-through-text-decoration" + :title (tr "workspace.options.text-options.strikethrough" (sc/get-tooltip :line-through)) + :icon i/text-stroked}]]])) -(mf/defc text-menu* +(mf/defc text-menu {::mf/wrap [mf/memo]} - [{:keys [ids type values]}] + [{:keys [ids type values] :as props}] (let [file-id (mf/use-ctx ctx/current-file-id) typographies (mf/deref refs/workspace-file-typography) @@ -294,19 +290,18 @@ multiple? (->> values vals (d/seek #(= % :multiple))) - props - (mf/props {:ids ids - :values values - :on-change on-change - :show-recent true - :on-blur - (fn [] - (ts/schedule - 100 - (fn [] - (when (not= "INPUT" (-> (dom/get-active) (dom/get-tag-name))) - (let [node (txu/get-text-editor-content)] - (dom/focus! node))))))})] + opts #js {:ids ids + :values values + :on-change on-change + :show-recent true + :on-blur + (fn [] + (ts/schedule + 100 + (fn [] + (when (not= "INPUT" (-> (dom/get-active) (dom/get-tag-name))) + (let [node (txu/get-text-editor-content)] + (dom/focus! node))))))}] (hooks/use-stream expand-stream #(swap! state* assoc-in [:more-options] true)) @@ -328,11 +323,11 @@ [:div {:class (stl/css :element-content)} (cond typography - [:> typography-entry* {:file-id typography-file-id - :typography typography - :local? (= typography-file-id file-id) - :on-detach handle-detach-typography - :on-change handle-change-typography}] + [:& typography-entry {:file-id typography-file-id + :typography typography + :local? (= typography-file-id file-id) + :on-detach handle-detach-typography + :on-change handle-change-typography}] (= typography-id :multiple) [:div {:class (stl/css :multiple-typography)} @@ -343,20 +338,19 @@ deprecated-icon/detach]] :else - [:> text-options* props]) + [:> text-options opts]) [:div {:class (stl/css :text-align-options)} - [:> text-align-options* props] - [:> grow-options* props] + [:> text-align-options opts] + [:> grow-options opts] [:> icon-button* {:variant "ghost" :aria-label (tr "labels.options") - :aria-pressed more-options-open? :data-testid "text-align-options-button" :on-click toggle-more-options :icon i/menu}]] (when more-options-open? - [:div {:class (stl/css :text-decoration-options)} - [:> vertical-align* props] - [:> text-decoration-options* props] - [:> text-direction-options* props]])])])) + [:div {:class (stl/css :text-decoration-options)} + [:> vertical-align opts] + [:> text-decoration-options opts] + [:> text-direction-options opts]])])])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs index fc1d60c34a..940682be89 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs @@ -22,10 +22,10 @@ [app.main.store :as st] [app.main.ui.components.editable-select :refer [editable-select]] [app.main.ui.components.numeric-input :refer [numeric-input*]] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.components.search-bar :refer [search-bar*]] [app.main.ui.components.select :refer [select]] [app.main.ui.context :as ctx] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.icons :as deprecated-icon] [app.util.dom :as dom] @@ -424,24 +424,27 @@ (on-change {:text-transform type})) (when (some? on-blur) (on-blur)))] - [:> radio-buttons* {:selected text-transform + [:div {:class (stl/css :text-transform)} + [:& radio-buttons {:selected text-transform :on-change handle-change - :name "text-transform" - :allow-empty true - :options [{:id "text-transform-uppercase" - :icon i/text-uppercase - :label (tr "inspect.attributes.typography.text-transform.uppercase") - :value "uppercase"} - {:id "text-transform-capitalize" - :icon i/text-mixed - :label (tr "inspect.attributes.typography.text-transform.capitalize") - :value "capitalize"} - {:id "text-transform-lowercase" - :icon i/text-lowercase - :label (tr "inspect.attributes.typography.text-transform.lowercase") - :value "lowercase"}]}])) + :name "text-transform"} + [:& radio-button {:icon i/text-uppercase + :type "checkbox" + :title (tr "inspect.attributes.typography.text-transform.uppercase") + :value "uppercase" + :id "text-transform-uppercase"}] + [:& radio-button {:icon i/text-mixed + :type "checkbox" + :value "capitalize" + :title (tr "inspect.attributes.typography.text-transform.capitalize") + :id "text-transform-capitalize"}] + [:& radio-button {:icon i/text-lowercase + :type "checkbox" + :title (tr "inspect.attributes.typography.text-transform.lowercase") + :value "lowercase" + :id "text-transform-lowercase"}]]])) -(mf/defc text-options* +(mf/defc text-options {::mf/wrap-props false} [{:keys [ids editor values on-change on-blur show-recent]}] (let [full-size-selector? (and show-recent (= (mf/use-ctx ctx/sidebar) :right)) @@ -499,13 +502,14 @@ :on-click on-close} deprecated-icon/tick]] - [:> text-options* {:values typography - :on-change on-change - :show-recent false}]] + [:& text-options {:values typography + :on-change on-change + :show-recent false}]] [:div {:class (stl/css :typography-info-wrapper)} [:div {:class (stl/css :typography-name-wrapper)} [:div {:class (stl/css :typography-sample) + :style {:font-family (:font-family typography) :font-weight (:font-weight typography) :font-style (:font-style typography)}} @@ -545,7 +549,7 @@ :on-click navigate-to-library} (tr "workspace.assets.typography.go-to-edit")])])]))) -(mf/defc typography-entry* +(mf/defc typography-entry {::mf/wrap-props false} [{:keys [file-id typography local? selected? on-click on-change on-detach on-context-menu editing? renaming? focus-name? external-open*]}] (let [name-input-ref (mf/use-ref) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.scss index b5c5ebaa62..506fb58b34 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.scss @@ -324,6 +324,15 @@ } } } + .text-transform { + @extend .asset-element; + width: fit-content; + padding: 0; + background-color: var(--radio-btns-background-color); + &:hover { + background-color: var(--radio-btns-background-color); + } + } } } diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/shadow_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/rows/shadow_row.cljs index 4b2fb0f4f7..48a8b8ca0d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/shadow_row.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/shadow_row.cljs @@ -141,9 +141,8 @@ [:> icon-button* {:variant "secondary" :icon i/menu :class (stl/css-case :shadow-basic-button true - :hidden hidden?) - :aria-pressed is-open - :aria-label (tr "labels.options") + :selected is-open) + :aria-label "open more options" :disabled hidden? :on-click on-toggle-open}] [:& select {:class (stl/css :shadow-basic-select) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/shadow_row.scss b/frontend/src/app/main/ui/workspace/sidebar/options/rows/shadow_row.scss index b4355228d9..f13404d03e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/shadow_row.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/shadow_row.scss @@ -43,8 +43,14 @@ .shadow-basic-button { border-radius: $br-8 0 0 $br-8; - &.hidden { - border: deprecated.$s-1 solid var(--input-border-color-disabled); + + &.selected { + --button-bg-color: var(--color-background-quaternary); + --button-fg-color: var(--color-accent-primary); + } + + &:disabled { + border: $b-1 solid var(--color-background-quaternary); } } diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs index 8b7cc718a4..eaab775a8e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs @@ -171,7 +171,7 @@ [:& blur-menu {:type type :ids blur-ids :values blur-values}]) (when-not (empty? text-ids) - [:> ot/text-menu* {:type type :ids text-ids :values text-values}]) + [:& ot/text-menu {:type type :ids text-ids :values text-values}]) (when-not (empty? svg-values) [:& svg-attrs-menu {:ids ids :values svg-values}]) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs index d2a8b25720..f3c6ee2b1e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs @@ -478,7 +478,7 @@ [:& constraints-menu {:ids constraint-ids :values constraint-values}]) (when-not (empty? text-ids) - [:> ot/text-menu* {:type type :ids text-ids :values text-values}]) + [:& ot/text-menu {:type type :ids text-ids :values text-values}]) (when-not (empty? fill-ids) [:> fill/fill-menu* {:type type diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs index 8b3f66dd51..21cd88b881 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs @@ -25,7 +25,7 @@ [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu*]] + [app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu]] [rumext.v2 :as mf])) (mf/defc options* @@ -162,9 +162,10 @@ {:ids ids :values (select-keys shape constraint-attrs)}]) - [:> text-menu* {:ids ids - :type type - :values text-values}] + [:& text-menu + {:ids ids + :type type + :values text-values}] [:> fill/fill-menu* {:ids ids diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/shadow.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/shadow.cljs index 99579abab1..9bf6fa32a2 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/shadow.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/shadow.cljs @@ -12,15 +12,14 @@ [app.common.types.token :as cto] [app.common.types.tokens-lib :as ctob] [app.main.data.workspace.tokens.errors :as wte] + [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.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.forms :as forms] [app.main.ui.hooks :as hooks] [app.main.ui.workspace.tokens.management.forms.controls :as token.controls] [app.main.ui.workspace.tokens.management.forms.generic-form :as generic] - [app.main.ui.workspace.tokens.management.forms.validators :refer [check-self-reference - default-validate-token]] + [app.main.ui.workspace.tokens.management.forms.validators :refer [check-self-reference default-validate-token]] [app.util.dom :as dom] [app.util.i18n :refer [tr]] [beicon.v2.core :as rx] @@ -232,17 +231,18 @@ :aria-label (tr "workspace.tokens.shadow-add-shadow") :on-click on-add-shadow-block :icon i/add}] - [:> radio-buttons* {:selected (d/name tab) - :on-change handle-toggle - :name "reference-composite-tab" - :options [{:id "composite-opt" - :icon i/layers - :label (tr "workspace.tokens.individual-tokens") - :value "composite"} - {:id "reference-opt" - :icon i/tokens - :label (tr "workspace.tokens.use-reference") - :value "reference"}]}]] + [:& radio-buttons {:class (stl/css :listing-options) + :selected (d/name tab) + :on-change handle-toggle + :name "reference-composite-tab"} + [:& radio-button {:icon i/layers + :value "composite" + :title (tr "workspace.tokens.individual-tokens") + :id "composite-opt"}] + [:& radio-button {:icon i/tokens + :value "reference" + :title (tr "workspace.tokens.use-reference") + :id "reference-opt"}]]] (if (= tab :composite) [:> composite-form* {:token token diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/typography.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/typography.cljs index 26a50a2f50..37a7fda7ca 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/typography.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/typography.cljs @@ -12,13 +12,11 @@ [app.common.types.token :as cto] [app.common.types.tokens-lib :as ctob] [app.main.data.workspace.tokens.errors :as wte] - [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] + [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.workspace.tokens.management.forms.controls :as token.controls] [app.main.ui.workspace.tokens.management.forms.generic-form :as generic] - [app.main.ui.workspace.tokens.management.forms.validators :refer [check-coll-self-reference - check-self-reference - default-validate-token]] + [app.main.ui.workspace.tokens.management.forms.validators :refer [check-coll-self-reference check-self-reference default-validate-token]] [app.util.i18n :refer [tr]] [beicon.v2.core :as rx] [cuerdas.core :as str] @@ -187,17 +185,18 @@ [:* [:div {:class (stl/css :title-bar)} [:div {:class (stl/css :title)} (tr "labels.typography")] - [:> radio-buttons* {:selected (d/name tab) - :on-change handle-toggle - :name "reference-composite-tab" - :options [{:id "composite-opt" - :icon i/layers - :label (tr "workspace.tokens.individual-tokens") - :value "composite"} - {:id "reference-opt" - :icon i/tokens - :label (tr "workspace.tokens.use-reference") - :value "reference"}]}]] + [:& radio-buttons {:class (stl/css :listing-options) + :selected (d/name tab) + :on-change handle-toggle + :name "reference-composite-tab"} + [:& radio-button {:icon i/layers + :value "composite" + :title (tr "workspace.tokens.individual-tokens") + :id "composite-opt"}] + [:& radio-button {:icon i/tokens + :value "reference" + :title (tr "workspace.tokens.use-reference") + :id "reference-opt"}]]] [:div {:class (stl/css :inputs-wrapper)} (if (= tab :composite) [:> composite-form* {:token token diff --git a/frontend/src/app/main/ui/workspace/tokens/themes/create_modal.cljs b/frontend/src/app/main/ui/workspace/tokens/themes/create_modal.cljs index 597d4a681e..a9fa7e5998 100644 --- a/frontend/src/app/main/ui/workspace/tokens/themes/create_modal.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/themes/create_modal.cljs @@ -119,7 +119,6 @@ :on-change on-switch-theme :default-checked selected?}]] - [:div {:class (stl/css :theme-actions-row)} (let [sets-count (some-> theme :sets seq count)] [:> button* {:class (stl/css-case :sets-count-button sets-count diff --git a/frontend/src/app/main/ui/workspace/top_toolbar.cljs b/frontend/src/app/main/ui/workspace/top_toolbar.cljs index 6fc3a09d4e..54a6bca3e0 100644 --- a/frontend/src/app/main/ui/workspace/top_toolbar.cljs +++ b/frontend/src/app/main/ui/workspace/top_toolbar.cljs @@ -17,10 +17,9 @@ [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] - [app.main.ui.components.file-uploader :refer [file-uploader*]] + [app.main.ui.components.file-uploader :refer [file-uploader]] [app.main.ui.context :as ctx] - [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.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.timers :as ts] @@ -28,7 +27,7 @@ [potok.v2.core :as ptk] [rumext.v2 :as mf])) -(mf/defc image-upload* +(mf/defc image-upload {::mf/wrap [mf/memo]} [] (let [ref (mf/use-ref nil) @@ -54,17 +53,18 @@ :position (gpt/point x y)}] (st/emit! (dwm/upload-media-workspace params)))))] [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/img - :aria-label (tr "workspace.toolbar.image" (sc/get-tooltip :insert-image)) - :tooltip-placement "bottom" - :on-click on-click} - [:> file-uploader* {:input-id "image-upload" - :accept dwm/accept-image-types - :multi true - :ref ref - :on-selected on-selected}]]])) + [:button + {:title (tr "workspace.toolbar.image" (sc/get-tooltip :insert-image)) + :aria-label (tr "workspace.toolbar.image" (sc/get-tooltip :insert-image)) + :on-click on-click + :class (stl/css :main-toolbar-options-button)} + deprecated-icon/img + [:& file-uploader + {:input-id "image-upload" + :accept dwm/accept-image-types + :multi true + :ref ref + :on-selected on-selected}]]])) (def ^:private toolbar-hidden-ref (l/derived (fn [state] @@ -136,104 +136,98 @@ [:ul {:class (stl/css :main-toolbar-options) :data-testid "toolbar-options"} [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/move - :aria-pressed (and (nil? drawtool) (not edition)) - :aria-label (tr "workspace.toolbar.move" (sc/get-tooltip :move)) - :tooltip-placement "bottom" - :on-click interrupt}]] + [:button + {:title (tr "workspace.toolbar.move" (sc/get-tooltip :move)) + :aria-label (tr "workspace.toolbar.move" (sc/get-tooltip :move)) + :class (stl/css-case :main-toolbar-options-button true + :selected (and (nil? drawtool) + (not edition))) + :on-click interrupt} + deprecated-icon/move]] [:* [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/board - :aria-pressed (= drawtool :frame) - :aria-label test-tooltip-board-text - :tooltip-placement "bottom" - :on-click select-drawtool - :data-tool "frame" - :data-testid "artboard-btn"}]] + [:button + {:title test-tooltip-board-text + :aria-label (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame)) + :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :frame)) + :on-click select-drawtool + :data-tool "frame" + :data-testid "artboard-btn"} + deprecated-icon/board]] [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/rectangle - :aria-pressed (= drawtool :rect) - :aria-label (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect)) - :tooltip-placement "bottom" - :on-click select-drawtool - :data-tool "rect" - :data-testid "rect-btn"}]] + [:button + {:title (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect)) + :aria-label (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect)) + :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :rect)) + :on-click select-drawtool + :data-tool "rect" + :data-testid "rect-btn"} + deprecated-icon/rectangle]] [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/elipse - :aria-pressed (= drawtool :circle) - :aria-label (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse)) - :tooltip-placement "bottom" - :on-click select-drawtool - :data-tool "circle" - :data-testid "ellipse-btn"}]] + [:button + {:title (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse)) + :aria-label (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse)) + :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :circle)) + :on-click select-drawtool + :data-tool "circle" + :data-testid "ellipse-btn"} + deprecated-icon/elipse]] [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/text - :aria-pressed (= drawtool :text) - :aria-label (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text)) - :tooltip-placement "bottom" - :on-click select-drawtool - :data-tool "text" - :data-testid "text-btn"}]] + [:button + {:title (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text)) + :aria-label (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text)) + :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :text)) + :on-click select-drawtool + :data-tool "text"} + deprecated-icon/text]] - [:> image-upload*] + [:& image-upload] [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/curve - :aria-pressed (= drawtool :curve) - :aria-label (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve)) - :tooltip-placement "bottom" - :on-click select-drawtool - :data-tool "curve" - :data-testid "curve-btn"}]] + [:button + {:title (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve)) + :aria-label (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve)) + :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :curve)) + :on-click select-drawtool + :data-tool "curve" + :data-testid "curve-btn"} + deprecated-icon/curve]] [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/path - :aria-pressed (= drawtool :path) - :aria-label (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path)) - :tooltip-placement "bottom" - :on-click select-drawtool - :data-tool "path" - :data-testid "path-btn"}]] + [:button + {:title (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path)) + :aria-label (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path)) + :class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :path)) + :on-click select-drawtool + :data-tool "path" + :data-testid "path-btn"} + deprecated-icon/path]] (when (features/active-feature? @st/state "plugins/runtime") [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/puzzle - :aria-label (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins)) - :tooltip-placement "bottom" - :on-click #(st/emit! - (ptk/data-event ::ev/event {::ev/name "open-plugins-manager" - ::ev/origin "workspace:toolbar"}) - (modal/show :plugin-management {})) - :data-tool "plugins" - :data-testid "plugins-btn"}]]) + [:button + {:title (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins)) + :aria-label (tr "workspace.toolbar.plugins" (sc/get-tooltip :plugins)) + :class (stl/css :main-toolbar-options-button) + :on-click #(st/emit! + (ptk/data-event ::ev/event {::ev/name "open-plugins-manager" + ::ev/origin "workspace:toolbar"}) + (modal/show :plugin-management {})) + :data-tool "plugins" + :data-testid "plugins-btn"} + deprecated-icon/puzzle]]) (when *assert* [:li - [:> icon-button* {:variant "ghost" - :class (stl/css :main-toolbar-options-button) - :icon i/bug - :aria-pressed (contains? layout :debug-panel) - :aria-label (tr "workspace.toolbar.debug") - :tooltip-placement "bottom" - :on-click toggle-debug-panel}]])]] + [:button + {:title "Debugging tool" + :class (stl/css-case :main-toolbar-options-button true :selected (contains? layout :debug-panel)) + :on-click toggle-debug-panel} + deprecated-icon/bug]])]] [:button {:title (tr "workspace.toolbar.toggle-toolbar") :aria-label (tr "workspace.toolbar.toggle-toolbar") :class (stl/css :toolbar-handler) :on-click toggle-toolbar} [:div {:class (stl/css :toolbar-handler-btn)}]]]))) + + diff --git a/frontend/src/app/main/ui/workspace/top_toolbar.scss b/frontend/src/app/main/ui/workspace/top_toolbar.scss index a2837cc433..d005682878 100644 --- a/frontend/src/app/main/ui/workspace/top_toolbar.scss +++ b/frontend/src/app/main/ui/workspace/top_toolbar.scss @@ -54,7 +54,6 @@ align-items: center; margin: 0; opacity: deprecated.$op-10; - gap: var(--sp-xs); transition: opacity 0.3s ease; li { @@ -63,8 +62,21 @@ } .main-toolbar-options-button { + @extend .button-tertiary; height: deprecated.$s-36; width: deprecated.$s-36; + flex-shrink: 0; + border-radius: deprecated.$s-8; + margin: 0 deprecated.$s-2; + + svg { + @extend .button-icon; + stroke: var(--color-foreground-secondary); + } + + &.selected { + @extend .button-icon-selected; + } } .toolbar-handler { @@ -85,3 +97,7 @@ background-color: var(--palette-handler-background-color); } } + +ul.main-toolbar-panels { + display: none; +} diff --git a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs index df81896e75..1fd44b32f0 100644 --- a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs @@ -28,7 +28,6 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.css-cursors :as cur] - [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.formats :as fmt] [app.main.ui.icons :as deprecated-icon] [app.main.ui.workspace.viewport.viewport-ref :as uwvv] @@ -60,13 +59,11 @@ [:div {:class (stl/css :grid-actions-container)} [:div {:class (stl/css :grid-actions-title)} (tr "workspace.layout-grid.editor.title") " " [:span {:stl/css :board-name} (:name shape)]] - [:> button* {:variant "secondary" - :class (stl/css :action-btn) - :on-click #(st/emit! (dwge/locate-board (:id shape)))} + [:button {:class (stl/css :locate-btn) + :on-click #(st/emit! (dwge/locate-board (:id shape)))} (tr "workspace.layout-grid.editor.top-bar.locate")] - [:> button* {:variant "primary" - :class (stl/css :action-btn) - :on-click #(st/emit! (dw/clear-edition-mode))} + [:button {:class (stl/css :done-btn) + :on-click #(st/emit! (dw/clear-edition-mode))} (tr "workspace.layout-grid.editor.top-bar.done")]]]) (mf/defc grid-editor-frame diff --git a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.scss b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.scss index 76859a85ff..d0f1549cb1 100644 --- a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.scss +++ b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.scss @@ -138,8 +138,18 @@ padding-left: deprecated.$s-8; } -.action-btn { - padding: 0 var(--sp-xl); +.locate-btn { + @extend .button-secondary; + text-transform: uppercase; + padding: deprecated.$s-8 deprecated.$s-20; + font-size: deprecated.$fs-11; +} + +.done-btn { + @extend .button-primary; + text-transform: uppercase; + padding: deprecated.$s-8 deprecated.$s-20; + font-size: deprecated.$fs-11; } .close-btn { diff --git a/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs b/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs index b9be870c15..f496c4ec9b 100644 --- a/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs @@ -11,11 +11,40 @@ [app.main.data.workspace.path :as drp] [app.main.data.workspace.path.shortcuts :as sc] [app.main.store :as st] - [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.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) +(def ^:private pentool-icon + (deprecated-icon/icon-xref :pentool (stl/css :pentool-icon :pathbar-icon))) + +(def ^:private move-icon + (deprecated-icon/icon-xref :move (stl/css :move-icon :pathbar-icon))) + +(def ^:private add-icon + (deprecated-icon/icon-xref :add (stl/css :add-icon :pathbar-icon))) + +(def ^:private remove-icon + (deprecated-icon/icon-xref :remove (stl/css :remove :pathbar-icon))) + +(def ^:private merge-nodes-icon + (deprecated-icon/icon-xref :merge-nodes (stl/css :merge-nodes-icon :pathbar-icon))) + +(def ^:private join-nodes-icon + (deprecated-icon/icon-xref :join-nodes (stl/css :join-nodes-icon :pathbar-icon))) + +(def ^:private separate-nodes-icon + (deprecated-icon/icon-xref :separate-nodes (stl/css :separate-nodes-icon :pathbar-icon))) + +(def ^:private to-corner-icon + (deprecated-icon/icon-xref :to-corner (stl/css :to-corner-icon :pathbar-icon))) + +(def ^:private to-curve-icon + (deprecated-icon/icon-xref :to-curve (stl/css :to-curve-icon :pathbar-icon))) + +(def ^:private snap-nodes-icon + (deprecated-icon/icon-xref :snap-nodes (stl/css :snap-nodes-icon :pathbar-icon))) + (defn check-enabled [content selected-points] (when content (let [segments (path.segm/get-segments-with-points content selected-points) @@ -115,91 +144,76 @@ [:div {:class (stl/css :sub-actions) :data-dont-clear-path true} [:div {:class (stl/css :sub-actions-group)} + ;; Draw Mode - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/pentool - :aria-pressed (= edit-mode :draw) - :aria-label (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes)) - :tooltip-placement "bottom" - :on-click on-select-draw-mode}] + [:button {:class (stl/css-case :is-toggled (= edit-mode :draw) + :topbar-btn true) + :title (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes)) + :on-click on-select-draw-mode} + pentool-icon] + ;; Edit mode - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/move - :aria-pressed (= edit-mode :move) - :aria-label (tr "workspace.path.actions.move-nodes" (sc/get-tooltip :move-nodes)) - :tooltip-placement "bottom" - :on-click on-select-edit-mode}]] + [:button {:class (stl/css-case :is-toggled (= edit-mode :move) + :topbar-btn true) + :title (tr "workspace.path.actions.move-nodes" (sc/get-tooltip :move-nodes)) + :on-click on-select-edit-mode} + move-icon]] [:div {:class (stl/css :sub-actions-group)} ;; Add Node - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/add - :aria-label (tr "workspace.path.actions.add-node" (sc/get-tooltip :add-node)) - :tooltip-placement "bottom" - :on-click on-add-node - :disabled (not (:add-node enabled-buttons))}] + [:button {:disabled (not (:add-node enabled-buttons)) + :class (stl/css :topbar-btn) + :title (tr "workspace.path.actions.add-node" (sc/get-tooltip :add-node)) + :on-click on-add-node} + add-icon] + ;; Remove node - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/remove - :aria-label (tr "workspace.path.actions.delete-node" (sc/get-tooltip :delete-node)) - :tooltip-placement "bottom" - :on-click on-remove-node - :disabled (not (:remove-node enabled-buttons))}]] + [:button {:disabled (not (:remove-node enabled-buttons)) + :class (stl/css :topbar-btn) + :title (tr "workspace.path.actions.delete-node" (sc/get-tooltip :delete-node)) + :on-click on-remove-node} + remove-icon]] [:div {:class (stl/css :sub-actions-group)} ;; Merge Nodes - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/merge-nodes - :aria-label (tr "workspace.path.actions.merge-nodes" (sc/get-tooltip :merge-nodes)) - :tooltip-placement "bottom" - :on-click on-merge-nodes - :disabled (not (:merge-nodes enabled-buttons))}] + [:button {:disabled (not (:merge-nodes enabled-buttons)) + :class (stl/css :topbar-btn) + :title (tr "workspace.path.actions.merge-nodes" (sc/get-tooltip :merge-nodes)) + :on-click on-merge-nodes} + merge-nodes-icon] + ;; Join Nodes - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/join-nodes - :aria-label (tr "workspace.path.actions.join-nodes" (sc/get-tooltip :join-nodes)) - :tooltip-placement "bottom" - :on-click on-join-nodes - :disabled (not (:join-nodes enabled-buttons))}] + [:button {:disabled (not (:join-nodes enabled-buttons)) + :class (stl/css :topbar-btn) + :title (tr "workspace.path.actions.join-nodes" (sc/get-tooltip :join-nodes)) + :on-click on-join-nodes} + join-nodes-icon] + ;; Separate Nodes - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/separate-nodes - :aria-label (tr "workspace.path.actions.separate-nodes" (sc/get-tooltip :separate-nodes)) - :tooltip-placement "bottom" - :on-click on-separate-nodes - :disabled (not (:separate-nodes enabled-buttons))}]] + [:button {:disabled (not (:separate-nodes enabled-buttons)) + :class (stl/css :topbar-btn) + :title (tr "workspace.path.actions.separate-nodes" (sc/get-tooltip :separate-nodes)) + :on-click on-separate-nodes} + separate-nodes-icon]] [:div {:class (stl/css :sub-actions-group)} ; Make Corner - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/to-corner - :aria-label (tr "workspace.path.actions.make-corner" (sc/get-tooltip :make-corner)) - :tooltip-placement "bottom" - :on-click on-make-corner - :disabled (not (:make-corner enabled-buttons))}] - ;; Make Curve - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/to-curve - :aria-label (tr "workspace.path.actions.make-curve" (sc/get-tooltip :make-curve)) - :tooltip-placement "bottom" - :on-click on-make-curve - :disabled (not (:make-curve enabled-buttons))}]] + [:button {:disabled (not (:make-corner enabled-buttons)) + :class (stl/css :topbar-btn) + :title (tr "workspace.path.actions.make-corner" (sc/get-tooltip :make-corner)) + :on-click on-make-corner} + to-corner-icon] + ;; Make Curve + [:button {:disabled (not (:make-curve enabled-buttons)) + :class (stl/css :topbar-btn) + :title (tr "workspace.path.actions.make-curve" (sc/get-tooltip :make-curve)) + :on-click on-make-curve} + to-curve-icon]] [:div {:class (stl/css :sub-actions-group)} ;; Toggle snap - [:> icon-button* {:variant "ghost" - :class (stl/css :topbar-btn) - :icon i/snap-nodes - :aria-pressed snap-toggled - :aria-label (tr "workspace.path.actions.snap-nodes" (sc/get-tooltip :snap-nodes)) - :tooltip-placement "bottom" - :on-click on-toggle-snap}]]])) + [:button {:class (stl/css-case :is-toggled snap-toggled + :topbar-btn true) + :title (tr "workspace.path.actions.snap-nodes" (sc/get-tooltip :snap-nodes)) + :on-click on-toggle-snap} + snap-nodes-icon]]])) diff --git a/frontend/src/app/main/ui/workspace/viewport/path_actions.scss b/frontend/src/app/main/ui/workspace/viewport/path_actions.scss index d6fa360618..94c86e6a8d 100644 --- a/frontend/src/app/main/ui/workspace/viewport/path_actions.scss +++ b/frontend/src/app/main/ui/workspace/viewport/path_actions.scss @@ -34,11 +34,27 @@ align-items: center; margin: 0; opacity: deprecated.$op-10; - gap: var(--sp-xs); transition: opacity 0.3s ease; } .topbar-btn { + --pathbar-icon-color: var(--color-foreground-secondary); + @extend .button-tertiary; height: deprecated.$s-36; width: deprecated.$s-36; + flex-shrink: 0; + background-color: transparent; + border-radius: deprecated.$s-8; + border: none; + margin: 0 deprecated.$s-2; + + &.is-toggled { + --pathbar-icon-color: var(--button-radio-foreground-color-active); + background-color: var(--button-radio-background-color-active); + } + + .pathbar-icon { + @extend .button-icon; + stroke: var(--pathbar-icon-color); + } } diff --git a/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs b/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs index 8aeaf5db3d..b9f4f69cb4 100644 --- a/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs @@ -10,7 +10,6 @@ [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] [app.main.store :as st] - [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.workspace.viewport.grid-layout-editor :refer [grid-edition-actions]] [app.main.ui.workspace.viewport.path-actions :refer [path-actions*]] [app.util.i18n :as i18n :refer [tr]] @@ -35,9 +34,8 @@ [:> i18n/tr-html* {:tag-name "span" :content (tr "workspace.top-bar.view-only")}]] - [:> button* {:variant "primary" - :class (stl/css :done-btn) - :on-click handle-close-view-mode} + [:button {:class (stl/css :done-btn) + :on-click handle-close-view-mode} (tr "workspace.top-bar.read-only.done")]]])) (mf/defc path-edition-bar* diff --git a/frontend/src/app/main/ui/workspace/viewport/top_bar.scss b/frontend/src/app/main/ui/workspace/viewport/top_bar.scss index d9dd78f4fd..802dc32ab7 100644 --- a/frontend/src/app/main/ui/workspace/viewport/top_bar.scss +++ b/frontend/src/app/main/ui/workspace/viewport/top_bar.scss @@ -45,7 +45,10 @@ } .done-btn { - padding: 0 var(--sp-xl); + @extend .button-primary; + text-transform: uppercase; + padding: deprecated.$s-8 deprecated.$s-20; + font-size: deprecated.$fs-11; } .viewport-actions-no-rulers { diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 61a736188f..f4928f67f8 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -5426,10 +5426,6 @@ msgstr "Ungroup" msgid "workspace.colorpicker.color-tokens" msgstr "Color tokens" -#: src/app/main/ui/workspace/colorpicker.cljs:434 -msgid "workspace.colorpicker.get-color" -msgstr "Get color" - #: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:506 msgid "workspace.component.swap.loop-error" msgstr "Components can't be nested inside themselves." @@ -5720,10 +5716,6 @@ msgstr "Full screen" msgid "workspace.header.zoom-selected" msgstr "Zoom to selected" -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:422 -msgid "workspace.layout-grid.editor.margin.expand" -msgstr "Show 4 sided margin options" - #: src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:275, src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:859 msgid "workspace.layout-grid.editor.options.edit-grid" msgstr "Edit grid" @@ -5776,30 +5768,6 @@ msgstr "Locate" msgid "workspace.layout-grid.editor.top-bar.locate.tooltip" msgstr "Locate grid layout" -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:449 -msgid "workspace.layout-item.fit-content-horizontal" -msgstr "Fit content (Horizontal)" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:477 -msgid "workspace.layout-item.fit-content-vertical" -msgstr "Fit content (Vertical)" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:465 -msgid "workspace.layout-item.fix-height" -msgstr "Fix height" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:439 -msgid "workspace.layout-item.fix-width" -msgstr "Fix width" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:471 -msgid "workspace.layout-item.height-100" -msgstr "Height 100%" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:444 -msgid "workspace.layout-item.width-100" -msgstr "Width 100%" - #: src/app/main/ui/workspace/libraries.cljs #, unused msgid "workspace.libraries.add" @@ -6400,30 +6368,6 @@ msgstr "After delay" msgid "workspace.options.interaction-animation" msgstr "Animation" -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:616 -msgid "workspace.options.interaction-animation-direction-down" -msgstr "Down" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:593 -msgid "workspace.options.interaction-animation-direction-in" -msgstr "In" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:612 -msgid "workspace.options.interaction-animation-direction-left" -msgstr "Left" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:596 -msgid "workspace.options.interaction-animation-direction-out" -msgstr "Out" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:608 -msgid "workspace.options.interaction-animation-direction-right" -msgstr "Right" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:620 -msgid "workspace.options.interaction-animation-direction-up" -msgstr "Up" - #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:383 msgid "workspace.options.interaction-animation-dissolve" msgstr "Dissolve" @@ -6869,14 +6813,6 @@ msgstr "More color tokens" msgid "workspace.options.opacity" msgstr "Opacity" -#: src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:108, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:401 -msgid "workspace.options.orientation.horizontal" -msgstr "Horizontal" - -#: src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:104, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:397 -msgid "workspace.options.orientation.vertical" -msgstr "Vertical" - #: src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs #, unused msgid "workspace.options.position" @@ -7715,7 +7651,7 @@ msgstr "Components" msgid "workspace.sidebar.layers.filter" msgstr "Filter" -#: src/app/main/ui/workspace/sidebar/layers.cljs:310, src/app/main/ui/workspace/sidebar/layers.cljs:338 +#: src/app/main/ui/workspace/sidebar/layers.cljs:311, src/app/main/ui/workspace/sidebar/layers.cljs:339 msgid "workspace.sidebar.layers.frames" msgstr "Boards" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index daa6c2cdae..683f73d6c4 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -5407,10 +5407,6 @@ msgstr "Desagrupar" msgid "workspace.colorpicker.color-tokens" msgstr "Tokens de color" -#: src/app/main/ui/workspace/colorpicker.cljs:434 -msgid "workspace.colorpicker.get-color" -msgstr "Absorber color" - #: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:506 msgid "workspace.component.swap.loop-error" msgstr "Los componentes no pueden anidarse dentro de sí mismos." @@ -5696,12 +5692,8 @@ msgstr "Pantalla completa" msgid "workspace.header.zoom-selected" msgstr "Zoom a selección" -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:422 -msgid "workspace.layout-grid.editor.margin.expand" -msgstr "Mostrar el margen a 4 lados" - -#: src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:275, src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:859 -msgid "workspace.layout-grid.editor.options.edit-grid" +#: src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:274, src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:276, src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:868 +msgid "workspace.layout_grid.editor.options.edit-grid" msgstr "Editar rejilla" #: src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:1539 @@ -5752,30 +5744,6 @@ msgstr "Mostrar" msgid "workspace.layout-grid.editor.top-bar.locate.tooltip" msgstr "Mostrar grid layout" -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:449 -msgid "workspace.layout-item.fit-content-horizontal" -msgstr "Ajustar contenido (horizontal)" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:477 -msgid "workspace.layout-item.fit-content-vertical" -msgstr "Ajustar contenido (vertical)" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:465 -msgid "workspace.layout-item.fix-height" -msgstr "Fijar altura" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:439 -msgid "workspace.layout-item.fix-width" -msgstr "Fijar anchura" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:471 -msgid "workspace.layout-item.height-100" -msgstr "Altura 100%" - -#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:444 -msgid "workspace.layout-item.width-100" -msgstr "Anchura 100%" - #: src/app/main/ui/workspace/libraries.cljs #, unused msgid "workspace.libraries.add" @@ -6340,30 +6308,6 @@ msgstr "Tiempo" msgid "workspace.options.interaction-animation" msgstr "Animación" -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:616 -msgid "workspace.options.interaction-animation-direction-down" -msgstr "Abajo" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:593 -msgid "workspace.options.interaction-animation-direction-in" -msgstr "Dentro" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:612 -msgid "workspace.options.interaction-animation-direction-left" -msgstr "Izquierda" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:596 -msgid "workspace.options.interaction-animation-direction-out" -msgstr "Fuera" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:608 -msgid "workspace.options.interaction-animation-direction-right" -msgstr "Derecha" - -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:620 -msgid "workspace.options.interaction-animation-direction-up" -msgstr "Arriba" - #: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:383 msgid "workspace.options.interaction-animation-dissolve" msgstr "Disolver" @@ -6809,14 +6753,6 @@ msgstr "Más tokens de color" msgid "workspace.options.opacity" msgstr "Opacidad" -#: src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:108, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:401 -msgid "workspace.options.orientation.horizontal" -msgstr "Horizontal" - -#: src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:104, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:397 -msgid "workspace.options.orientation.vertical" -msgstr "Vertical" - #: src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs, src/app/main/ui/workspace/sidebar/options/menus/measures.cljs #, unused msgid "workspace.options.position" @@ -7655,11 +7591,7 @@ msgstr "Capas" msgid "workspace.sidebar.layers.components" msgstr "Componentes" -#: src/app/main/ui/workspace/sidebar/layers.cljs:297 -msgid "workspace.sidebar.layers.filter" -msgstr "Filtrar" - -#: src/app/main/ui/workspace/sidebar/layers.cljs:310, src/app/main/ui/workspace/sidebar/layers.cljs:338 +#: src/app/main/ui/workspace/sidebar/layers.cljs:311, src/app/main/ui/workspace/sidebar/layers.cljs:339 msgid "workspace.sidebar.layers.frames" msgstr "Paneles" @@ -8216,7 +8148,6 @@ msgid "workspace.tokens.text-decoration-value-enter" msgstr "none | underline | strike-through o {alias}" #: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:154 -#, unused msgid "workspace.tokens.theme-name" msgstr "Tema %s"