From 079b3fbfad09cc3e0271b4dc9139362b00db5936 Mon Sep 17 00:00:00 2001 From: Luis de Dios Date: Tue, 20 Jan 2026 18:56:25 +0100 Subject: [PATCH] :recycle: Extract and create panel title component (#8090) --- .../styles/common/refactor/design-tokens.scss | 1 - frontend/src/app/main/ui/ds.cljs | 2 ++ .../app/main/ui/ds/product/panel_title.cljs | 34 +++++++++++++++++++ .../app/main/ui/ds/product/panel_title.mdx | 26 ++++++++++++++ .../app/main/ui/ds/product/panel_title.scss | 25 ++++++++++++++ .../ui/ds/product/panel_title.stories.jsx | 21 ++++++++++++ .../src/app/main/ui/workspace/comments.cljs | 17 ++++------ .../src/app/main/ui/workspace/comments.scss | 21 ++---------- .../app/main/ui/workspace/sidebar/debug.cljs | 14 +++----- .../app/main/ui/workspace/sidebar/debug.scss | 23 +++---------- .../workspace/sidebar/debug_shape_info.cljs | 10 +++--- .../workspace/sidebar/debug_shape_info.scss | 29 +--------------- .../main/ui/workspace/sidebar/history.scss | 17 ---------- .../main/ui/workspace/sidebar/shortcuts.cljs | 12 +++---- .../main/ui/workspace/sidebar/shortcuts.scss | 23 ++----------- .../app/main/ui/workspace/top_toolbar.cljs | 2 +- frontend/translations/en.po | 8 +++++ frontend/translations/es.po | 8 +++++ 18 files changed, 155 insertions(+), 138 deletions(-) create mode 100644 frontend/src/app/main/ui/ds/product/panel_title.cljs create mode 100644 frontend/src/app/main/ui/ds/product/panel_title.mdx create mode 100644 frontend/src/app/main/ui/ds/product/panel_title.scss create mode 100644 frontend/src/app/main/ui/ds/product/panel_title.stories.jsx diff --git a/frontend/resources/styles/common/refactor/design-tokens.scss b/frontend/resources/styles/common/refactor/design-tokens.scss index a9f8074707..37f6c546f1 100644 --- a/frontend/resources/styles/common/refactor/design-tokens.scss +++ b/frontend/resources/styles/common/refactor/design-tokens.scss @@ -17,7 +17,6 @@ --app-background: var(--color-background-primary); --loader-background: var(--color-background-primary); - --panel-title-background-color: var(--color-background-secondary); // BUTTONS --button-foreground-hover: var(--color-accent-primary); diff --git a/frontend/src/app/main/ui/ds.cljs b/frontend/src/app/main/ui/ds.cljs index aa4c56f472..91152dc0e6 100644 --- a/frontend/src/app/main/ui/ds.cljs +++ b/frontend/src/app/main/ui/ds.cljs @@ -38,6 +38,7 @@ [app.main.ui.ds.product.loader :refer [loader*]] [app.main.ui.ds.product.milestone :refer [milestone*]] [app.main.ui.ds.product.milestone-group :refer [milestone-group*]] + [app.main.ui.ds.product.panel-title :refer [panel-title*]] [app.main.ui.ds.storybook :as sb] [app.main.ui.ds.tooltip.tooltip :refer [tooltip*]] [app.main.ui.ds.utilities.date :refer [date*]] @@ -81,6 +82,7 @@ :Milestone milestone* :MilestoneGroup milestone-group* :Date date* + :PanelTitle panel-title* :set-default-translations (fn [data] diff --git a/frontend/src/app/main/ui/ds/product/panel_title.cljs b/frontend/src/app/main/ui/ds/product/panel_title.cljs new file mode 100644 index 0000000000..32eef07a1e --- /dev/null +++ b/frontend/src/app/main/ui/ds/product/panel_title.cljs @@ -0,0 +1,34 @@ +;; 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.product.panel-title + (:require-macros + [app.main.style :as stl]) + (:require + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] + [app.main.ui.ds.foundations.assets.icon :as i] + [app.util.i18n :refer [tr]] + [rumext.v2 :as mf])) + +(def ^:private schema:panel-title + [:map + [:class {:optional true} :string] + [:text :string] + [:on-close {:optional true} fn?]]) + +(mf/defc panel-title* + {::mf/schema schema:panel-title} + [{:keys [class text on-close] :rest props}] + (let [props + (mf/spread-props props {:class [class (stl/css :panel-title)]})] + + [:> :div props + [:span {:class (stl/css :panel-title-text)} text] + (when on-close + [:> icon-button* {:variant "ghost" + :aria-label (tr "labels.close") + :on-click on-close + :icon i/close}])])) diff --git a/frontend/src/app/main/ui/ds/product/panel_title.mdx b/frontend/src/app/main/ui/ds/product/panel_title.mdx new file mode 100644 index 0000000000..1a1c7b7a5f --- /dev/null +++ b/frontend/src/app/main/ui/ds/product/panel_title.mdx @@ -0,0 +1,26 @@ +{ /* 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 PanelTitle from "./panel_title.stories"; + + + +# PanelTitle + +The `panel-title*` is used as a header for some sidebar sections. + + + +## Technical notes + +The only mandatory parameter is `text`. Usually you'll want to pass a function property `on-close` that will be called when the user clicks on the close button on the right. + +```clj +[:> panel-title* {:class class + :text text + :on-close on-close}] +``` diff --git a/frontend/src/app/main/ui/ds/product/panel_title.scss b/frontend/src/app/main/ui/ds/product/panel_title.scss new file mode 100644 index 0000000000..e0419221e4 --- /dev/null +++ b/frontend/src/app/main/ui/ds/product/panel_title.scss @@ -0,0 +1,25 @@ +// 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/_sizes.scss" as *; +@use "ds/_borders.scss" as *; +@use "ds/typography.scss" as t; + +.panel-title { + display: flex; + align-items: center; + justify-content: center; + block-size: $sz-32; + border-radius: $br-8; + background-color: var(--color-background-secondary); +} + +.panel-title-text { + @include t.use-typography("headline-small"); + flex-grow: 1; + text-align: center; + color: var(--color-foreground-primary); +} diff --git a/frontend/src/app/main/ui/ds/product/panel_title.stories.jsx b/frontend/src/app/main/ui/ds/product/panel_title.stories.jsx new file mode 100644 index 0000000000..e601d56934 --- /dev/null +++ b/frontend/src/app/main/ui/ds/product/panel_title.stories.jsx @@ -0,0 +1,21 @@ +import * as React from "react"; +import Components from "@target/components"; + +const { PanelTitle } = Components; + +export default { + title: "Product/PanelTitle", + component: PanelTitle, + argTypes: { + text: { + control: { type: "text" }, + }, + }, + args: { + text: "Lorem ipsum", + onClose: () => null, + }, + render: ({ ...args }) => , +}; + +export const Default = {}; diff --git a/frontend/src/app/main/ui/workspace/comments.cljs b/frontend/src/app/main/ui/workspace/comments.cljs index 4dbfc71c6e..f03acb4f2a 100644 --- a/frontend/src/app/main/ui/workspace/comments.cljs +++ b/frontend/src/app/main/ui/workspace/comments.cljs @@ -16,9 +16,9 @@ [app.main.ui.comments :as cmt] [app.main.ui.components.dropdown :refer [dropdown]] [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.ds.product.empty-state :refer [empty-state*]] + [app.main.ui.ds.product.panel-title :refer [panel-title*]] [app.main.ui.icons :as deprecated-icon] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -121,15 +121,12 @@ (st/emit! (with-meta (dcmt/open-thread thread) {::ev/origin "viewer"})) (st/emit! (dwcm/navigate-to-comment thread)))))] - [:div {:class (stl/css-case :comments-section true - :from-viewer from-viewer)} - [:div {:class (stl/css-case :comments-section-title true - :viewer-title from-viewer)} - [:span (tr "labels.comments")] - [:> icon-button* {:variant "ghost" - :aria-label (tr "labels.close") - :on-click close-section - :icon i/close}]] + [:div {:class (stl/css-case :comments-section true + :from-viewer from-viewer)} + + [:> panel-title* {:class (stl/css :comments-title) + :text (tr "labels.comments") + :on-close close-section}] [:button {:class (stl/css :mode-dropdown-wrapper) :on-click toggle-mode-selector} diff --git a/frontend/src/app/main/ui/workspace/comments.scss b/frontend/src/app/main/ui/workspace/comments.scss index 5a7c7e2dd3..1cd9c04b64 100644 --- a/frontend/src/app/main/ui/workspace/comments.scss +++ b/frontend/src/app/main/ui/workspace/comments.scss @@ -18,25 +18,8 @@ padding: 0 deprecated.$s-8; } -.comments-section-title { - @include deprecated.flexCenter; - @include deprecated.uppercaseTitleTipography; - position: relative; - height: deprecated.$s-32; - min-height: deprecated.$s-32; - margin: deprecated.$s-8 deprecated.$s-8 0 deprecated.$s-8; - border-radius: deprecated.$br-8; - background-color: var(--panel-title-background-color); - span { - @include deprecated.flexCenter; - flex-grow: 1; - color: var(--title-foreground-color-hover); - } -} - -.viewer-title { - margin: 0; - margin-block-start: deprecated.$s-8; +.comments-title { + margin: var(--sp-s) var(--sp-s) 0 var(--sp-s); } .mode-dropdown-wrapper { diff --git a/frontend/src/app/main/ui/workspace/sidebar/debug.cljs b/frontend/src/app/main/ui/workspace/sidebar/debug.cljs index ffce84660f..3874279fc7 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/debug.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/debug.cljs @@ -11,12 +11,11 @@ [app.common.data.macros :as dm] [app.main.data.workspace :as dw] [app.main.store :as st] - [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] - [app.main.ui.ds.foundations.assets.icon :as i] + [app.main.ui.ds.product.panel-title :refer [panel-title*]] [app.main.ui.icons :as deprecated-icon] [app.util.debug :as dbg] [app.util.dom :as dom] - [app.util.i18n :as i18n :refer [tr]] + [app.util.i18n :refer [tr]] [rumext.v2 :as mf])) (mf/defc debug-panel* @@ -35,12 +34,9 @@ (st/emit! (dw/remove-layout-flag :debug-panel))))] [:div {:class (dm/str class " " (stl/css :debug-panel))} - [:div {:class (stl/css :panel-title)} - [:span "Debugging tools"] - [:> icon-button* {:variant "ghost" - :aria-label (tr "labels.close") - :on-click handle-close - :icon i/close}]] + [:> panel-title* {:class (stl/css :debug-panel-title) + :text (tr "workspace.debug.title") + :on-close handle-close}] [:div {:class (stl/css :debug-panel-inner)} (for [option (sort-by d/name dbg/options)] diff --git a/frontend/src/app/main/ui/workspace/sidebar/debug.scss b/frontend/src/app/main/ui/workspace/sidebar/debug.scss index ce9698a180..47f119009c 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/debug.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/debug.scss @@ -12,21 +12,12 @@ background-color: var(--panel-background-color); } -.panel-title { - @include deprecated.flexCenter; - @include deprecated.uppercaseTitleTipography; - position: relative; - height: deprecated.$s-32; - min-height: deprecated.$s-32; - margin: deprecated.$s-8 deprecated.$s-8 0 deprecated.$s-8; - border-radius: deprecated.$br-8; - background-color: var(--panel-title-background-color); +.debug-panel-title { + margin: var(--sp-s) var(--sp-s) 0 var(--sp-s); +} - span { - @include deprecated.flexCenter; - flex-grow: 1; - color: var(--title-foreground-color-hover); - } +.debug-panel-inner { + padding: deprecated.$s-16 deprecated.$s-8; } .checkbox-wrapper { @@ -39,7 +30,3 @@ @extend .checkbox-icon; cursor: pointer; } - -.debug-panel-inner { - padding: deprecated.$s-16 deprecated.$s-8; -} diff --git a/frontend/src/app/main/ui/workspace/sidebar/debug_shape_info.cljs b/frontend/src/app/main/ui/workspace/sidebar/debug_shape_info.cljs index 4a35c66975..69ce4ca670 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/debug_shape_info.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/debug_shape_info.cljs @@ -13,7 +13,7 @@ [app.main.data.workspace :as dw] [app.main.refs :as refs] [app.main.store :as st] - [app.main.ui.icons :as deprecated-icon] + [app.main.ui.ds.product.panel-title :refer [panel-title*]] [debug :as dbg] [rumext.v2 :as mf])) @@ -125,11 +125,9 @@ (map (d/getf objects)))] [:div {:class (stl/css :shape-info)} - [:div {:class (stl/css :shape-info-title)} - [:span "Debug"] - [:div {:class (stl/css :close-button) - :on-click #(dbg/disable! :shape-panel)} - deprecated-icon/close]] + [:> panel-title* {:class (stl/css :shape-info-title) + :text "Debug" + :on-close #(dbg/disable! :shape-panel)}] (if (empty? selected) [:div {:class (stl/css :attrs-container)} "No shapes selected"] diff --git a/frontend/src/app/main/ui/workspace/sidebar/debug_shape_info.scss b/frontend/src/app/main/ui/workspace/sidebar/debug_shape_info.scss index 45a00fe022..a72bf3a833 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/debug_shape_info.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/debug_shape_info.scss @@ -16,34 +16,7 @@ } .shape-info-title { - @include deprecated.flexCenter; - @include deprecated.uppercaseTitleTipography; - position: relative; - height: deprecated.$s-32; - min-height: deprecated.$s-32; - margin: deprecated.$s-8 deprecated.$s-8 0 deprecated.$s-8; - border-radius: deprecated.$br-8; - background-color: var(--panel-title-background-color); - - span { - @include deprecated.flexCenter; - flex-grow: 1; - color: var(--title-foreground-color-hover); - } -} - -.close-button { - @extend .button-tertiary; - position: absolute; - right: deprecated.$s-2; - top: deprecated.$s-2; - height: deprecated.$s-28; - width: deprecated.$s-28; - border-radius: deprecated.$br-6; - svg { - @extend .button-icon; - stroke: var(--icon-foreground); - } + margin: var(--sp-s) var(--sp-s) 0 var(--sp-s); } .attrs-container { diff --git a/frontend/src/app/main/ui/workspace/sidebar/history.scss b/frontend/src/app/main/ui/workspace/sidebar/history.scss index 993a2f123a..907e6732bf 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/history.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/history.scss @@ -13,23 +13,6 @@ background-color: var(--panel-background-color); } -.history-toolbox-title { - @include deprecated.flexCenter; - @include deprecated.uppercaseTitleTipography; - position: relative; - height: deprecated.$s-32; - min-height: deprecated.$s-32; - margin: deprecated.$s-8 deprecated.$s-8 0 deprecated.$s-8; - border-radius: deprecated.$br-8; - background-color: var(--panel-title-background-color); - - span { - @include deprecated.flexCenter; - flex-grow: 1; - color: var(--title-foreground-color-hover); - } -} - .history-entry-empty { display: flex; flex-direction: column; diff --git a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.cljs b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.cljs index 5f4f7e2e75..dd82656545 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.cljs @@ -18,8 +18,8 @@ [app.main.data.workspace.shortcuts] [app.main.store :as st] [app.main.ui.components.search-bar :refer [search-bar*]] - [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.foundations.assets.icon :as i :refer [icon*]] + [app.main.ui.ds.product.panel-title :refer [panel-title*]] [app.util.dom :as dom] [app.util.i18n :refer [tr]] [app.util.strings :refer [matches-search]] @@ -487,13 +487,9 @@ (dom/focus! (dom/get-element "shortcut-search"))) [:div {:class (dm/str class " " (stl/css :shortcuts))} - [:div {:class (stl/css :shortcuts-header)} - [:div {:class (stl/css :shortcuts-title)} (tr "shortcuts.title")] - [:> icon-button* {:variant "ghost" - :icon i/close - :class (stl/css :shortcuts-close-button) - :on-click close-fn - :aria-label (tr "labels.close")}]] + [:> panel-title* {:class (stl/css :shortcuts-title) + :text (tr "shortcuts.title") + :on-close close-fn}] [:div {:class (stl/css :search-field)} [:> search-bar* {:on-change on-search-term-change-2 diff --git a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss index 23aef8f116..56376d9f02 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss @@ -18,27 +18,8 @@ margin: deprecated.$s-16 deprecated.$s-12 deprecated.$s-4 deprecated.$s-12; } -.shortcuts-header { - @include deprecated.flexCenter; - @include deprecated.uppercaseTitleTipography; - position: relative; - height: deprecated.$s-32; - padding: deprecated.$s-2 deprecated.$s-2 deprecated.$s-2 0; - margin: deprecated.$s-4 deprecated.$s-4 0 deprecated.$s-4; - border-radius: deprecated.$br-6; - background-color: var(--panel-title-background-color); - - .shortcuts-title { - @include deprecated.flexCenter; - flex-grow: 1; - color: var(--title-foreground-color-hover); - } - - .shortcuts-close-button { - position: absolute; - right: 0; - top: 0; - } +.shortcuts-title { + margin: var(--sp-s) var(--sp-s) 0 var(--sp-s); } .section { diff --git a/frontend/src/app/main/ui/workspace/top_toolbar.cljs b/frontend/src/app/main/ui/workspace/top_toolbar.cljs index d2b2716037..6fc3a09d4e 100644 --- a/frontend/src/app/main/ui/workspace/top_toolbar.cljs +++ b/frontend/src/app/main/ui/workspace/top_toolbar.cljs @@ -228,7 +228,7 @@ :class (stl/css :main-toolbar-options-button) :icon i/bug :aria-pressed (contains? layout :debug-panel) - :aria-label "Debugging tool" + :aria-label (tr "workspace.toolbar.debug") :tooltip-placement "bottom" :on-click toggle-debug-panel}]])]] diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 43b44ee2a8..a514937354 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -5476,6 +5476,10 @@ msgstr "Delete row and shapes" msgid "workspace.context-menu.grid-track.row.duplicate" msgstr "Duplicate row" +#: src/app/main/ui/workspace/sidebar/debug.cljs:37 +msgid "workspace.debug.title" +msgstr "Debugging tools" + #: src/app/main/ui/workspace/sidebar/layers.cljs:512 msgid "workspace.focus.focus-mode" msgstr "Focus mode" @@ -8421,6 +8425,10 @@ msgstr "Comments (%s)" msgid "workspace.toolbar.curve" msgstr "Curve (%s)" +#: src/app/main/ui/workspace/top_toolbar.cljs:231 +msgid "workspace.toolbar.debug" +msgstr "Debugging tools" + #: src/app/main/ui/workspace/top_toolbar.cljs:172 msgid "workspace.toolbar.ellipse" msgstr "Ellipse (%s)" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 10552a09eb..2894156837 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -5461,6 +5461,10 @@ msgstr "Borrar fila con el contenido" msgid "workspace.context-menu.grid-track.row.duplicate" msgstr "Duplicar fila" +#: src/app/main/ui/workspace/sidebar/debug.cljs:37 +msgid "workspace.debug.title" +msgstr "Herramientas de depuración" + #: src/app/main/ui/workspace/sidebar/layers.cljs:512 msgid "workspace.focus.focus-mode" msgstr "Modo foco" @@ -8282,6 +8286,10 @@ msgstr "Comentarios (%s)" msgid "workspace.toolbar.curve" msgstr "Curva (%s)" +#: src/app/main/ui/workspace/top_toolbar.cljs:231 +msgid "workspace.toolbar.debug" +msgstr "Herramientas de depuración" + #: src/app/main/ui/workspace/top_toolbar.cljs:172 msgid "workspace.toolbar.ellipse" msgstr "Elipse (%s)"