mirror of
https://github.com/penpot/penpot.git
synced 2026-05-20 07:23:42 +00:00
🎉 Add typography token row to multiselected texts (#9128)
* 🐛 Fix text multiselection messages * ♻️ Add tooltip to typography tooltip * ♻️ Improve copy and add detach buttons
This commit is contained in:
parent
595ec599c6
commit
e854309049
@ -250,14 +250,14 @@ test("Multiselection of text and typographies", async ({ page }) => {
|
||||
|
||||
await expect(textSection).toBeVisible();
|
||||
await expect(
|
||||
textSection.getByText("Multiple typographies"),
|
||||
textSection.getByText("Mixed assets"),
|
||||
).not.toBeVisible();
|
||||
|
||||
// Select two plain text layer with different font family
|
||||
await plainTextLayerTwo.click({ modifiers: ["Control"] });
|
||||
await expect(textSection).toBeVisible();
|
||||
await expect(
|
||||
textSection.getByTitle("Font family").getByText("--"),
|
||||
textSection.getByTitle("Font family").getByText("Mixed Font Families"),
|
||||
).toBeVisible();
|
||||
|
||||
// Select typography text layer
|
||||
@ -268,7 +268,7 @@ test("Multiselection of text and typographies", async ({ page }) => {
|
||||
// Select two typography text layer with different typography
|
||||
await typographyTextLayerTwo.click({ modifiers: ["Control"] });
|
||||
await expect(textSection).toBeVisible();
|
||||
await expect(textSection.getByText("Multiple typographies")).toBeVisible();
|
||||
await expect(textSection.getByText("Mixed assets")).toBeVisible();
|
||||
|
||||
// Select token typography text layer
|
||||
// TODO: CHANGE WHEN TOKEN TYPOGRAPHY ROW IS READY
|
||||
@ -281,32 +281,32 @@ test("Multiselection of text and typographies", async ({ page }) => {
|
||||
await tokenTypographyTextLayerTwo.click({ modifiers: ["Control"] });
|
||||
await expect(textSection).toBeVisible();
|
||||
await expect(
|
||||
textSection.getByTitle("Font family").getByText("--"),
|
||||
textSection.getByTitle("Font family").getByText("Mixed Font Families"),
|
||||
).toBeVisible();
|
||||
|
||||
//Select plain text layer and typography text layer together
|
||||
await plainTextLayer.click();
|
||||
await typographyTextLayerOne.click({ modifiers: ["Control"] });
|
||||
await expect(textSection).toBeVisible();
|
||||
await expect(textSection.getByText("Multiple typographies")).toBeVisible();
|
||||
await expect(textSection.getByText("Mixed assets")).toBeVisible();
|
||||
|
||||
//Select plain text layer and typography text layer together on reverse order
|
||||
await typographyTextLayerOne.click();
|
||||
await plainTextLayer.click({ modifiers: ["Control"] });
|
||||
await expect(textSection).toBeVisible();
|
||||
await expect(textSection.getByText("Multiple typographies")).toBeVisible();
|
||||
await expect(textSection.getByText("Mixed assets")).toBeVisible();
|
||||
|
||||
//Selen token typography text layer and typography text layer together
|
||||
await tokenTypographyTextLayerOne.click();
|
||||
await typographyTextLayerOne.click({ modifiers: ["Control"] });
|
||||
await expect(textSection).toBeVisible();
|
||||
await expect(textSection.getByText("Multiple typographies")).toBeVisible();
|
||||
await expect(textSection.getByText("Mixed assets")).toBeVisible();
|
||||
|
||||
//Select token typography text layer and typography text layer together on reverse order
|
||||
await typographyTextLayerOne.click();
|
||||
await tokenTypographyTextLayerOne.click({ modifiers: ["Control"] });
|
||||
await expect(textSection).toBeVisible();
|
||||
await expect(textSection.getByText("Multiple typographies")).toBeVisible();
|
||||
await expect(textSection.getByText("Mixed assets")).toBeVisible();
|
||||
|
||||
// Select rectangle and elipse together
|
||||
await rectangleLayer.click();
|
||||
|
||||
@ -777,6 +777,19 @@
|
||||
(fn [shape]
|
||||
(update shape :applied-tokens remove-token))))))))
|
||||
|
||||
(defn unapply-multiple-tokens
|
||||
"Removes `attributes` for `shape-ids` without knowing the token, used when a token is deleted."
|
||||
[{:keys [attributes shape-ids] :as _props}]
|
||||
|
||||
(ptk/reify ::unapply-multiple-tokens
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of
|
||||
(dwsh/update-shapes
|
||||
shape-ids
|
||||
(fn [shape]
|
||||
(update shape :applied-tokens #(when % (apply dissoc % attributes)))))))))
|
||||
|
||||
|
||||
(defn toggle-token
|
||||
[{:keys [token attrs shape-ids expand-with-children]}]
|
||||
|
||||
@ -60,8 +60,10 @@
|
||||
id (d/nilv id internal-id)
|
||||
element-ref (mf/use-ref nil)
|
||||
tooltip-content (if (map? resolved)
|
||||
(mf/html [:> resolved-value-tooltip* {:token-name name
|
||||
:resolved-value resolved}])
|
||||
(mf/html
|
||||
[:> resolved-value-tooltip*
|
||||
{:token-name name
|
||||
:resolved-value resolved}])
|
||||
name)]
|
||||
[:li {:value id
|
||||
:class (stl/css-case :token-option true
|
||||
|
||||
@ -294,7 +294,7 @@
|
||||
sorted-tokens (sort-combined-tokens filtered-combined)]
|
||||
(if (seq combined-tokens)
|
||||
[:div {:class (stl/css :color-tokens-section)}
|
||||
[:> input* {:placeholder "Search by token name"
|
||||
[:> input* {:placeholder (tr "workspace.tokens.search-by-token")
|
||||
:icon i/search
|
||||
:max-length max-input-length
|
||||
:variant "comfortable"
|
||||
|
||||
@ -292,7 +292,7 @@
|
||||
(csu/get-token-dropdown-options typography-tokens nil))
|
||||
|
||||
selected-token-id*
|
||||
(mf/use-state #(when current-token-name
|
||||
(mf/use-state #(when (and (not= :multiple current-token-name) current-token-name)
|
||||
(:id (get-option-by-name dropdown-options current-token-name))))
|
||||
selected-token-id (deref selected-token-id*)
|
||||
|
||||
@ -411,11 +411,19 @@
|
||||
|
||||
detach-token
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token-name]
|
||||
(st/emit! (dwta/unapply-token {:token-name token-name
|
||||
:attributes #{:typography}
|
||||
:shape-ids ids}))))
|
||||
|
||||
handle-detach-all-tokens
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn []
|
||||
(st/emit! (dwta/unapply-multiple-tokens {:attributes #{:typography}
|
||||
:shape-ids ids}))))
|
||||
|
||||
expand-stream
|
||||
(mf/with-memo []
|
||||
(->> st/stream (rx/filter (ptk/type? :expand-text-more-options))))
|
||||
@ -445,7 +453,7 @@
|
||||
|
||||
(mf/with-effect [applied-token-name dropdown-options]
|
||||
(reset! selected-token-id*
|
||||
(when applied-token-name
|
||||
(when (and (not= :multiple applied-token-name) applied-token-name)
|
||||
(:id (get-option-by-name dropdown-options applied-token-name)))))
|
||||
|
||||
(mf/with-effect [token-dropdown-open?]
|
||||
@ -477,11 +485,36 @@
|
||||
(when main-menu-open?
|
||||
[:div {:class (stl/css :element-content)}
|
||||
(cond
|
||||
(and token-typography-row-enabled? (= :multiple current-token-name) (= typography-id :multiple))
|
||||
[:div {:class (stl/css :multiple-typography)}
|
||||
[:span {:class (stl/css :multiple-text)}
|
||||
(tr "workspace.libraries.text.mixed-tokens-and-assets")]]
|
||||
|
||||
(and token-typography-row-enabled? (= :multiple current-token-name))
|
||||
[:div {:class (stl/css :multiple-typography)}
|
||||
[:span {:class (stl/css :multiple-text)}
|
||||
(tr "workspace.libraries.text.mixed-tokens")]
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.libraries.text.multiple-token-tooltip")
|
||||
:tooltip-placement "top-left"
|
||||
:on-click handle-detach-all-tokens
|
||||
:icon i/detach}]]
|
||||
|
||||
(and token-typography-row-enabled? current-token-name)
|
||||
[:> token-typography-row* {:token-name current-token-name
|
||||
:detach-token detach-token
|
||||
:active-tokens (resolve-delay typography-tokens)}]
|
||||
|
||||
(= typography-id :multiple)
|
||||
[:div {:class (stl/css :multiple-typography)}
|
||||
[:span {:class (stl/css :multiple-text)}
|
||||
(tr "workspace.libraries.text.mixed-typography")]
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.libraries.text.multiple-assets-tooltip")
|
||||
:on-click handle-detach-typography
|
||||
:tooltip-placement "top-left"
|
||||
:icon i/detach}]]
|
||||
|
||||
typography
|
||||
[:& typography-entry {:file-id typography-file-id
|
||||
:typography typography
|
||||
@ -489,13 +522,7 @@
|
||||
:on-detach handle-detach-typography
|
||||
:on-change handle-change-typography}]
|
||||
|
||||
(= typography-id :multiple)
|
||||
[:div {:class (stl/css :multiple-typography)}
|
||||
[:span {:class (stl/css :multiple-text)} (tr "workspace.libraries.text.multiple-typography")]
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.libraries.text.multiple-typography-tooltip")
|
||||
:on-click handle-detach-typography
|
||||
:icon i/detach}]]
|
||||
|
||||
|
||||
:else
|
||||
[:> text-options* common-props])
|
||||
@ -521,4 +548,5 @@
|
||||
:options (resolve-delay dropdown-options)
|
||||
:selected selected-token-id
|
||||
:align "right"
|
||||
:placeholder (tr "workspace.tokens.search-by-token")
|
||||
:ref set-option-ref}])]))
|
||||
|
||||
@ -4,11 +4,18 @@
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@use "refactor/common-refactor.scss" as deprecated;
|
||||
@use "../../../sidebar/common/sidebar.scss" as sidebar;
|
||||
@use "ds/typography.scss" as t;
|
||||
@use "ds/_utils.scss" as *;
|
||||
@use "ds/_sizes.scss" as *;
|
||||
@use "ds/_borders.scss" as *;
|
||||
@use "ds/spacing.scss" as *;
|
||||
@use "ds/mixins.scss" as *;
|
||||
|
||||
.element-set {
|
||||
@include sidebar.option-grid-structure;
|
||||
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.element-title {
|
||||
@ -16,37 +23,37 @@
|
||||
}
|
||||
|
||||
.element-content {
|
||||
@include deprecated.flex-column;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-xs);
|
||||
grid-column: span 8;
|
||||
margin-top: deprecated.$s-4;
|
||||
margin-block-start: var(--sp-xs);
|
||||
}
|
||||
|
||||
.multiple-typography {
|
||||
@extend %mixed-bar;
|
||||
@include t.use-typography("body-small");
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
border-radius: $br-8;
|
||||
block-size: $sz-32;
|
||||
padding-block: var(--sp-s);
|
||||
padding-inline: var(--sp-s) 0;
|
||||
background-color: var(--color-background-tertiary);
|
||||
color: var(--color-foreground-primary);
|
||||
}
|
||||
|
||||
.multiple-text {
|
||||
@include deprecated.body-small-typography;
|
||||
@include t.use-typography("body-small");
|
||||
|
||||
flex-grow: 1;
|
||||
color: var(--input-foreground-color-active);
|
||||
}
|
||||
|
||||
.multiple-typography-button {
|
||||
@extend %button-tertiary;
|
||||
|
||||
height: deprecated.$s-32;
|
||||
width: deprecated.$s-28;
|
||||
|
||||
svg {
|
||||
@extend %button-icon;
|
||||
}
|
||||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
|
||||
.text-align-options {
|
||||
display: flex;
|
||||
gap: deprecated.$s-4;
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.align-options,
|
||||
@ -54,10 +61,10 @@
|
||||
.vertical-align-options,
|
||||
.grow-options,
|
||||
.text-decoration-options {
|
||||
height: deprecated.$s-32;
|
||||
block-size: $sz-32;
|
||||
}
|
||||
|
||||
.text-decoration-options {
|
||||
display: flex;
|
||||
gap: deprecated.$s-4;
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
@ -315,7 +315,12 @@
|
||||
:on-click #(reset! open-selector? true)}
|
||||
(cond
|
||||
(or (= :multiple font-id) (= "mixed" font-id))
|
||||
"--"
|
||||
[:*
|
||||
[:span {:class (stl/css :font-option-name :font-family-mixed)}
|
||||
(tr "inspect.attributes.typography.mixed-font-family")]
|
||||
[:> icon* {:icon-id i/arrow-down
|
||||
:class (stl/css :dropdown-icon)
|
||||
:size "s"}]]
|
||||
|
||||
(some? font)
|
||||
[:*
|
||||
|
||||
@ -51,6 +51,10 @@
|
||||
visibility: var(--actions-visibility);
|
||||
}
|
||||
|
||||
.font-family-mixed {
|
||||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
|
||||
.typography-selection-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: $sz-24 auto 1fr;
|
||||
|
||||
@ -274,7 +274,7 @@
|
||||
(merge-attrs shape-attrs)
|
||||
(merge-attrs content-attrs))
|
||||
|
||||
new-token-acc (merge-token-values token-acc content-attrs applied-tokens)]
|
||||
new-token-acc (merge-token-values token-acc editable-attrs applied-tokens)]
|
||||
[(conj ids id)
|
||||
new-values
|
||||
new-token-acc])
|
||||
|
||||
@ -2015,6 +2015,10 @@ msgstr "Typography"
|
||||
msgid "inspect.attributes.typography.font-family"
|
||||
msgstr "Font Family"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:308
|
||||
msgid "inspect.attributes.typography.mixed-font-family"
|
||||
msgstr "Mixed Font Families"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:326, src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:332
|
||||
msgid "inspect.attributes.typography.font-size"
|
||||
msgstr "Font Size"
|
||||
@ -6347,10 +6351,34 @@ msgstr "Connect library"
|
||||
msgid "workspace.libraries.text.multiple-typography"
|
||||
msgstr "Multiple typographies"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:332
|
||||
msgid "workspace.libraries.text.mixed-typography"
|
||||
msgstr "Mixed assets"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:332
|
||||
msgid "workspace.libraries.text.mixed-tokens"
|
||||
msgstr "Mixed tokens"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:332
|
||||
msgid "workspace.libraries.text.mixed-tokens-and-assets"
|
||||
msgstr "Mixed assets and tokens"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:335
|
||||
msgid "workspace.libraries.text.multiple-typography-tooltip"
|
||||
msgstr "Unlink all typographies"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:335
|
||||
msgid "workspace.libraries.text.multiple-assets-tooltip"
|
||||
msgstr "Unlink all assets"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:335
|
||||
msgid "workspace.libraries.text.multiple-token-tooltip"
|
||||
msgstr "Detach all tokens"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:335
|
||||
msgid "workspace.libraries.text.multiple-token-and-asset-tooltip"
|
||||
msgstr "Detach all tokens & unlink all typographies"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:103, src/app/main/ui/workspace/libraries.cljs:130
|
||||
msgid "workspace.libraries.typography"
|
||||
msgid_plural "workspace.libraries.typography"
|
||||
@ -8960,6 +8988,10 @@ msgstr "Duplicate Tokens Group"
|
||||
msgid "workspace.tokens.rename-group-name-hint"
|
||||
msgstr "Your tokens will automatically be renamed to %s.(suffix).(tokenName)"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs, src/app/main/ui/workspace/colorpicker/color_tokens.cljs
|
||||
msgid "workspace.tokens.search-by-token"
|
||||
msgstr "Search by token name"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar.cljs:159, src/app/main/ui/workspace/sidebar.cljs:166
|
||||
msgid "workspace.toolbar.assets"
|
||||
msgstr "Assets"
|
||||
|
||||
@ -1958,6 +1958,10 @@ msgstr "Tipografía"
|
||||
msgid "inspect.attributes.typography.font-family"
|
||||
msgstr "Familia tipográfica"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:308
|
||||
msgid "inspect.attributes.typography.mixed-font-family"
|
||||
msgstr "Varias Familias tipográficas"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:326, src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:332
|
||||
msgid "inspect.attributes.typography.font-size"
|
||||
msgstr "Tamaño de fuente"
|
||||
@ -6216,13 +6220,33 @@ msgid "workspace.libraries.shared-library-btn"
|
||||
msgstr "Conectar biblioteca"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:332
|
||||
msgid "workspace.libraries.text.multiple-typography"
|
||||
msgstr "Varias tipografías"
|
||||
msgid "workspace.libraries.text.mixed-typography"
|
||||
msgstr "Varios recursos"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:332
|
||||
msgid "workspace.libraries.text.mixed-tokens"
|
||||
msgstr "Varios tokens"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:332
|
||||
msgid "workspace.libraries.text.mixed-tokens-and-assets"
|
||||
msgstr "Varios tokens y recursos"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:335
|
||||
msgid "workspace.libraries.text.multiple-typography-tooltip"
|
||||
msgstr "Desvincular todas las tipografías"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:335
|
||||
msgid "workspace.libraries.text.multiple-assets-tooltip"
|
||||
msgstr "Desvincular todos los recursos"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:335
|
||||
msgid "workspace.libraries.text.multiple-token-tooltip"
|
||||
msgstr "Desvincular todos los tokens"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs:335
|
||||
msgid "workspace.libraries.text.multiple-token-and-asset-tooltip"
|
||||
msgstr "Desvincular todos los tokens y recursos"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:103, src/app/main/ui/workspace/libraries.cljs:130
|
||||
msgid "workspace.libraries.typography"
|
||||
msgid_plural "workspace.libraries.typography"
|
||||
@ -8674,6 +8698,10 @@ msgstr "Duplicar grupo de tokens"
|
||||
msgid "workspace.tokens.rename-group-name-hint"
|
||||
msgstr "Tus tokens serán automáticamente renombrados a %s.(sufijo).(token)"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs, src/app/main/ui/workspace/colorpicker/color_tokens.cljs
|
||||
msgid "workspace.tokens.search-by-token"
|
||||
msgstr "Buscar por el nombre del token"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar.cljs:159, src/app/main/ui/workspace/sidebar.cljs:166
|
||||
msgid "workspace.toolbar.assets"
|
||||
msgstr "Recursos"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user