From 6879f54e5da45b38173c3e2660d88b4ea6939bb0 Mon Sep 17 00:00:00 2001 From: Luis de Dios Date: Mon, 22 Dec 2025 00:07:59 +0100 Subject: [PATCH] :recycle: Replace some components with DS ones --- frontend/playwright/ui/pages/WorkspacePage.js | 8 +- .../playwright/ui/specs/design-tab.spec.js | 4 +- frontend/playwright/ui/specs/tokens.spec.js | 6 +- .../playwright/ui/specs/workspace.spec.js | 25 +- .../styles/common/refactor/design-tokens.scss | 14 - .../app/main/ui/components/file_uploader.cljs | 4 +- .../app/main/ui/components/radio_buttons.cljs | 107 ---- .../app/main/ui/components/radio_buttons.scss | 79 --- frontend/src/app/main/ui/dashboard/fonts.cljs | 12 +- .../src/app/main/ui/dashboard/import.cljs | 10 +- frontend/src/app/main/ui/dashboard/team.cljs | 10 +- frontend/src/app/main/ui/delete_shared.cljs | 27 +- frontend/src/app/main/ui/delete_shared.scss | 15 +- frontend/src/app/main/ui/ds.cljs | 2 + .../src/app/main/ui/ds/buttons/button.scss | 1 + .../main/ui/ds/controls/radio_buttons.cljs | 107 ++++ .../app/main/ui/ds/controls/radio_buttons.mdx | 97 +++ .../main/ui/ds/controls/radio_buttons.scss | 40 ++ .../ui/ds/controls/radio_buttons.stories.jsx | 72 +++ frontend/src/app/main/ui/exports/assets.cljs | 2 +- frontend/src/app/main/ui/inspect/code.cljs | 44 +- frontend/src/app/main/ui/inspect/code.scss | 16 +- .../src/app/main/ui/settings/profile.cljs | 12 +- frontend/src/app/main/ui/viewer/comments.cljs | 5 +- frontend/src/app/main/ui/viewer/header.cljs | 159 +++-- frontend/src/app/main/ui/viewer/header.scss | 79 +-- .../src/app/main/ui/viewer/share_link.cljs | 54 +- .../src/app/main/ui/viewer/share_link.scss | 28 +- .../app/main/ui/workspace/colorpicker.cljs | 47 +- .../app/main/ui/workspace/colorpicker.scss | 46 -- .../src/app/main/ui/workspace/libraries.cljs | 54 +- .../src/app/main/ui/workspace/libraries.scss | 100 +-- .../src/app/main/ui/workspace/main_menu.cljs | 3 +- .../src/app/main/ui/workspace/palette.cljs | 37 +- .../src/app/main/ui/workspace/palette.scss | 48 +- .../src/app/main/ui/workspace/presence.cljs | 2 +- .../app/main/ui/workspace/right_header.cljs | 87 ++- .../app/main/ui/workspace/right_header.scss | 140 +--- .../app/main/ui/workspace/sidebar/assets.cljs | 52 +- .../app/main/ui/workspace/sidebar/assets.scss | 91 +-- .../workspace/sidebar/assets/components.cljs | 34 +- .../sidebar/assets/typographies.cljs | 25 +- .../app/main/ui/workspace/sidebar/layers.cljs | 13 +- .../app/main/ui/workspace/sidebar/layers.scss | 36 +- .../sidebar/options/drawing/frame.cljs | 26 +- .../sidebar/options/menus/align.cljs | 108 ++-- .../sidebar/options/menus/align.scss | 26 - .../workspace/sidebar/options/menus/blur.cljs | 11 +- .../workspace/sidebar/options/menus/blur.scss | 14 - .../workspace/sidebar/options/menus/bool.cljs | 74 +-- .../workspace/sidebar/options/menus/bool.scss | 29 +- .../sidebar/options/menus/border_radius.cljs | 4 +- .../sidebar/options/menus/border_radius.scss | 6 - .../options/menus/color_selection.cljs | 19 +- .../options/menus/color_selection.scss | 4 +- .../sidebar/options/menus/component.cljs | 34 +- .../sidebar/options/menus/component.scss | 9 +- .../sidebar/options/menus/constraints.cljs | 21 +- .../sidebar/options/menus/constraints.scss | 32 - .../sidebar/options/menus/exports.cljs | 11 +- .../sidebar/options/menus/exports.scss | 8 +- .../workspace/sidebar/options/menus/fill.cljs | 21 +- .../workspace/sidebar/options/menus/fill.scss | 9 - .../sidebar/options/menus/frame_grid.cljs | 31 +- .../sidebar/options/menus/frame_grid.scss | 24 +- .../sidebar/options/menus/grid_cell.cljs | 109 ++-- .../sidebar/options/menus/grid_cell.scss | 15 +- .../sidebar/options/menus/interactions.cljs | 58 +- .../options/menus/layout_container.cljs | 600 +++++++++--------- .../options/menus/layout_container.scss | 105 +-- .../sidebar/options/menus/layout_item.cljs | 228 +++---- .../sidebar/options/menus/layout_item.scss | 18 +- .../sidebar/options/menus/measures.cljs | 101 ++- .../sidebar/options/menus/measures.scss | 32 - .../workspace/sidebar/options/menus/text.cljs | 260 ++++---- .../sidebar/options/menus/typography.cljs | 46 +- .../sidebar/options/menus/typography.scss | 9 - .../sidebar/options/rows/shadow_row.cljs | 5 +- .../sidebar/options/rows/shadow_row.scss | 10 +- .../sidebar/options/shapes/group.cljs | 2 +- .../sidebar/options/shapes/multiple.cljs | 2 +- .../sidebar/options/shapes/text.cljs | 9 +- .../tokens/management/forms/shadow.cljs | 28 +- .../tokens/management/forms/typography.cljs | 29 +- .../workspace/tokens/themes/create_modal.cljs | 32 +- .../app/main/ui/workspace/top_toolbar.cljs | 184 +++--- .../app/main/ui/workspace/top_toolbar.scss | 18 +- .../viewport/grid_layout_editor.cljs | 11 +- .../viewport/grid_layout_editor.scss | 14 +- .../ui/workspace/viewport/path_actions.cljs | 160 +++-- .../ui/workspace/viewport/path_actions.scss | 18 +- .../main/ui/workspace/viewport/top_bar.cljs | 6 +- .../main/ui/workspace/viewport/top_bar.scss | 5 +- frontend/translations/en.po | 86 ++- frontend/translations/es.po | 86 ++- 95 files changed, 2010 insertions(+), 2651 deletions(-) delete mode 100644 frontend/src/app/main/ui/components/radio_buttons.cljs delete mode 100644 frontend/src/app/main/ui/components/radio_buttons.scss create mode 100644 frontend/src/app/main/ui/ds/controls/radio_buttons.cljs create mode 100644 frontend/src/app/main/ui/ds/controls/radio_buttons.mdx create mode 100644 frontend/src/app/main/ui/ds/controls/radio_buttons.scss create mode 100644 frontend/src/app/main/ui/ds/controls/radio_buttons.stories.jsx diff --git a/frontend/playwright/ui/pages/WorkspacePage.js b/frontend/playwright/ui/pages/WorkspacePage.js index 728f313416..5b5886f397 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.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.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.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 f3441140eb..22e952436f 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.getByTitle("Fit content (Horizontal)"); - const vAuto = await workspacePage.page.getByTitle("Fit content (Vertical)"); + const hAuto = await workspacePage.page.getByTestId("behaviour-h-auto"); + const vAuto = await workspacePage.page.getByTestId("behaviour-v-auto"); await expect(vAuto.locator("input")).toBeChecked(); await expect(hAuto.locator("input")).toBeChecked(); diff --git a/frontend/playwright/ui/specs/tokens.spec.js b/frontend/playwright/ui/specs/tokens.spec.js index 90cbefd5a7..5c4d4d5730 100644 --- a/frontend/playwright/ui/specs/tokens.spec.js +++ b/frontend/playwright/ui/specs/tokens.spec.js @@ -2418,10 +2418,12 @@ test.describe("Tokens: Apply token", () => { await nameField.fill(newTokenTitle); const referenceTabButton = - tokensUpdateCreateModal.getByTestId("reference-opt"); + tokensUpdateCreateModal.getByRole('button', { name: 'Use a reference' }); referenceTabButton.click(); - const referenceField = tokensUpdateCreateModal.getByLabel("Reference"); + const referenceField = tokensUpdateCreateModal.getByRole('textbox', { + name: 'Reference' + }); await referenceField.fill("{Full}"); const submitButton = tokensUpdateCreateModal.getByRole("button", { diff --git a/frontend/playwright/ui/specs/workspace.spec.js b/frontend/playwright/ui/specs/workspace.spec.js index 8489cf122f..38e2bb56ca 100644 --- a/frontend/playwright/ui/specs/workspace.spec.js +++ b/frontend/playwright/ui/specs/workspace.spec.js @@ -332,24 +332,33 @@ test("Copy/paste properties", async ({ page, context }) => { await page.getByText("Copy/Paste as").hover(); await page.getByText("Paste properties").click(); - 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 + .getByTestId("layer-item") + .getByText("Rectangle") + .first() + .click({ button: "right" }); await page.getByText("Copy/Paste as").hover(); await page.getByText("Paste properties").click(); await page .getByTestId("layer-item") - .locator("div") - .filter({ hasText: "Path" }) + .getByText("Board") .nth(1) .click({ button: "right" }); await page.getByText("Copy/Paste as").hover(); await page.getByText("Paste properties").click(); - await page.getByText("Ellipse").click({ button: "right" }); + 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("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 512ebd5076..a9f8074707 100644 --- a/frontend/resources/styles/common/refactor/design-tokens.scss +++ b/frontend/resources/styles/common/refactor/design-tokens.scss @@ -245,13 +245,6 @@ --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); @@ -424,13 +417,6 @@ --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 8eebdff516..b381dc396a 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] :as props} input-ref] + [{:keys [accept multi label-text label-class input-id on-selected data-testid]} 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 deleted file mode 100644 index d8bc4c969e..0000000000 --- a/frontend/src/app/main/ui/components/radio_buttons.cljs +++ /dev/null @@ -1,107 +0,0 @@ -;; 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 deleted file mode 100644 index 6ef73339ad..0000000000 --- a/frontend/src/app/main/ui/components/radio_buttons.scss +++ /dev/null @@ -1,79 +0,0 @@ -// 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 f84d694893..c1aa638671 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 8950aaf93d..4972618a60 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.notifications :as ntf] [app.main.errors :as errors] [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 96afda2563..51eab781b2 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 51fcb8225e..eb6ffcd35c 100644 --- a/frontend/src/app/main/ui/delete_shared.cljs +++ b/frontend/src/app/main/ui/delete_shared.cljs @@ -11,8 +11,10 @@ [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] @@ -97,8 +99,11 @@ [:div {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-header)} [:h2 {:class (stl/css :modal-title)} title] - [:button {:class (stl/css :modal-close-btn) - :on-click cancel-fn} deprecated-icon/close]] + [:> icon-button* {:variant "ghost" + :class (stl/css :modal-close-btn) + :icon i/close + :aria-label (tr "labels.close") + :on-click cancel-fn}]] [:div {:class (stl/css :modal-content)} (when (and (string? subtitle) (not= subtitle "")) @@ -124,14 +129,10 @@ [:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :action-buttons)} (when-not (= cancel-label :omit) - [:input {:class (stl/css :cancel-button) - :type "button" - :value cancel-label - :on-click cancel-fn}]) + [:> button* {:variant "secondary" + :on-click cancel-fn} + cancel-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}]]]]])) + [:> button* {:variant (if (= accept-style :danger) "destructive" "primary") + :on-click accept-fn} + accept-label]]]]])) diff --git a/frontend/src/app/main/ui/delete_shared.scss b/frontend/src/app/main/ui/delete_shared.scss index d0f08a50e8..e9597009d1 100644 --- a/frontend/src/app/main/ui/delete_shared.scss +++ b/frontend/src/app/main/ui/delete_shared.scss @@ -33,7 +33,9 @@ } .modal-close-btn { - @extend .modal-close-btn-base; + position: absolute; + top: var(--sp-s); + right: var(--sp-s); } .modal-content { @@ -53,17 +55,6 @@ @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.cljs b/frontend/src/app/main/ui/ds.cljs index 129bf9fc2e..aa4c56f472 100644 --- a/frontend/src/app/main/ui/ds.cljs +++ b/frontend/src/app/main/ui/ds.cljs @@ -12,6 +12,7 @@ [app.main.ui.ds.controls.combobox :refer [combobox*]] [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.controls.select :refer [select*]] [app.main.ui.ds.controls.switch :refer [switch*]] [app.main.ui.ds.controls.utilities.hint-message :refer [hint-message*]] @@ -63,6 +64,7 @@ :Select select* :Switch switch* :Checkbox checkbox* + :RadioButtons radio-buttons* :Combobox combobox* :Text text* :TabSwitcher tab-switcher* diff --git a/frontend/src/app/main/ui/ds/buttons/button.scss b/frontend/src/app/main/ui/ds/buttons/button.scss index dd8c720559..a46f062c5d 100644 --- a/frontend/src/app/main/ui/ds/buttons/button.scss +++ b/frontend/src/app/main/ui/ds/buttons/button.scss @@ -15,6 +15,7 @@ display: inline-flex; align-items: center; + justify-content: center; column-gap: var(--sp-xs); } diff --git a/frontend/src/app/main/ui/ds/controls/radio_buttons.cljs b/frontend/src/app/main/ui/ds/controls/radio_buttons.cljs new file mode 100644 index 0000000000..ea9dd6fff3 --- /dev/null +++ b/frontend/src/app/main/ui/ds/controls/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.ds.controls.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.buttons.button :refer [button*]] + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] + [app.main.ui.ds.foundations.assets.icon :refer [icon-list]] + [app.util.dom :as dom] + [rumext.v2 :as mf] + [rumext.v2.util :as mfu])) + +(def ^:private schema:radio-button + [:map + [:id :string] + [:icon {:optional true} + [:and :string [:fn #(contains? icon-list %)]]] + [:label :string] + [:value [:or :keyword :string]] + [:disabled {:optional true} :boolean]]) + +(def ^:private schema:radio-buttons + [:map + [:class {:optional true} :string] + [:variant {:optional true} + [:maybe [:enum "primary" "secondary" "ghost" "destructive" "action"]]] + [:extended {:optional true} :boolean] + [:name {:optional true} :string] + [:selected {:optional true} + [:maybe [:or :keyword :string]]] + [:allow-empty {:optional true} :boolean] + [:options [:vector {:min 1} schema:radio-button]] + [:on-change {:optional true} fn?]]) + +(mf/defc radio-buttons* + {::mf/schema schema:radio-buttons} + [{:keys [class variant extended name selected allow-empty options on-change] :rest props}] + (let [options (if (array? options) + (mfu/bean options) + options) + type (if allow-empty "checkbox" "radio") + variant (d/nilv variant "secondary") + + handle-click + (mf/use-fn + (fn [event] + (let [target (dom/get-target event) + label (dom/get-parent-with-data target "label")] + (dom/prevent-default event) + (dom/stop-propagation event) + (dom/click label)))) + + handle-change + (mf/use-fn + (mf/deps selected on-change) + (fn [event] + (let [input (dom/get-target event) + value (dom/get-target-val event)] + (when (fn? on-change) + (on-change value event)) + (dom/blur! input)))) + + props + (mf/spread-props props {:key (dm/str name "-" selected) + :class [class (stl/css-case :wrapper true + :extended extended)]})] + + [:> :div props + (for [[idx {:keys [id class value label icon disabled]}] (d/enumerate options)] + (let [checked? (= selected value)] + [:label {:key idx + :html-for id + :data-label true + :data-testid id + :class [class (stl/css-case :label true + :extended extended)]} + + (if (some? icon) + [:> icon-button* {:variant variant + :on-click handle-click + :aria-pressed checked? + :aria-label label + :icon icon + :disabled disabled}] + [:> button* {:variant variant + :on-click handle-click + :aria-pressed checked? + :class (stl/css-case :button true + :extended extended) + :disabled disabled} + label]) + + [:input {:id id + :class (stl/css :input) + :on-change handle-change + :type type + :name name + :disabled disabled + :value value + :default-checked checked?}]]))])) diff --git a/frontend/src/app/main/ui/ds/controls/radio_buttons.mdx b/frontend/src/app/main/ui/ds/controls/radio_buttons.mdx new file mode 100644 index 0000000000..226319286a --- /dev/null +++ b/frontend/src/app/main/ui/ds/controls/radio_buttons.mdx @@ -0,0 +1,97 @@ +{ /* 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 */ } + +import { Canvas, Meta } from '@storybook/addon-docs/blocks'; +import * as RadioButtons from "./radio_buttons.stories"; + + + +# Radio Buttons + +The `radio-buttons*` component allows users to switch between two or more options that are mutually exclusive. + +## Variants + +Radio buttons with text only. The label will be the text of the button. + + + +```clj +[:> radio-buttons* {:selected "left" + :on-change handle-change + :name "alignment" + :extended false + :allow-empty false + :options [{:id "align-left" + :label "Left" + :value "left"} + {:id "align-center" + :label "Center" + :value "center"} + {:id "align-right" + :label "Right" + :value "right"}]}] +``` + +Radio buttons with icons only. In this case, the label will act as the tooltip of each button. + + + +```clj +(ns app.main.ui.foo + (:require + [app.main.ui.ds.foundations.assets.icon :as i])) + +[:> radio-buttons* {:selected "left" + :on-change handle-change + :name "alignment" + :extended false + :allow-empty false + :options [{:id "align-left" + :icon i/text-align-left + :label "Left align" + :value "left"} + {:id "align-center" + :icon i/text-align-center + :label "Center align" + :value "center"} + {:id "align-right" + :icon i/text-align-right + :label "Right align" + :value "right"}]}] +``` + +## Anatomy + +Under the hood, each option is represented by +- a button, which is the visible and clickable element. It may be either an icon button or a text button. +- a radio input, which is not visible but retains the current state of the option. + +A radio group is defined by giving each of radio buttons in the group the same name. Once a radio group is established, +selecting any radio button in that group automatically deselects any currently-selected radio button in the same group. + +The `selected` parameter should be set to the value of the option that is to be active. Otherwise, no option will be selected. + +If the parameter `allow-empty` is enabled, then the component will work with checkboxes instead of radio buttons, +and therefore the selected option can be deselected. However, it will still only be possible to select one option. + +The `extended` parameter allows the component to use all the available space from the parent and distribute it equally +among all elements. + +Any option can be individually disabled using the `disabled` parameter. + +## Usage Guidelines + +### When to Use + +- For multiple choice settings that take effect immediately. +- In preference panels and configuration screens. + +### When Not to Use + +- For boolean settings (use switch or checkbox instead). +- For actions that require confirmation (use buttons instead). +- For temporary states that need explicit "Apply" action. diff --git a/frontend/src/app/main/ui/ds/controls/radio_buttons.scss b/frontend/src/app/main/ui/ds/controls/radio_buttons.scss new file mode 100644 index 0000000000..05957025dc --- /dev/null +++ b/frontend/src/app/main/ui/ds/controls/radio_buttons.scss @@ -0,0 +1,40 @@ +// 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 "ds/_borders.scss" as *; +@use "ds/spacing.scss" as *; + +.wrapper { + display: flex; + justify-content: flex-start; + align-items: center; + width: fit-content; + border-radius: $br-8; + background-color: var(--color-background-tertiary); + gap: var(--sp-xs); + + &.extended { + width: 100%; + display: flex; + } +} + +.label { + &.extended { + display: flex; + flex: 1 1 0; + } +} + +.button { + &.extended { + flex-grow: 1; + } +} + +.input { + display: none; +} diff --git a/frontend/src/app/main/ui/ds/controls/radio_buttons.stories.jsx b/frontend/src/app/main/ui/ds/controls/radio_buttons.stories.jsx new file mode 100644 index 0000000000..b7aca4194f --- /dev/null +++ b/frontend/src/app/main/ui/ds/controls/radio_buttons.stories.jsx @@ -0,0 +1,72 @@ +// 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 + +import * as React from "react"; +import Components from "@target/components"; + +const { RadioButtons } = Components; + +const options = [ + {id: "left", label: "Left", value: "left" }, + {id: "center", label: "Center", value: "center" }, + {id: "right", label: "Right", value: "right" }, +]; + +const optionsIcon = [ + {id: "left", label: "Left align", value: "left", icon: "text-align-left" }, + {id: "center", label: "Center align", value: "center", icon: "text-align-center" }, + {id: "right", label: "Right align", value: "right", icon: "text-align-right" }, +]; + +export default { + title: "Controls/Radio Buttons", + component: RadioButtons, + argTypes: { + name: { + control: { type: "text" }, + description: "Whether the checkbox is checked", + }, + selected: { + control: { type: "select" }, + options: ["", "left", "center", "right"], + description: "Whether the checkbox is checked", + }, + extended: { + control: { type: "boolean" }, + description: "Whether the checkbox is checked", + }, + allowEmpty: { + control: { type: "boolean" }, + description: "Whether the checkbox is checked", + }, + disabled: { + control: { type: "boolean" }, + description: "Whether the checkbox is disabled", + }, + }, + args: { + name: "alignment", + selected: "left", + extended: false, + allowEmpty: false, + options: options, + disabled: false, + }, + parameters: { + controls: { + exclude: ["options", "on-change"], + }, + }, + render: ({ ...args }) => , +}; + +export const Default = {}; + +export const WithIcons = { + args: { + options: optionsIcon, + }, +}; \ No newline at end of file diff --git a/frontend/src/app/main/ui/exports/assets.cljs b/frontend/src/app/main/ui/exports/assets.cljs index e6dd1ec51b..c82b13ffb3 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 661bee9075..605d8e38ee 100644 --- a/frontend/src/app/main/ui/inspect/code.cljs +++ b/frontend/src/app/main/ui/inspect/code.cljs @@ -19,7 +19,10 @@ [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.components.radio-buttons :refer [radio-button radio-buttons]] + [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.hooks.resize :refer [use-resize-hook]] [app.main.ui.icons :as deprecated-icon] [app.main.ui.shapes.text.fontfaces :refer [shapes->fonts]] @@ -260,8 +263,9 @@ [:div {:class (stl/css-case :element-options true :viewer-code-block (= :viewer from))} [:div {:class (stl/css :attributes-block)} - [:button {:class (stl/css :download-button) - :on-click handle-copy-all-code} + [:> button* {:variant "secondary" + :class (stl/css :download-button) + :on-click handle-copy-all-code} "Copy all code"]] #_[:div.attributes-block @@ -288,10 +292,10 @@ ;; :options [{:label "CSS" :value "css"}]}] [:div {:class (stl/css :action-btns)} - [:button {:class (stl/css :expand-button) - :on-click on-expand} - deprecated-icon/code] - + [:> icon-button* {:variant "ghost" + :aria-label "Expand" + :on-click on-expand + :icon i/code}] [:> copy-button* {:data copy-css-fn :class (stl/css :css-copy-btn) :on-copied on-style-copied}]]] @@ -318,21 +322,21 @@ :rotated collapsed-markup?)} deprecated-icon/arrow]] - [:& 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}]] + [:> 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"}]}] [:div {:class (stl/css :action-btns)} - [:button {:class (stl/css :expand-button) - :on-click on-expand} - deprecated-icon/code] - + [:> icon-button* {:variant "ghost" + :aria-label "Expand" + :on-click on-expand + :icon i/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 7f88871edc..93bf3c88e5 100644 --- a/frontend/src/app/main/ui/inspect/code.scss +++ b/frontend/src/app/main/ui/inspect/code.scss @@ -17,16 +17,18 @@ 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 { - @extend .button-secondary; - @include deprecated.uppercaseTitleTipography; - height: deprecated.$s-32; - width: 100%; - margin: deprecated.$s-8 0; + margin: var(--sp-s) 0; } .code-block { @@ -73,7 +75,6 @@ gap: deprecated.$s-4; } -.expand-button, .css-copy-btn, .html-copy-btn { @extend .button-tertiary; @@ -85,9 +86,6 @@ } } -.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 763ee3c836..30855c2b00 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 9646c81f8c..5bc7e4a953 100644 --- a/frontend/src/app/main/ui/viewer/comments.cljs +++ b/frontend/src/app/main/ui/viewer/comments.cljs @@ -27,9 +27,8 @@ [okulary.core :as l] [rumext.v2 :as mf])) -(mf/defc comments-menu - {::mf/props :obj - ::mf/memo true} +(mf/defc comments-menu* + {::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 270e30643b..334c3ac9d2 100644 --- a/frontend/src/app/main/ui/viewer/header.cljs +++ b/frontend/src/app/main/ui/viewer/header.cljs @@ -14,10 +14,13 @@ [app.main.data.viewer.shortcuts :as sc] [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] - [app.main.ui.exports.assets :refer [progress-widget]] + [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.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]] @@ -33,20 +36,12 @@ [] (modal/show! :login-register {})) -(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}] +(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*) - (let [open* (mf/use-state false) - open? (deref open*) open-dropdown (mf/use-fn (fn [event] @@ -75,7 +70,7 @@ [:div {:class (stl/css-case :zoom-widget true :selected open?) - :on-click open-dropdown + :on-click (if open? close-dropdown open-dropdown) :title (tr "workspace.header.zoom")} [:span {:class (stl/css :label)} (fmt/format-percent zoom)] [:& dropdown {:show open? @@ -83,18 +78,18 @@ [:ul {:class (stl/css :dropdown)} [:li {:class (stl/css :basic-zoom-bar)} [:span {:class (stl/css :zoom-btns)} - [: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)} + [:> icon-button* {:variant "ghost" + :aria-label (tr "shortcuts.decrease-zoom") + :on-click on-decrease + :icon i/remove}] + [:p {:class (stl/css :zoom-text)} (fmt/format-percent zoom)] - [: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} + [:> 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} (tr "workspace.header.reset-zoom")]] [:li {:class (stl/css :zoom-option) @@ -119,7 +114,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) @@ -159,6 +154,7 @@ handle-zoom-fit (mf/use-fn #(st/emit! dv/zoom-to-fit))] + (mf/with-effect [permissions share] (when (and (:in-team permissions) @@ -167,7 +163,7 @@ (open-share-dialog))) [:div {:class (stl/css :options-zone)} - [:& progress-widget] + [:> progress-widget*] (case section :interactions [:* @@ -175,40 +171,41 @@ [:> 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) - [:span {:on-click go-to-workspace - :class (stl/css :edit-btn)} - deprecated-icon/curve]) + [:> icon-button* {:variant "ghost" + :aria-label (tr "viewer.header.edit-in-workspace") + :on-click go-to-workspace + :icon i/curve}]) - [:span {:title (tr "viewer.header.fullscreen") - :class (stl/css-case :fullscreen-btn true - :selected fullscreen?) - :on-click toggle-fullscreen} - deprecated-icon/expand] + [:> icon-button* {:variant "ghost" + :aria-pressed fullscreen? + :aria-label (tr "viewer.header.fullscreen") + :on-click toggle-fullscreen + :icon i/expand}] (when (:in-team permissions) - [:button {:on-click open-share-dialog - :class (stl/css :share-btn)} + [:> button* {:variant "primary" + :class (stl/css :share-btn) + :on-click open-share-dialog} (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] :as props}] +(mf/defc header-sitemap* + [{:keys [project file page frame toggle-thumbnails]}] (let [project-name (:name project) file-name (:name file) page-name (:name page) @@ -317,44 +314,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)} - [: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] + [:> 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}] (when (or (:in-team permissions) (= (:who-comment permissions) "all")) - [: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]) + [:> 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}]) (when (or (:in-team permissions) (and (= (:type permissions) :share-link) (= (:who-inspect permissions) "all"))) - [: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])] + [:> 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}])] - [:& 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 f9814d3a44..83a1400033 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 deprecated.$s-92 1fr; + grid-template-columns: 1fr auto 1fr; justify-content: space-between; align-items: center; height: deprecated.$s-48; @@ -130,23 +130,9 @@ // SECTION BUTTONS .mode-zone { - @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; + display: flex; + flex-direction: row; + gap: var(--sp-xs); } // OPTION AREA @@ -165,33 +151,8 @@ 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 { - @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); - } + margin-left: var(--sp-xs); } .go-log-btn { @@ -245,43 +206,15 @@ 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-64; + min-width: deprecated.$s-48; 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 646405676c..7867a3c200 100644 --- a/frontend/src/app/main/ui/viewer/share_link.cljs +++ b/frontend/src/app/main/ui/viewer/share_link.cljs @@ -20,6 +20,9 @@ [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] @@ -171,10 +174,11 @@ [:div {:class (stl/css :share-link-header)} [:h2 {:class (stl/css :share-link-title)} (tr "common.share-link.title")] - [:button {:class (stl/css :modal-close-button) - :on-click on-close - :title (tr "labels.close")} - deprecated-icon/close]] + [:> icon-button* {:variant "ghost" + :class (stl/css :modal-close-button) + :aria-label (tr "labels.close") + :on-click on-close + :icon i/close}]] [:div {:class (stl/css :modal-content)} [:div {:class (stl/css :share-link-section)} (when (and (not confirm?) (some? current-link)) @@ -185,10 +189,10 @@ :placeholder (tr "common.share-link.placeholder") :read-only true}] - [:button {:class (stl/css :copy-button) - :title (tr "viewer.header.share.copy-link") - :on-click copy-link} - deprecated-icon/clipboard]]) + [:> icon-button* {:variant "ghost" + :aria-label (tr "viewer.header.share.copy-link") + :on-click copy-link + :icon i/clipboard}]]) [:div {:class (stl/css :hint-wrapper)} (when (not ^boolean confirm?) @@ -199,28 +203,22 @@ [:div {:class (stl/css :description)} (tr "common.share-link.confirm-deletion-link-description")] [:div {:class (stl/css :actions)} - [: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")}]]] + [:> button* {:variant "secondary" + :on-click #(reset! confirm* false)} + (tr "labels.cancel")] + [:> button* {:variant "destructive" + :on-click delete-link} + (tr "common.share-link.destroy-link")]]] (some? current-link) - [:input - {:type "button" - :class (stl/css :button-danger) - :on-click try-delete-link - :value (tr "common.share-link.destroy-link")}] + [:> button* {:variant "destructive" + :on-click try-delete-link} + (tr "common.share-link.destroy-link")] :else - [:input - {:type "button" - :class (stl/css :button-active) - :on-click create-link - :value (tr "common.share-link.get-link")}])]] + [:> button* {:variant "primary" + :on-click create-link} + (tr "common.share-link.get-link")])]] (when (not ^boolean confirm?) @@ -305,6 +303,7 @@ :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")] @@ -315,6 +314,3 @@ :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 2c8bcc60b1..b877736d16 100644 --- a/frontend/src/app/main/ui/viewer/share_link.scss +++ b/frontend/src/app/main/ui/viewer/share_link.scss @@ -30,7 +30,9 @@ } .modal-close-button { - @extend .modal-close-btn-base; + position: absolute; + top: var(--sp-s); + right: var(--sp-s); } .modal-content { @@ -74,18 +76,6 @@ } } -.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); @@ -97,18 +87,6 @@ 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 3e930e9f81..8abd50ba06 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -25,10 +25,11 @@ [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] @@ -415,24 +416,25 @@ :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"} - [:& 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"}]])] + [:> 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}]}])] (when (and (not= selected-mode :image) (= color-style :direct-color)) - [:button {:class (stl/css-case :picker-btn true - :selected picking-color?) - :on-click handle-click-picker} - deprecated-icon/picker]) + [:> icon-button* {:variant "ghost" + :aria-label (tr "workspace.colorpicker.get-color") + :aria-pressed picking-color? + :on-click handle-click-picker + :icon i/picker}]) (when (= color-style :token-color) [:div {:class (stl/css :token-color-title)} @@ -483,12 +485,11 @@ :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 1d7e303d41..d50ed0002c 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.scss +++ b/frontend/src/app/main/ui/workspace/colorpicker.scss @@ -46,52 +46,6 @@ 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 18fd87e7c8..bede05c92c 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -30,6 +30,7 @@ [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*]] @@ -44,12 +45,6 @@ [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] @@ -168,12 +163,10 @@ [:div {:class (stl/css :sample-library-item) :key (dm/str id)} [:div {:class (stl/css :sample-library-item-name)} (:name library)] - [: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}]])) + [:> button* {:variant "secondary" + :on-click import-library + :disabled (some? importing?)} + (if (= importing? id) (tr "labels.adding") (tr "labels.add"))]])) (defn- empty-library? "Check if currentt library summary has elements or not" @@ -322,14 +315,12 @@ [:> library-description* {:summary summary}]]] (if ^boolean is-shared - [: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}])] + [:> button* {:variant "secondary" + :on-click unpublish} + (tr "common.unpublish")] + [:> button* {:variant "primary" + :on-click publish} + (tr "common.publish")])] (for [{:keys [id name data connected-to connected-to-names] :as library} linked-libraries] (let [disabled? (some #(contains? linked-libraries-ids %) connected-to)] @@ -377,12 +368,11 @@ (let [summary (-> (:library-summary library) (adapt-backend-summary))] [:> library-description* {:summary summary}])]] - - [: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]])] + [:> 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}]])] (when (empty? shared-libraries) [:div {:class (stl/css :section-list-empty)} @@ -647,11 +637,13 @@ :on-click close-dialog-outside :data-testid "libraries-modal"} [:div {:class (stl/css :modal-dialog)} - [:button {:class (stl/css :close-btn) - :on-click close-dialog - :aria-label (tr "labels.close") - :data-testid "close-libraries"} - close-icon] + [:> 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}] + [: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 9776c08bad..46a7edca7f 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: auto 1fr; + grid-template-rows: 0 auto 1fr; min-width: $sz-364; min-height: $sz-192; height: $sz-520; @@ -42,21 +42,10 @@ max-width: $sz-712; } -// TODO: Remove this extended creating modal component .close-btn { - @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); + position: absolute; + top: var(--sp-s); + right: var(--sp-s); } .modal-title { @@ -120,46 +109,6 @@ 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); } @@ -170,26 +119,6 @@ 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; @@ -428,24 +357,3 @@ 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 a964d27475..226d0d0233 100644 --- a/frontend/src/app/main/ui/workspace/main_menu.cljs +++ b/frontend/src/app/main/ui/workspace/main_menu.cljs @@ -853,8 +853,9 @@ [:* [:> icon-button* {:variant "ghost" + :aria-pressed show-menu? :aria-label (tr "shortcut-subsection.main-menu") - :on-click open-menu + :on-click (if show-menu? close-all-menus 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 80c396989e..dd219410a8 100644 --- a/frontend/src/app/main/ui/workspace/palette.cljs +++ b/frontend/src/app/main/ui/workspace/palette.cljs @@ -18,9 +18,10 @@ [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]] @@ -178,27 +179,27 @@ [:ul {:class (dm/str size-classname " " (stl/css-case :palette-btn-list true :hidden-bts hide-palettes?))} [:li {:class (stl/css :palette-item)} - [: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]] - + [:> 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}]] [:li {:class (stl/css :palette-item)} - [: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]]] - + [:> 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}]]] (if any-palette? [:* - [:button {:class (stl/css :palette-actions) - :on-click #(swap! state* update :show-menu not)} - deprecated-icon/menu] + [: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}]] + [: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 7dc42ffc37..dbdef2a6b2 100644 --- a/frontend/src/app/main/ui/workspace/palette.scss +++ b/frontend/src/app/main/ui/workspace/palette.scss @@ -49,7 +49,6 @@ &.wide { width: 100%; } - .resize-area { grid-area: resize; height: deprecated.$s-8; @@ -72,49 +71,22 @@ &.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 7e22276be4..398dd8499a 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 ce10de99cf..b9867ea6b2 100644 --- a/frontend/src/app/main/ui/workspace/right_header.cljs +++ b/frontend/src/app/main/ui/workspace/right_header.cljs @@ -20,23 +20,19 @@ [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.icons :as deprecated-icon] - [app.main.ui.workspace.presence :refer [active-sessions]] + [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]}] @@ -72,11 +68,12 @@ zoom (fmt/format-percent zoom {:precision 0})] [:* - [:div {:on-click open-dropdown + [:div {:on-click (if open? close-dropdown 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)} @@ -90,9 +87,10 @@ :aria-label (tr "shortcuts.increase-zoom") :on-click on-increase :icon i/add}]] - [:button {:class (stl/css :reset-btn) - :on-click on-zoom-reset} + [:> button* {:variant "ghost" + :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") @@ -100,6 +98,7 @@ (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") @@ -198,51 +197,43 @@ [: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-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)}])]] + [: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)}])] (when-not ^boolean read-only? - [: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]]) + [:> icon-button* {:variant "ghost" + :aria-pressed (contains? layout :document-history) + :aria-label (tr "workspace.sidebar.history") + :on-click toggle-history + :icon i/history}]) (when display-share-button? - [: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.share") + :on-click open-share-dialog + :icon i/to-corner}]) + [:> 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 e6d7ea2092..e49c314ef6 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; - gap: deprecated.$s-8; + padding: deprecated.$s-8 deprecated.$s-12; + gap: deprecated.$s-4; background-color: var(--panel-background-color); } @@ -28,19 +28,14 @@ } .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; - border-radius: deprecated.$br-8; + height: deprecated.$s-32; .label { @include deprecated.bodySmallTypography; - height: 100%; - padding: deprecated.$s-8 0; color: var(--button-tertiary-foreground-color-rest); } @@ -84,13 +79,6 @@ 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; @@ -113,127 +101,11 @@ } } -.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-wrapper { + position: relative; } -.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 { +.comments-button-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 d899f20d67..482393e286 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -17,8 +17,9 @@ [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.icons :as deprecated-icon] + [app.main.ui.ds.foundations.assets.icon :as i] [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] @@ -161,43 +162,40 @@ :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 {:class (stl/css :add-library-button) - :on-click show-libraries-dialog - :data-testid "libraries"} + [:> button* {:variant "primary" + :on-click show-libraries-dialog + :data-testid "libraries"} (tr "workspace.assets.add-library")] - - [:button {:class (stl/css :libraries-button) - :on-click show-libraries-dialog - :data-testid "libraries"} + [:> button* {:variant "secondary" + :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")} - [: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]] + [:> 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}]] - [:> 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 f89069cca5..53cbc98e0e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.scss @@ -17,89 +17,14 @@ padding-top: deprecated.$s-8; } -.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); - } +.assets-header { + display: flex; + flex-direction: column; + gap: var(--sp-xxs); } -.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; - } +.filter-button { + border-radius: deprecated.$br-8 0 0 deprecated.$br-8; } .sections-container { @@ -125,10 +50,6 @@ 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 077742d71d..9aa485d5eb 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.radio-buttons :refer [radio-button radio-buttons]] + [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.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"} - [:& 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"}]]]) + [:> 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"}]}]]) (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 8ad40c2f4e..5d29117036 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,18 +113,17 @@ :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 398473f54c..de90c9bbfe 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/layers.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/layers.cljs @@ -291,13 +291,12 @@ :value current-search :on-clear clear-search-text :placeholder (tr "workspace.sidebar.layers.search")} - [: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 "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}]] [:> 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 353eaf009e..67de81174c 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/layers.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/layers.scss @@ -19,39 +19,7 @@ padding: 0 deprecated.$s-12 0 deprecated.$s-8; gap: deprecated.$s-4; .filter-button { - @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; - } + border-radius: deprecated.$br-8 0 0 deprecated.$br-8; } } } @@ -143,7 +111,7 @@ .filters-container { @extend .menu-dropdown; position: absolute; - left: deprecated.$s-20; + left: deprecated.$s-16; 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 275ad11e8d..7bebe451b3 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.components.radio-buttons :refer [radio-button radio-buttons]] + [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] @@ -95,15 +95,15 @@ (when preset-match [:span {:class (stl/css :check-icon)} deprecated-icon/tick])])))]]] - [:& 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"}]]])) - + [:> 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"}]}]])) 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 4cf1c6efc4..aeb1fb8c60 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,7 +10,8 @@ [app.main.data.workspace :as dw] [app.main.data.workspace.shortcuts :as sc] [app.main.store :as st] - [app.main.ui.icons :as deprecated-icon] + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] + [app.main.ui.ds.foundations.assets.icon :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) @@ -42,68 +43,59 @@ (when-not (and disabled-align disabled-distribute) [:div {:class (stl/css :align-options)} [:div {:class (stl/css :align-group-horizontal)} - [: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-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.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-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.hright" (sc/get-tooltip :align-right)) - :data-value "hright" - :on-click align-objects} - deprecated-icon/align-right] + [:> 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-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]] + [:> 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}]] [:div {:class (stl/css :align-group-vertical)} - [: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-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.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-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.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/align-bottom + :aria-label (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom)) + :on-click align-objects + :data-value "vbottom" + :disabled disabled-align}] + [:> 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 6535f728b4..6b3f27b621 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,12 +4,10 @@ // // 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 { @@ -26,27 +24,3 @@ .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 52a5570614..7c27041728 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,7 +15,6 @@ [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])) @@ -103,10 +102,12 @@ [:div {:class (stl/css-case :first-row true :hidden hidden?)} [:div {:class (stl/css :blur-info)} - [:button {:class (stl/css-case :show-more true - :selected more-options?) - :on-click toggle-more-options} - deprecated-icon/menu] + [:> 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}] [: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 e15a50c83e..7623012431 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,21 +37,7 @@ 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 b2ffa16cb8..9fc8fdc6bb 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,15 +15,12 @@ [app.main.data.workspace.shortcuts :as sc] [app.main.features :as features] [app.main.store :as st] - [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.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) @@ -70,41 +67,40 @@ (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 :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"}]]] + [: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}]}]] - [: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]]))) + [:> icon-button* {:variant "ghost" + :icon i/boolean-flatten + :aria-label (tr "workspace.shape.menu.flatten") + :on-click flatten-objects + :disabled disabled-flatten}]]))) 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 ef69c2dd4e..babf5564bd 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,45 +4,18 @@ // // 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); } -.bool-group { +.boolean-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 6c2e4137c9..e425539f6d 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 @@ -145,9 +145,9 @@ :on-change on-radius-r3-change :value (:r3 values)}]]]) - [:> icon-button* {:class (stl/css-case :selected radius-expanded) - :variant "ghost" + [:> icon-button* {: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 65a421790c..1c230b4108 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 @@ -28,12 +28,6 @@ @include deprecated.bodySmallTypography; } -.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: deprecated.$s-4; } 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 86622173c8..7fe3efce8f 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,6 +13,7 @@ [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])) @@ -49,16 +50,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." @@ -217,8 +218,8 @@ :origin :color-selection :on-close on-close}])) (when (and (false? @expand-lib-color) (< 3 (count library-colors))) - [:button {:class (stl/css :more-colors-btn) - :on-click #(reset! expand-lib-color true)} + [:> button* {:variant "secondary" + :on-click #(reset! expand-lib-color true)} (tr "workspace.options.more-lib-colors")])] [:div {:class (stl/css :selected-color-group)} @@ -235,8 +236,8 @@ :on-close on-close}]) (when (and (false? @expand-color) (< 3 (count colors))) - [:button {:class (stl/css :more-colors-btn) - :on-click #(reset! expand-color true)} + [:> button* {:variant "secondary" + :on-click #(reset! expand-color true)} (tr "workspace.options.more-colors")])] [:div {:class (stl/css :selected-color-group)} @@ -259,6 +260,6 @@ (when (and (false? @expand-token-color) (< 3 (count token-colors))) - [:button {:class (stl/css :more-colors-btn) - :on-click #(reset! expand-token-color true)} + [:> button* {:variant "secondary" + :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 7519bcb568..f84a46c2a2 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,7 +40,5 @@ } .more-colors-btn { - @extend .button-secondary; - @include deprecated.uppercaseTitleTipography; - height: deprecated.$s-32; + justify-content: center; } 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 e016bc354f..a742e95afd 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,7 +28,6 @@ [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]] @@ -37,6 +36,7 @@ [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,15 +794,17 @@ [: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"} - [:& 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"}]]] + [:> 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"}]}]] (when-not (or search? (str/empty? (:path filters))) [:button {:class (stl/css :swap-library-back) @@ -897,11 +899,13 @@ (when menu-entries? [:div {:class (stl/css :pill-actions)} - [:button {:class (stl/css-case :pill-actions-btn true - :selected menu-open?) - :on-click on-menu-click} - [:> icon* {:icon-id i/menu}]] - + [:> 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}] [:& 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 88ca5dd5b6..e8838fdb77 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,14 +587,9 @@ } .pill-actions-btn { - @extend .button-secondary; - cursor: unset; - block-size: 100%; - inline-size: 100%; border-radius: 0 $br-8 $br-8 0; - - &.selected { - @extend .button-icon-selected; + &.extended { + block-size: $sz-48; } } 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 a56843dce2..f9368c9a4f 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.icons :as deprecated-icon] + [app.main.ui.ds.controls.checkbox :refer [checkbox*]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [cuerdas.core :as str] @@ -61,6 +61,7 @@ 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 @@ -218,16 +219,8 @@ :options options-v :on-change on-constraint-v-select-changed}]] (when first-level? - [: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}]]])]])]))) + [:> 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}])]])]))) 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 5f7578afe1..3f3fdc5dc1 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,36 +137,4 @@ 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 5e7d5c9127..88eca7dcfe 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,6 +14,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.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] @@ -263,12 +264,10 @@ :icon i/remove}]])]) (when (or (= :multiple exports) (seq exports)) - [:button - {:on-click (when-not in-progress? on-download) - :class (stl/css-case - :export-btn true - :btn-disabled in-progress?) - :disabled in-progress?} + [:> button* {:variant "secondary" + :class (stl/css :export-btn) + :on-click (when-not in-progress? on-download) + :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 487e4805bc..a9a4963921 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 9; + grid-column: 1 / span 8; .label { @extend .mixed-bar; } @@ -76,8 +76,6 @@ } .export-btn { - @extend .button-secondary; - @include deprecated.uppercaseTitleTipography; - grid-column: 1 / span 9; - height: deprecated.$s-32; + grid-column: 1 / span 8; + justify-content: center; } 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 326c5dfa18..c521868519 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,16 +252,9 @@ (when (or (= type :frame) (and (= type :multiple) (some? hide-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}]]])])])) + [:> 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}])])])) 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 28a159b4de..3ca90bb806 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,14 +50,5 @@ } .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 326b5efa4a..6cb6665d56 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,10 +148,13 @@ [:div {:class (stl/css :grid-title)} [:div {:class (stl/css-case :option-row true :hidden is-hidden?)} - [:button {:class (stl/css-case :show-options true - :selected open?) - :on-click toggle-advanced-options} - deprecated-icon/menu] + [:> 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?}] [:div {:class (stl/css :type-select-wrapper)} [:& select {:class (stl/css :grid-type-select) @@ -204,10 +207,11 @@ :origin :guides :on-change handle-change-color :on-detach handle-detach-color}] - [:button {:class (stl/css-case :show-more-options true - :selected show-more-options?) - :on-click toggle-more-options} - deprecated-icon/menu]] + [:> icon-button* {:variant "ghost" + :icon i/menu + :aria-pressed show-more-options? + :aria-label (tr "labels.options") + :on-click toggle-more-options}]] (when show-more-options? [:div {:class (stl/css :second-row)} [:button {:class (stl/css-case :btn-options true @@ -284,11 +288,12 @@ :className (stl/css :numeric-input) :value (or (:margin params) 0)}]] - [:button {:class (stl/css-case :show-more-options true - :selected show-more-options?) - :on-click toggle-more-options - :disabled is-default} - deprecated-icon/menu] + [:> 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}] (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 51b82c5434..f6ab50dba3 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,18 +38,7 @@ 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; @@ -108,7 +97,6 @@ &.hidden { .show-options { - @include deprecated.hiddenElement; border: deprecated.$s-1 solid var(--input-border-color-disabled); } .type-select-wrapper, @@ -176,17 +164,7 @@ .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 25a92ac854..88d75222ad 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,8 +16,9 @@ [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] @@ -35,10 +36,10 @@ :justify-self :area-name]) -(mf/defc set-self-alignment - [{:keys [is-col? alignment set-alignment] :as props}] +(mf/defc set-self-alignment* + [{:keys [is-col alignment set-alignment]}] (let [alignment (or alignment :auto) - type (if is-col? "col" "row") + type (if is-col "col" "row") handle-set-alignment (mf/use-callback @@ -46,39 +47,35 @@ (fn [value] (set-alignment (-> value keyword))))] - [:div {:class (stl/css :self-align-menu)} - [:& radio-buttons {:selected (d/name alignment) - :on-change handle-set-alignment + [:> radio-buttons* {:class (stl/css :self-align-menu) + :selected (d/name alignment) + :name (dm/str "flex-align-items-" type) :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)}]]])) - + :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"}]}])) (mf/defc options {::mf/wrap [mf/memo]} @@ -182,16 +179,19 @@ (when open? [:div {:class (stl/css :grid-cell-menu-container)} - [:div {:class (stl/css :cell-mode :row)} - [:& radio-buttons {:selected (d/name cell-mode) - :on-change set-cell-mode + [:> radio-buttons* {:selected (d/name cell-mode) :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?)}]]] + :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?)}]}] (when (= :area cell-mode) [:div {:class (stl/css :row)} @@ -261,16 +261,15 @@ :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 - {:class (stl/css :edit-grid-btn) - :alt (tr "workspace.layout_grid.editor.options.edit-grid") - :on-click toggle-edit-mode} + [:> button* {:variant "secondary" + :class (stl/css :edit-grid-btn) + :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 5b61b4dabf..a9c9814683 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,17 +30,6 @@ @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; @@ -66,3 +55,7 @@ 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 ac8fdc23cf..9c2846a614 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,41 +582,43 @@ :options animation-opts :on-change change-animation-type}]]] - ;; Direction + ;; Way (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"} - [:& radio-button {:value "in" - :id "animation-way-in"}] - [:& radio-button {:id "animation-way-out" - :value "out"}]]]]) + [:> 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"}]}]]]) ;; 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"} - [:& 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"}]]]]) + [:> 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"}]}]]]) ;; 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 320abd7d18..45fe2bc7e1 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 @@ -23,12 +23,13 @@ [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.context :as muc] + [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [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.formats :as fmt] [app.main.ui.hooks :as h] @@ -202,128 +203,118 @@ :space-between i/align-content-row-between :stretch i/align-content-row-stretch)))) -(mf/defc direction-row-flex - {::mf/props :obj - ::mf/private true} +(mf/defc direction-row-flex* + {::mf/private true} [{:keys [value on-change]}] - [:& 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)}]]) + [:> 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"}]}]) -(mf/defc wrap-row - {::mf/props :obj} +(mf/defc wrap-row* [{:keys [wrap-type on-click]}] - [: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]) + [:> 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}]) -(mf/defc align-row - {::mf/props :obj} +(mf/defc align-row* [{:keys [is-column value on-change]}] - [:& 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"}]]) + [:> 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"}]}]) -(mf/defc align-content-row - {::mf/props :obj} +(mf/defc align-content-row* [{:keys [is-column value on-change]}] - [:& 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"}]]) + [:> 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"}]}]) -(mf/defc justify-content-row - {::mf/props :obj} +(mf/defc justify-content-row* [{: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"} - [:& 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"}]]) + [:> 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"}]}]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PADDING @@ -679,14 +670,12 @@ (= type :multiple) [:> multiple-padding-selection* props])] - [: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]])) + [:> 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}]])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; GAP @@ -831,25 +820,22 @@ ;; GRID COMPONENTS -(mf/defc direction-row-grid - {::mf/props :obj} +(mf/defc direction-row-grid* [{:keys [value on-change] :as props}] - [:& 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)}]]) + [:> 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"}]}]) -(mf/defc grid-edit-mode - {::mf/props :obj} +(mf/defc grid-edit-mode* [{:keys [id]}] (let [edition (mf/deref refs/selected-edition) active? (= id edition) @@ -861,81 +847,65 @@ (if-not active? (st/emit! (udw/start-edition-mode id)) (st/emit! :interrupt))))] - [:button - {:class (stl/css :edit-mode-btn) - :alt "Grid edit mode" - :on-click toggle-edit-mode} + + [:> button* {:variant "secondary" + :class (stl/css :edit-mode-btn) + :on-click toggle-edit-mode} (tr "workspace.layout_grid.editor.options.edit-grid")])) -(mf/defc align-grid-row - {::mf/props :obj - ::mf/private true} +(mf/defc align-grid-row* + {::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) - :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)}]])) + [:> 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-flex-icon :align-items :start is-column) + :label "Align items start" + :value "start"} + {:id (dm/str "align-items-center-" type) + :icon (get-layout-flex-icon :align-items :center is-column) + :label "Align items center" + :value "center"} + {:id (dm/str "align-items-end-" type) + :icon (get-layout-flex-icon :align-items :end is-column) + :label "Align items end" + :value "end"}]}])) -(mf/defc justify-grid-row - {::mf/props :obj - ::mf/private :obj} +(mf/defc justify-grid-row* + {::mf/private true} [{: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 - :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)}]])) + [:> 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"}]}])) (defn- manage-values [{:keys [type value]}] @@ -946,8 +916,7 @@ :fixed (fmt/format-pixels value) value)) -(mf/defc grid-track-info - {::mf/props :obj} +(mf/defc grid-track-info* [{:keys [is-column type index @@ -1030,8 +999,7 @@ :data-index index :icon i/remove}]])) -(mf/defc grid-columns-row - {::mf/props :obj} +(mf/defc grid-columns-row* [{: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) @@ -1052,27 +1020,38 @@ [:div {:class (stl/css :grid-tracks) :data-testid testid} [:div {:class (stl/css :grid-track-header)} - [:button {:class (stl/css :expand-icon) :on-click toggle} deprecated-icon/menu] + [:> 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] [: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]] - [:button {:class (stl/css :add-column) :on-click add-track} deprecated-icon/add]] + [:> 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]] (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 @@ -1208,8 +1187,8 @@ (mf/deps layout-type ids) (fn [dir] (if (= :flex layout-type) - (st/emit! (dwsl/update-layout ids {:layout-flex-dir dir})) - (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))) + (st/emit! (dwsl/update-layout ids {:layout-flex-dir (keyword dir)})) + (st/emit! (dwsl/update-layout ids {:layout-grid-dir (keyword dir)}))))) ;; Align grid align-items-row (:layout-align-items values) @@ -1219,13 +1198,13 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-justify-items value})))) + (st/emit! (dwsl/update-layout ids {:layout-justify-items (keyword value)})))) on-row-align-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-align-items value})))) + (st/emit! (dwsl/update-layout ids {:layout-align-items (keyword value)})))) ;; Justify grid grid-justify-content-row (:layout-justify-content values) @@ -1235,13 +1214,13 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-align-content value})))) + (st/emit! (dwsl/update-layout ids {:layout-align-content (keyword value)})))) on-row-justify-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-justify-content value})))) + (st/emit! (dwsl/update-layout ids {:layout-justify-content (keyword value)})))) on-toggle-dropdown-visibility (mf/use-fn #(swap! show-dropdown* not)) @@ -1314,31 +1293,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 :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 :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}])] - [:> 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)} + [:div {:class (stl/css :last-row)} [:> gap-section* {:is-column is-column :wrap-type wrap-type :on-change on-gap-change @@ -1356,7 +1335,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 @@ -1365,23 +1344,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 @@ -1407,7 +1386,7 @@ (mf/use-fn (mf/deps ids) (fn [dir] - (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})))) + (st/emit! (dwsl/update-layout ids {:layout-grid-dir (keyword dir)})))) on-gap-change (mf/use-fn @@ -1446,13 +1425,13 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-justify-items value})))) + (st/emit! (dwsl/update-layout ids {:layout-justify-items (keyword value)})))) on-row-align-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-align-items value})))) + (st/emit! (dwsl/update-layout ids {:layout-align-items (keyword value)})))) ;; Justify grid grid-justify-content-row (:layout-justify-content values) @@ -1462,13 +1441,13 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-align-content value})))) + (st/emit! (dwsl/update-layout ids {:layout-align-content (keyword value)})))) on-row-justify-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout ids {:layout-justify-content value})))) + (st/emit! (dwsl/update-layout ids {:layout-justify-content (keyword value)})))) columns-open? (mf/use-state false) rows-open? (mf/use-state false) @@ -1549,31 +1528,32 @@ :aria-label (tr "labels.help-center") :on-click open-grid-help :icon i/help}] - [:button {:class (stl/css :exit-btn) - :on-click #(st/emit! (udw/clear-edition-mode))} + [:> button* {:variant "secondary" + :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) @@ -1587,33 +1567,33 @@ :applied-tokens applied-tokens :value (:layout-gap values)}]] - [:div {:class (stl/css :padding-row :padding-section)} + [:div {:class (stl/css :padding-row)} [:> 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 13d04e9446..18a2644d63 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,6 +42,7 @@ .flex-layout-menu { @include sidebar.option-grid-structure; + row-gap: var(--sp-s); margin-block-end: var(--sp-s); } @@ -49,8 +50,6 @@ grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; - margin-block-end: var(--sp-m); - margin-block-start: var(--sp-xs); } .align-row { @@ -61,27 +60,11 @@ grid-column: span 4; } -// 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); +.middle-row { + grid-column: span 8; + display: flex; + flex-direction: column; + row-gap: var(--sp-xs); } .align-content-row, @@ -89,7 +72,7 @@ grid-column: span 6; } -.forth-row { +.last-row { display: grid; grid-template-columns: var(--grid-exception-input-width) /* first input block */ @@ -100,9 +83,7 @@ } .help-button-wrapper { - grid-column: 1 / -1; display: flex; - flex-direction: row; justify-content: space-between; } @@ -149,23 +130,10 @@ 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, @@ -177,7 +145,6 @@ } .first-row { - margin-block-end: var(--sp-s); display: grid; grid-template-columns: subgrid; } @@ -202,20 +169,12 @@ grid-column: span 5; } -// TODO: Replace this buttons with DS buttons .edit-mode-btn { - @extend .button-secondary; - @include t.use-typography("headline-small"); - inline-size: 100%; - padding: var(--sp-s); + justify-content: center; 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; } @@ -227,14 +186,11 @@ 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 { @@ -293,7 +249,6 @@ display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; - margin-block-start: var(--sp-s); } .grid-track-header { @@ -304,7 +259,7 @@ border-radius: $br-8; overflow: hidden; background: var(--color-background-tertiary); - block-size: px2rem(52); + block-size: $sz-48; grid-column: 1 / -1; } @@ -328,44 +283,14 @@ color: var(--color-foreground-secondary); } -// TODO: Replace this buttons with DS buttons .expand-icon { - @extend .button-secondary; - block-size: px2rem(52); - + block-size: $sz-48; 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 { - @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); - } + block-size: $sz-48; + border-radius: 0 $br-8 $br-8 0; } .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 abd9490095..ca11e31ac9 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 @@ -14,8 +14,9 @@ [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.layout-container :refer [get-layout-flex-icon]] @@ -211,105 +212,85 @@ (= type :multiple) [:> margin-multiple* props])] - [:button {:class (stl/css-case - :margin-mode true - :selected (= type :multiple)) - :title "Margin - multiple" - :on-click on-type-change'} - deprecated-icon/margin]])) + [:> 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}]])) -(mf/defc element-behaviour-horizontal - {::mf/props :obj - ::mf/private true} +(mf/defc element-behaviour-horizontal* + {::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) - :decode-fn keyword - :on-change on-change - :name "flex-behaviour-h"} + [: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"})])}]]) - [:& 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} +(mf/defc element-behaviour-vertical* + {::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) - :decode-fn keyword - :on-change on-change - :name "flex-behaviour-v"} + [: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"})])}]]) - [:& radio-button - {:value "fix" - :icon i/fixed-width - :icon-class (stl/css :rotated) - :title "Fix height" - :id "behaviour-v-fix"}] - - (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} +(mf/defc align-self-row* [{:keys [^boolean is-col value on-change]}] - [:& 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"}]]) - + [:> 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"}]}]) (mf/defc layout-item-menu {::mf/memo #{:ids :values :type :is-layout-child? :is-grid-parent :is-flex-parent? :is-grid-layout? :is-flex-layout?} @@ -377,9 +358,10 @@ (mf/use-fn (mf/deps ids align-self) (fn [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}))))) + (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})))))) ;; Margin on-margin-type-change @@ -407,13 +389,13 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value})))) + (st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing (keyword value)})))) on-behaviour-v-change (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value})))) + (st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing (keyword value)})))) ;; Size and position on-size-change @@ -429,9 +411,10 @@ (mf/use-fn (mf/deps ids) (fn [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)})))) + (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)}))))) ;; Z Index on-change-z-index @@ -452,16 +435,17 @@ [:div {:class (stl/css :flex-element-menu)} (when (or is-layout-child? is-absolute?) [:div {:class (stl/css :position-row)} - [:div {:class (stl/css :position-options)} - [:& radio-buttons {:selected (if is-absolute? "absolute" "static") - :decode-fn keyword + [:> radio-buttons* {:class (stl/css :position-options) + :selected (if is-absolute? "absolute" "static") :on-change on-change-position :name "layout-style" - :wide true} - [:& radio-button {:value "static" - :id :static-position}] - [:& radio-button {:value "absolute" - :id :absolute-position}]]] + :extended true + :options [{:id "static-position" + :label "Static" + :value "static"} + {:id "absolute-position" + :label "Absolute" + :value "absolute"}]}] [:div {:class (stl/css :z-index-wrapper) :title "z-index"} @@ -480,22 +464,20 @@ :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 de32c3ce4b..664fb759b8 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 @@ -30,10 +30,8 @@ grid-template-columns: auto auto; } -.vertical-behaviour { - .rotated { - transform: rotate(90deg); - } +.rotated { + transform: rotate(90deg); } .z-index-wrapper { @@ -70,18 +68,6 @@ 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 813faf0847..3bc39653a0 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 @@ -26,11 +26,11 @@ [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.context :as muc] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.controls.numeric-input :refer [numeric-input*]] - [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] + [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.border-radius :refer [border-radius-menu*]] [app.util.dom :as dom] @@ -237,12 +237,6 @@ 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) @@ -390,19 +384,19 @@ ;; CLIP CONTENT AND SHOW IN VIEWER on-change-clip-content (mf/use-fn - (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)))))))) + (mf/deps ids values) + (fn [] + (let [value (not (:show-content values))] + (st/emit! (dwsh/update-shapes ids (fn [shape] (assoc shape :show-content value))))))) on-change-show-in-viewer (mf/use-fn - (mf/deps ids) - (fn [event] - (let [value (-> event dom/get-target dom/checked?) + (mf/deps ids values) + (fn [] + (let [value (not (:hide-in-viewer values)) undo-id (js/Symbol)] (st/emit! (dwu/start-undo-transaction undo-id) - (dwsh/update-shapes ids (fn [shape] (cls/change-show-in-viewer shape (not value))))) + (dwsh/update-shapes ids (fn [shape] (cls/change-show-in-viewer shape value)))) (when-not value ;; when a frame is no longer shown in view mode, cannot @@ -450,22 +444,23 @@ (when preset-match [:span {:class (stl/css :check-icon)} deprecated-icon/tick])])))]]] - [:& 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}]]) + [:> 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}]]) (when (options :size) [:div {:class (stl/css :size)} @@ -522,8 +517,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}]]) @@ -608,34 +603,20 @@ :applied-tokens applied-tokens :shapes shapes :shape shape}])]) - (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) - [: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}] + [:> 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}]) - [: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) - [: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}]]])])])) + [:> 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}])])])) 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 ffc4822ef0..719a46a2d9 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 @@ -144,16 +144,6 @@ 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); @@ -166,28 +156,6 @@ 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 c2f9226250..0989aab7b2 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 @@ -18,15 +18,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.ui :as txu] @@ -35,96 +35,99 @@ [potok.v2.core :as ptk] [rumext.v2 :as mf])) -(mf/defc text-align-options - [{:keys [values on-change on-blur] :as props}] +(mf/defc text-align-options* + [{:keys [values on-change on-blur]}] (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))))] - ;; --- Align - [:div {:class (stl/css :align-options)} - [:& radio-buttons {:selected text-align + [:> radio-buttons* {:class (stl/css :align-options) + :selected text-align :on-change handle-change - :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}]]])) + :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"}]}])) -(mf/defc text-direction-options - [{:keys [values on-change on-blur] :as props}] +(mf/defc text-direction-options* + [{:keys [values on-change on-blur]}] (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)))))] - [:div {:class (stl/css :text-direction-options)} - [:& radio-buttons {:selected direction + [:> radio-buttons* {:class (stl/css :text-direction-options) + :selected direction :on-change handle-change - :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}]]])) + :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"}]}])) -(mf/defc vertical-align - [{:keys [values on-change on-blur] :as props}] +(mf/defc vertical-align* + [{:keys [values on-change on-blur]}] (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))))] - [:div {:class (stl/css :vertical-align-options)} - [:& radio-buttons {:selected vertical-align + [:> radio-buttons* {:class (stl/css :vertical-align-options) + :selected vertical-align :on-change handle-change - :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}]]])) + :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"}]}])) -(mf/defc grow-options - [{:keys [ids values on-blur] :as props}] +(mf/defc grow-options* + [{:keys [ids values on-blur]}] (let [grow-type (:grow-type values) handle-change-grow @@ -141,55 +144,56 @@ (st/emit! (dwt/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))))] - [:div {:class (stl/css :grow-options)} - [:& radio-buttons {:selected (d/name grow-type) + [:> radio-buttons* {:class (stl/css :grow-options) + :selected (d/name grow-type) :on-change handle-change-grow - :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}]]])) + :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"}]}])) -(mf/defc text-decoration-options - [{:keys [values on-change on-blur] :as props}] +(mf/defc text-decoration-options* + [{:keys [values on-change on-blur]}] (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)))))] - [:div {:class (stl/css :text-decoration-options)} - [:& radio-buttons {:selected text-decoration - :on-change handle-change - :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}]]])) + (when (some? on-blur) + (on-blur)))))] -(mf/defc text-menu + [:> radio-buttons* {:class (stl/css :text-decoration-options) + :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"}]}])) + +(mf/defc text-menu* {::mf/wrap [mf/memo]} - [{:keys [ids type values] :as props}] + [{:keys [ids type values]}] (let [file-id (mf/use-ctx ctx/current-file-id) typographies (mf/deref refs/workspace-file-typography) @@ -282,18 +286,19 @@ multiple? (->> values vals (d/seek #(= % :multiple))) - 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))))))}] + 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))))))})] (hooks/use-stream expand-stream #(swap! state* assoc-in [:more-options] true)) @@ -315,11 +320,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)} @@ -330,19 +335,20 @@ deprecated-icon/detach]] :else - [:> text-options opts]) + [:> text-options* props]) [:div {:class (stl/css :text-align-options)} - [:> text-align-options opts] - [:> grow-options opts] + [:> text-align-options* props] + [:> grow-options* props] [:> 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 opts] - [:> text-decoration-options opts] - [:> text-direction-options opts]])])])) + [:div {:class (stl/css :text-decoration-options)} + [:> vertical-align* props] + [:> text-decoration-options* props] + [:> text-direction-options* props]])])])) 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 00a7ca455e..ef48c00f22 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] @@ -422,27 +422,24 @@ (on-change {:text-transform type})) (when (some? on-blur) (on-blur)))] - [:div {:class (stl/css :text-transform)} - [:& radio-buttons {:selected text-transform + [:> radio-buttons* {:selected text-transform :on-change handle-change - :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"}]]])) + :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"}]}])) -(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)) @@ -500,14 +497,13 @@ :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)}} @@ -547,7 +543,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 506fb58b34..b5c5ebaa62 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,15 +324,6 @@ } } } - .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 48a8b8ca0d..4b2fb0f4f7 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,8 +141,9 @@ [:> icon-button* {:variant "secondary" :icon i/menu :class (stl/css-case :shadow-basic-button true - :selected is-open) - :aria-label "open more options" + :hidden hidden?) + :aria-pressed is-open + :aria-label (tr "labels.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 f13404d03e..b4355228d9 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,14 +43,8 @@ .shadow-basic-button { border-radius: $br-8 0 0 $br-8; - - &.selected { - --button-bg-color: var(--color-background-quaternary); - --button-fg-color: var(--color-accent-primary); - } - - &:disabled { - border: $b-1 solid var(--color-background-quaternary); + &.hidden { + border: deprecated.$s-1 solid var(--input-border-color-disabled); } } 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 ddd77e2735..4efd8f7ac1 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 @@ -169,7 +169,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 c809647ba1..bcefd8b3bb 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 7cf76bcad2..4d5b180409 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* @@ -160,10 +160,9 @@ {: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 e243042a3d..41e5e01640 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,14 +12,15 @@ [app.common.schema :as sm] [app.common.types.token :as cto] [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] @@ -231,18 +232,17 @@ :aria-label (tr "workspace.tokens.shadow-add-shadow") :on-click on-add-shadow-block :icon i/add}] - [:& 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"}]]] + [:> 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"}]}]] (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 474d6cb5b5..f8a488765d 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,11 +12,13 @@ [app.common.schema :as sm] [app.common.types.token :as cto] [app.main.data.workspace.tokens.errors :as wte] - [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] + [app.main.ui.ds.controls.radio-buttons :refer [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] @@ -185,18 +187,17 @@ [:* [:div {:class (stl/css :title-bar)} [:div {:class (stl/css :title)} (tr "labels.typography")] - [:& 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"}]]] + [:> 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"}]}]] [: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 7df19b02c8..033d680354 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 @@ -16,11 +16,11 @@ [app.main.data.workspace.tokens.library-edit :as dwtl] [app.main.refs :as refs] [app.main.store :as st] - [app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]] [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.input :refer [input*]] + [app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]] [app.main.ui.ds.controls.utilities.label :refer [label*]] [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] [app.main.ui.ds.foundations.typography.heading :refer [heading*]] @@ -85,20 +85,20 @@ :on-click create-theme} (tr "workspace.tokens.add-new-theme")]]]])) -(mf/defc switch +(mf/defc switch* [{:keys [selected? name on-change]}] (let [selected (if selected? :on :off)] - [:& radio-buttons {:selected selected - :on-change on-change - :name name} - [:& radio-button {:id :on - :value :on - :icon i/tick - :label ""}] - [:& radio-button {:id :off - :value :off - :icon i/close - :label ""}]])) + [:> radio-buttons* {:selected selected + :on-change on-change + :name name + :options [{:id "on" + :icon i/tick + :label (tr "workspace.tokens.theme.enable") + :value :on} + {:id "off" + :icon i/close + :label (tr "workspace.tokens.theme.disable") + :value :off}]}])) (mf/defc themes-overview [{:keys [change-view]}] @@ -151,9 +151,9 @@ (dom/prevent-default e) (dom/stop-propagation e) (st/emit! (dwtl/toggle-token-theme-active id)))} - [:& switch {:name (tr "workspace.tokens.theme-name" name) - :on-change (constantly nil) - :selected? selected?}]]] + [:> switch* {:name (tr "workspace.tokens.theme-name" name) + :on-change (constantly nil) + :selected? selected?}]]] [:div {:class (stl/css :theme-name-row)} [:> text* {:as "span" :typography "body-medium" :class (stl/css :theme-name) :title name} name]] diff --git a/frontend/src/app/main/ui/workspace/top_toolbar.cljs b/frontend/src/app/main/ui/workspace/top_toolbar.cljs index 54a6bca3e0..d2b2716037 100644 --- a/frontend/src/app/main/ui/workspace/top_toolbar.cljs +++ b/frontend/src/app/main/ui/workspace/top_toolbar.cljs @@ -17,9 +17,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.context :as ctx] - [app.main.ui.icons :as deprecated-icon] + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] + [app.main.ui.ds.foundations.assets.icon :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.timers :as ts] @@ -27,7 +28,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) @@ -53,18 +54,17 @@ :position (gpt/point x y)}] (st/emit! (dwm/upload-media-workspace params)))))] [:li - [: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}]]])) + [:> 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}]]])) (def ^:private toolbar-hidden-ref (l/derived (fn [state] @@ -136,98 +136,104 @@ [:ul {:class (stl/css :main-toolbar-options) :data-testid "toolbar-options"} [:li - [: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]] + [:> 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}]] [:* [:li - [: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]] + [:> 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"}]] [:li - [: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]] + [:> 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"}]] [:li - [: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]] + [:> 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"}]] [:li - [: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]] + [:> 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"}]] - [:& image-upload] + [:> image-upload*] [:li - [: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]] + [:> 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"}]] [:li - [: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]] + [:> 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"}]] (when (features/active-feature? @st/state "plugins/runtime") [:li - [: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]]) + [:> 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"}]]) (when *assert* [:li - [: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]])]] + [:> icon-button* {:variant "ghost" + :class (stl/css :main-toolbar-options-button) + :icon i/bug + :aria-pressed (contains? layout :debug-panel) + :aria-label "Debugging tool" + :tooltip-placement "bottom" + :on-click toggle-debug-panel}]])]] [: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 d005682878..a2837cc433 100644 --- a/frontend/src/app/main/ui/workspace/top_toolbar.scss +++ b/frontend/src/app/main/ui/workspace/top_toolbar.scss @@ -54,6 +54,7 @@ align-items: center; margin: 0; opacity: deprecated.$op-10; + gap: var(--sp-xs); transition: opacity 0.3s ease; li { @@ -62,21 +63,8 @@ } .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 { @@ -97,7 +85,3 @@ 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 869fc0f178..f20c9face5 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,6 +28,7 @@ [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] @@ -59,11 +60,13 @@ [: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 {:class (stl/css :locate-btn) - :on-click #(st/emit! (dwge/locate-board (:id shape)))} + [:> button* {:variant "secondary" + :class (stl/css :action-btn) + :on-click #(st/emit! (dwge/locate-board (:id shape)))} (tr "workspace.layout_grid.editor.top-bar.locate")] - [:button {:class (stl/css :done-btn) - :on-click #(st/emit! (dw/clear-edition-mode))} + [:> button* {:variant "primary" + :class (stl/css :action-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 d0f1549cb1..76859a85ff 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,18 +138,8 @@ padding-left: deprecated.$s-8; } -.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; +.action-btn { + padding: 0 var(--sp-xl); } .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 81bd964e5c..9ca8f4d526 100644 --- a/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs @@ -11,40 +11,11 @@ [app.main.data.workspace.path :as drp] [app.main.data.workspace.path.shortcuts :as sc] [app.main.store :as st] - [app.main.ui.icons :as deprecated-icon] + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] + [app.main.ui.ds.foundations.assets.icon :as i] [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) @@ -144,76 +115,91 @@ [:div {:class (stl/css :sub-actions) :data-dont-clear-path true} [:div {:class (stl/css :sub-actions-group)} - ;; 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] - + [:> 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}] ;; 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]] + [:> 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}]] [:div {:class (stl/css :sub-actions-group)} ;; Add Node - [: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] - + [:> 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))}] ;; Remove node - [: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]] + [:> 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))}]] [:div {:class (stl/css :sub-actions-group)} ;; Merge Nodes - [: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] - + [:> 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))}] ;; Join Nodes - [: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] - + [:> 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))}] ;; Separate Nodes - [: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]] + [:> 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))}]] [:div {:class (stl/css :sub-actions-group)} ; Make Corner - [: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] - + [:> 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 - [: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]] + [:> 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))}]] + [:div {:class (stl/css :sub-actions-group)} ;; 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]]])) + [:> 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}]]])) 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 94c86e6a8d..d6fa360618 100644 --- a/frontend/src/app/main/ui/workspace/viewport/path_actions.scss +++ b/frontend/src/app/main/ui/workspace/viewport/path_actions.scss @@ -34,27 +34,11 @@ 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 b9f4f69cb4..8aeaf5db3d 100644 --- a/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/top_bar.cljs @@ -10,6 +10,7 @@ [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]] @@ -34,8 +35,9 @@ [:> i18n/tr-html* {:tag-name "span" :content (tr "workspace.top-bar.view-only")}]] - [:button {:class (stl/css :done-btn) - :on-click handle-close-view-mode} + [:> button* {:variant "primary" + :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 802dc32ab7..d9dd78f4fd 100644 --- a/frontend/src/app/main/ui/workspace/viewport/top_bar.scss +++ b/frontend/src/app/main/ui/workspace/viewport/top_bar.scss @@ -45,10 +45,7 @@ } .done-btn { - @extend .button-primary; - text-transform: uppercase; - padding: deprecated.$s-8 deprecated.$s-20; - font-size: deprecated.$fs-11; + padding: 0 var(--sp-xl); } .viewport-actions-no-rulers { diff --git a/frontend/translations/en.po b/frontend/translations/en.po index df899cb398..5a34b0fc81 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -5168,6 +5168,10 @@ msgstr "Show interactions on click" msgid "viewer.header.sitemap" msgstr "Sitemap" +#: src/app/main/ui/viewer/header.cljs:185 +msgid "viewer.header.edit-in-workspace" +msgstr "Edit in workspace" + #: src/app/main/ui/dashboard/team.cljs:1203 msgid "webhooks.last-delivery.success" msgstr "Last delivery was successful." @@ -5393,6 +5397,10 @@ 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." @@ -5679,7 +5687,11 @@ msgstr "Full screen" msgid "workspace.header.zoom-selected" msgstr "Zoom to selected" -#: 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 +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:217 +msgid "workspace.layout_grid.editor.margin.expand" +msgstr "Show 4 sided margin options" + +#: src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:273, src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:275, src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:868 msgid "workspace.layout_grid.editor.options.edit-grid" msgstr "Edit grid" @@ -5731,6 +5743,30 @@ 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:234 +msgid "workspace.layout_item.fix-width" +msgstr "Fix width" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:238 +msgid "workspace.layout_item.width-100" +msgstr "Width 100%" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:242 +msgid "workspace.layout_item.fit-content-horizontal" +msgstr "Fit content (Horizontal)" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:260 +msgid "workspace.layout_item.fix-height" +msgstr "Fix height" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:264 +msgid "workspace.layout_item.height-100" +msgstr "Height 100%" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:268 +msgid "workspace.layout_item.fit-content-vertical" +msgstr "Fit content (Vertical)" + #: src/app/main/ui/workspace/libraries.cljs #, unused msgid "workspace.libraries.add" @@ -6331,7 +6367,31 @@ msgstr "After delay" msgid "workspace.options.interaction-animation" msgstr "Animation" -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:383 +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:609 +msgid "workspace.options.interaction-animation-direction-right" +msgstr "Right" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:613 +msgid "workspace.options.interaction-animation-direction-left" +msgstr "Left" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:617 +msgid "workspace.options.interaction-animation-direction-down" +msgstr "Down" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:621 +msgid "workspace.options.interaction-animation-direction-up" +msgstr "Up" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:595 +msgid "workspace.options.interaction-animation-direction-in" +msgstr "In" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:599 +msgid "workspace.options.interaction-animation-direction-out" +msgstr "Out" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:413 msgid "workspace.options.interaction-animation-dissolve" msgstr "Dissolve" @@ -6776,6 +6836,14 @@ msgstr "More color tokens" msgid "workspace.options.opacity" msgstr "Opacity" +#: src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:457, frontend/src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:108 +msgid "workspace.options.orientation.horizontal" +msgstr "Horizontal" + +#: src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:453, frontend/src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:104 +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" @@ -7610,6 +7678,10 @@ msgstr "Layers" msgid "workspace.sidebar.layers.components" msgstr "Components" +#: src/app/main/ui/workspace/sidebar/layers.cljs:295 +msgid "workspace.sidebar.layers.filter" +msgstr "Filter" + #: 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" @@ -8209,7 +8281,15 @@ msgstr "none | uppercase | lowercase | capitalize or {alias}" msgid "workspace.tokens.text-decoration-value-enter" msgstr "none | underline | strike-through or {alias}" -#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:154 +#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:100 +msgid "workspace.tokens.theme.disable" +msgstr "Disable" + +#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:96 +msgid "workspace.tokens.theme.enable" +msgstr "Enable" + +#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:155 msgid "workspace.tokens.theme-name" msgstr "Theme %s" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 32aaded44a..53fae37da9 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -5147,6 +5147,10 @@ msgstr "Mostrar interacciones al hacer click" msgid "viewer.header.sitemap" msgstr "Mapa del sitio" +#: src/app/main/ui/viewer/header.cljs:185 +msgid "viewer.header.edit-in-workspace" +msgstr "Editar en el espacio de trabajo" + #: src/app/main/ui/dashboard/team.cljs:1203 msgid "webhooks.last-delivery.success" msgstr "El último envío fue correcto." @@ -5374,6 +5378,10 @@ 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." @@ -5655,7 +5663,11 @@ msgstr "Pantalla completa" msgid "workspace.header.zoom-selected" msgstr "Zoom a selección" -#: 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 +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:217 +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:273, src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs:275, src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs:868 msgid "workspace.layout_grid.editor.options.edit-grid" msgstr "Editar rejilla" @@ -5707,6 +5719,30 @@ 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:234 +msgid "workspace.layout_item.fix-width" +msgstr "Fijar anchura" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:238 +msgid "workspace.layout_item.width-100" +msgstr "Anchura 100%" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:242 +msgid "workspace.layout_item.fit-content-horizontal" +msgstr "Ajustar contenido (horizontal)" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:260 +msgid "workspace.layout_item.fix-height" +msgstr "Fijar altura" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:264 +msgid "workspace.layout_item.height-100" +msgstr "Altura 100%" + +#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs:268 +msgid "workspace.layout_item.fit-content-vertical" +msgstr "Ajustar contenido (vertical)" + #: src/app/main/ui/workspace/libraries.cljs #, unused msgid "workspace.libraries.add" @@ -6271,7 +6307,31 @@ msgstr "Tiempo" msgid "workspace.options.interaction-animation" msgstr "Animación" -#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:383 +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:609 +msgid "workspace.options.interaction-animation-direction-right" +msgstr "Derecha" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:613 +msgid "workspace.options.interaction-animation-direction-left" +msgstr "Izquierda" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:617 +msgid "workspace.options.interaction-animation-direction-down" +msgstr "Abajo" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:621 +msgid "workspace.options.interaction-animation-direction-up" +msgstr "Arriba" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:595 +msgid "workspace.options.interaction-animation-direction-in" +msgstr "Dentro" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:599 +msgid "workspace.options.interaction-animation-direction-out" +msgstr "Fuera" + +#: src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs:413 msgid "workspace.options.interaction-animation-dissolve" msgstr "Disolver" @@ -6716,6 +6776,14 @@ msgstr "Más tokens de color" msgid "workspace.options.opacity" msgstr "Opacidad" +#: src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:457, frontend/src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:108 +msgid "workspace.options.orientation.horizontal" +msgstr "Horizontal" + +#: src/app/main/ui/workspace/sidebar/options/menus/measures.cljs:453, frontend/src/app/main/ui/workspace/sidebar/options/drawing/frame.cljs:104 +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" @@ -7554,6 +7622,10 @@ msgstr "Capas" msgid "workspace.sidebar.layers.components" msgstr "Componentes" +#: src/app/main/ui/workspace/sidebar/layers.cljs:295 +msgid "workspace.sidebar.layers.filter" +msgstr "Filtrar" + #: 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" @@ -8088,7 +8160,15 @@ msgstr "none | uppercase | lowercase | capitalize o {alias}" 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 +#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:100 +msgid "workspace.tokens.theme.disable" +msgstr "Deshabilitar" + +#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:96 +msgid "workspace.tokens.theme.enable" +msgstr "Habilitar" + +#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:155 msgid "workspace.tokens.theme-name" msgstr "Tema %s"