diff --git a/frontend/resources/images/help-variant-connection.png b/frontend/resources/images/help-variant-connection.png new file mode 100644 index 0000000000..2d743678f7 Binary files /dev/null and b/frontend/resources/images/help-variant-connection.png differ 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 e6e3adadc4..d0a3aaf751 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 @@ -37,6 +37,7 @@ [app.main.ui.hooks :as h] [app.main.ui.icons :as i] [app.main.ui.workspace.sidebar.assets.common :as cmm] + [app.main.ui.workspace.sidebar.options.menus.variants-help-modal] [app.util.debug :as dbg] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -963,6 +964,12 @@ (mf/deps menu-open*) #(reset! menu-open* false)) + on-click-variant-title-help + (mf/use-fn + (fn [] + (modal/show! {:type :variants-help-modal}) + (modal/allow-click-outside!))) + update-property-name (mf/use-fn (mf/deps variant-id) @@ -1001,8 +1008,15 @@ [:& title-bar {:collapsable false :title (tr "workspace.options.component") :class (stl/css :title-spacing-component)} + [:span {:class (stl/css :copy-text)} - (tr "workspace.options.component.main")]]] + (tr "workspace.options.component.main")] + + [:div {:class (stl/css :variants-help-modal-button)} + [:> icon-button* {:variant "ghost" + :aria-label (tr "workspace.options.component.variants-help-modal.title") + :on-click on-click-variant-title-help + :icon "help"}]]]] [:div {:class (stl/css :element-content)} [:div {:class (stl/css-case :component-wrapper 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 fcf5ea7ed9..e352a32377 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 @@ -32,6 +32,15 @@ cursor: pointer; } +.title-spacing-component { + justify-content: flex-start; + gap: $s-4; +} + +.variants-help-modal-button { + margin-inline-start: auto; +} + .icon-back { @include flexCenter; width: $s-12; @@ -163,7 +172,6 @@ display: flex; align-items: center; color: var(--title-foreground-color); - margin-right: $s-8; } .swappeable { diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/variants_help_modal.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/variants_help_modal.cljs new file mode 100644 index 0000000000..adf33484b8 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/variants_help_modal.cljs @@ -0,0 +1,101 @@ + +;; 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.workspace.sidebar.options.menus.variants-help-modal + (:require-macros [app.main.style :as stl]) + (:require + [app.main.data.modal :as modal] + [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*] :as i] + [app.main.ui.ds.foundations.typography :as t] + [app.main.ui.ds.foundations.typography.heading :refer [heading*]] + [app.main.ui.ds.foundations.typography.text :refer [text*]] + [app.util.dom :as dom] + [app.util.i18n :as i18n :refer [tr]] + [rumext.v2 :as mf])) + +(mf/defc variants-help-modal + {::mf/register modal/components + ::mf/register-as :variants-help-modal} + [] + (let [on-close + (mf/use-fn + (fn [] (modal/hide!))) + + close-dialog-outside + (mf/use-fn + (fn [event] + (when (= (dom/get-target event) (dom/get-current-target event)) + (modal/hide!))))] + + [:div {:class (stl/css :modal-overlay) + :on-click close-dialog-outside} + [:div {:class (stl/css :modal-dialog)} + [:> icon-button* {:on-click on-close + :class (stl/css :modal-close-btn) + :icon i/close + :variant "action" + :aria-label (tr "labels.close")}] + [:> heading* {:level 2 + :typography "headline-medium" + :class (stl/css :modal-title)} + (tr "workspace.options.component.variants-help-modal.title")] + + [:div {:class (stl/css :modal-content)} + + [:div {:class (stl/css :help-text)} + + [:> text* {:typography t/body-large} + (tr "workspace.options.component.variants-help-modal.intro")] + + [:ul {:class (stl/css :rule-list)} + [:li {:class (stl/css :rule-item)} + [:div {:class (stl/css :rule-item-icon)} + [:> icon* {:icon-id i/text-mixed + :size "s" + :aria-hidden true}]] + + [:div {:class (stl/css :rule-item-text)} + [:> text* {:as "span" + :typography t/body-large + :class (stl/css :rule-item-highlight)} + (tr "workspace.options.component.variants-help-modal.rule1")]]] + [:li {:class (stl/css :rule-item)} + [:div {:class (stl/css :rule-item-icon)} + [:> icon* {:icon-id i/img + :size "s" + :aria-hidden true}]] + + [:> text* {:typography t/body-large + :class (stl/css :rule-item-text)} + [:span {:class (stl/css :rule-item-highlight)} (tr "workspace.options.component.variants-help-modal.rule2")] + (tr "workspace.options.component.variants-help-modal.rule2.detail")]] + + [:li {:class (stl/css :rule-item)} + [:div {:class (stl/css :rule-item-icon)} + [:> icon* {:icon-id i/folder + :size "s" + :aria-hidden true}]] + + [:> text* {:class (stl/css :rule-item-text) + :typography t/body-large} + [:span {:class (stl/css :rule-item-highlight)} (tr "workspace.options.component.variants-help-modal.rule3")] + (tr "workspace.options.component.variants-help-modal.rule3.detail")]]] + + [:> text* {:typography t/body-large} + (tr "workspace.options.component.variants-help-modal.outro")]] + + [:div {:class (stl/css :help-image)} + [:img {:src "images/help-variant-connection.png" + :alt ""}]]] + + [:div {:class (stl/css :button-row)} + [:> button* {:variant "primary" + :class (stl/css :modal-accept-btn) + :on-click on-close} + (tr "ds.confirm-ok")]]]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/variants_help_modal.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/variants_help_modal.scss new file mode 100644 index 0000000000..542860e8ff --- /dev/null +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/variants_help_modal.scss @@ -0,0 +1,84 @@ +// 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 "refactor/common-refactor.scss"; + +.modal-overlay { + @extend .modal-overlay-base; +} + +.modal-dialog { + @extend .modal-container-base; + + max-width: $s-800; + width: 100%; + max-height: unset; +} + +.modal-title { + color: var(--modal-title-foreground-color); + margin-bottom: $s-32; +} + +.modal-content { + display: flex; + color: var(--color-foreground-secondary); + padding-block-end: $s-32; +} + +.modal-close-btn { + @extend .modal-close-btn-base; +} + +.rule-list { + margin: $s-32 0; +} + +.rule-item { + display: flex; + gap: $s-16; + align-items: center; + margin-bottom: $s-16; + + &:last-child { + margin-bottom: 0; + } +} + +.rule-item-highlight { + color: var(--color-foreground-primary); + margin-inline-end: $s-4; +} + +.rule-item-icon { + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + width: $s-32; + height: $s-32; + background: var(--color-background-quaternary); + color: var(--color-foreground-secondary); + border-radius: 90px; +} + +.rule-item-text { + margin: 0; +} + +.button-row { + display: flex; + justify-content: end; + padding-block-start: $s-8; +} + +.help-text { + inline-size: 100%; +} + +.help-image img { + inline-size: 374px; +} diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 38168aeb8a..fde713a795 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -5530,6 +5530,30 @@ msgstr "[property]=[value], [property]=[value]" msgid "workspace.options.component.variant.malformed.structure.title" msgstr "Try using the following structure:" +msgid "workspace.options.component.variants-help-modal.title" +msgstr "How variants stay connected" + +msgid "workspace.options.component.variants-help-modal.intro" +msgstr "To keep changes when switching between variants, Penpot connects layers using these rules:" + +msgid "workspace.options.component.variants-help-modal.rule1" +msgstr "Same name" + +msgid "workspace.options.component.variants-help-modal.rule2" +msgstr "Same type" + +msgid "workspace.options.component.variants-help-modal.rule2.detail" +msgstr "Rectangle, ellipsis, paths and boolean operations count as same type" + +msgid "workspace.options.component.variants-help-modal.rule3" +msgstr "Same hierachy level" + +msgid "workspace.options.component.variants-help-modal.rule3.detail" +msgstr "Goups, boards and layouts are considered equivalent" + +msgid "workspace.options.component.variants-help-modal.outro" +msgstr "Changing any of these (e.g., renaming or moving a layer) breaks the connection, but reverting the change will restore it." + #: src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs:163 msgid "workspace.options.constraints" msgstr "Constraints"