Merge remote-tracking branch 'origin/staging' into develop

This commit is contained in:
alonso.torres
2025-10-21 11:19:21 +02:00
28 changed files with 631 additions and 691 deletions

View File

@@ -76,7 +76,8 @@
- Fix scroll on the inspect tab [Taiga #12293](https://tree.taiga.io/project/penpot/issue/12293) - Fix scroll on the inspect tab [Taiga #12293](https://tree.taiga.io/project/penpot/issue/12293)
- Fix lock proportion tooltip [Taiga #12326](https://tree.taiga.io/project/penpot/issue/12326) - Fix lock proportion tooltip [Taiga #12326](https://tree.taiga.io/project/penpot/issue/12326)
- Fix internal Error when selecting a set by name in the token theme editor [Taiga #12310](https://tree.taiga.io/project/penpot/issue/12310) - Fix internal Error when selecting a set by name in the token theme editor [Taiga #12310](https://tree.taiga.io/project/penpot/issue/12310)
- Fix drag & drop functionality is swapping instead or reordering [Taiga #12254](https://tree.taiga.io/project/penpot/issue/12254)
- Fix variants not syncronizing tokens on switch [Taiga #12290](https://tree.taiga.io/project/penpot/issue/12290)
## 2.10.1 ## 2.10.1
@@ -84,12 +85,10 @@
- Improve workpace file loading [Github 7366](https://github.com/penpot/penpot/pull/7366) - Improve workpace file loading [Github 7366](https://github.com/penpot/penpot/pull/7366)
### :bug: Bugs fixed ### :bug: Bugs fixed
- Fix regression with text shapes creation with Plugins API [Taiga #12244](https://tree.taiga.io/project/penpot/issue/12244) - Fix regression with text shapes creation with Plugins API [Taiga #12244](https://tree.taiga.io/project/penpot/issue/12244)
## 2.10.0 ## 2.10.0
### :rocket: Epics and highlights ### :rocket: Epics and highlights
@@ -186,7 +185,6 @@
- Add info to apply-token event [Taiga #11710](https://tree.taiga.io/project/penpot/task/11710) - Add info to apply-token event [Taiga #11710](https://tree.taiga.io/project/penpot/task/11710)
- Fix double click on set name input [Taiga #11747](https://tree.taiga.io/project/penpot/issue/11747) - Fix double click on set name input [Taiga #11747](https://tree.taiga.io/project/penpot/issue/11747)
### :bug: Bugs fixed ### :bug: Bugs fixed
- Copying font size does not copy the unit [Taiga #11143](https://tree.taiga.io/project/penpot/issue/11143) - Copying font size does not copy the unit [Taiga #11143](https://tree.taiga.io/project/penpot/issue/11143)

View File

@@ -296,7 +296,8 @@
notify (or (-> profile :props :notifications :dashboard-comments) :all) notify (or (-> profile :props :notifications :dashboard-comments) :all)
result (case notify result (case notify
:all (db/exec! cfg [sql:unread-all-comment-threads-by-team profile-id team-id]) :all (db/exec! cfg [sql:unread-all-comment-threads-by-team profile-id team-id])
:partial (db/exec! cfg [sql:unread-partial-comment-threads-by-team profile-id team-id profile-id profile-id]))] :partial (db/exec! cfg [sql:unread-partial-comment-threads-by-team profile-id team-id profile-id profile-id])
[])]
(into [] xf-decode-row result))) (into [] xf-decode-row result)))
(def ^:private (def ^:private

View File

@@ -1024,6 +1024,29 @@
:clj :clj
(sort comp-fn items)))) (sort comp-fn items))))
(defn reorder
"Reorder a vector by moving one of their items from some position to some space between positions.
It clamps the position numbers to a valid range."
[v from-pos to-space-between-pos]
(let [max-space-pos (count v)
max-prop-pos (dec max-space-pos)
from-pos (max 0 (min max-prop-pos from-pos))
to-space-between-pos (max 0 (min max-space-pos to-space-between-pos))]
(if (= from-pos to-space-between-pos)
v
(let [elem (nth v from-pos)
without-elem (-> []
(into (subvec v 0 from-pos))
(into (subvec v (inc from-pos))))
insert-pos (if (< from-pos to-space-between-pos)
(dec to-space-between-pos)
to-space-between-pos)]
(-> []
(into (subvec without-elem 0 insert-pos))
(into [elem])
(into (subvec without-elem insert-pos)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; String Functions ;; String Functions

View File

@@ -88,7 +88,7 @@
related-components (cfv/find-variant-components data objects variant-id)] related-components (cfv/find-variant-components data objects variant-id)]
(reduce (fn [changes component] (reduce (fn [changes component]
(let [props (:variant-properties component) (let [props (:variant-properties component)
props (ctv/reorder-by-moving-to-position props from-pos to-space-between-pos) props (d/reorder props from-pos to-space-between-pos)
main-id (:main-instance-id component) main-id (:main-instance-id component)
name (ctv/properties-to-name props)] name (ctv/properties-to-name props)]
(-> changes (-> changes

View File

@@ -310,27 +310,3 @@
the real name of the shape joined by the properties values separated by '/'" the real name of the shape joined by the properties values separated by '/'"
[variant] [variant]
(cpn/merge-path-item (:name variant) (str/replace (:variant-name variant) #", " " / "))) (cpn/merge-path-item (:name variant) (str/replace (:variant-name variant) #", " " / ")))
(defn reorder-by-moving-to-position
"Reorder a vector by moving one of their items from some position to some space between positions.
It clamps the position numbers to a valid range."
[props from-pos to-space-between-pos]
(let [max-space-pos (count props)
max-prop-pos (dec max-space-pos)
from-pos (max 0 (min max-prop-pos from-pos))
to-space-between-pos (max 0 (min max-space-pos to-space-between-pos))]
(if (= from-pos to-space-between-pos)
props
(let [elem (nth props from-pos)
without-elem (-> []
(into (subvec props 0 from-pos))
(into (subvec props (inc from-pos))))
insert-pos (if (< from-pos to-space-between-pos)
(dec to-space-between-pos)
to-space-between-pos)]
(-> []
(into (subvec without-elem 0 insert-pos))
(into [elem])
(into (subvec without-elem insert-pos)))))))

View File

@@ -102,3 +102,14 @@
(t/is (= (d/insert-at-index [:a :b :c :d] 1 [:a]) (t/is (= (d/insert-at-index [:a :b :c :d] 1 [:a])
[:a :b :c :d]))) [:a :b :c :d])))
(t/deftest reorder
(let [v ["a" "b" "c" "d"]]
(t/is (= (d/reorder v 0 2) ["b" "a" "c" "d"]))
(t/is (= (d/reorder v 0 3) ["b" "c" "a" "d"]))
(t/is (= (d/reorder v 0 4) ["b" "c" "d" "a"]))
(t/is (= (d/reorder v 3 0) ["d" "a" "b" "c"]))
(t/is (= (d/reorder v 3 2) ["a" "b" "d" "c"]))
(t/is (= (d/reorder v 0 5) ["b" "c" "d" "a"]))
(t/is (= (d/reorder v 3 -1) ["d" "a" "b" "c"]))
(t/is (= (d/reorder v 5 -1) ["d" "a" "b" "c"]))
(t/is (= (d/reorder v -1 5) ["b" "c" "d" "a"]))))

View File

@@ -159,48 +159,3 @@
(t/testing "update-number-in-repeated-prop-names" (t/testing "update-number-in-repeated-prop-names"
(t/is (= (ctv/update-number-in-repeated-prop-names props) numbered-props))))) (t/is (= (ctv/update-number-in-repeated-prop-names props) numbered-props)))))
(t/deftest reorder-by-moving-to-position
(let [props [{:name "border" :value "no"}
{:name "color" :value "blue"}
{:name "shadow" :value "yes"}
{:name "background" :value "none"}]]
(t/testing "reorder-by-moving-to-position"
(t/is (= (ctv/reorder-by-moving-to-position props 0 2) [{:name "color" :value "blue"}
{:name "border" :value "no"}
{:name "shadow" :value "yes"}
{:name "background" :value "none"}]))
(t/is (= (ctv/reorder-by-moving-to-position props 0 3) [{:name "color" :value "blue"}
{:name "shadow" :value "yes"}
{:name "border" :value "no"}
{:name "background" :value "none"}]))
(t/is (= (ctv/reorder-by-moving-to-position props 0 4) [{:name "color" :value "blue"}
{:name "shadow" :value "yes"}
{:name "background" :value "none"}
{:name "border" :value "no"}]))
(t/is (= (ctv/reorder-by-moving-to-position props 3 0) [{:name "background" :value "none"}
{:name "border" :value "no"}
{:name "color" :value "blue"}
{:name "shadow" :value "yes"}]))
(t/is (= (ctv/reorder-by-moving-to-position props 3 2) [{:name "border" :value "no"}
{:name "color" :value "blue"}
{:name "background" :value "none"}
{:name "shadow" :value "yes"}]))
(t/is (= (ctv/reorder-by-moving-to-position props 0 5) [{:name "color" :value "blue"}
{:name "shadow" :value "yes"}
{:name "background" :value "none"}
{:name "border" :value "no"}]))
(t/is (= (ctv/reorder-by-moving-to-position props 3 -1) [{:name "background" :value "none"}
{:name "border" :value "no"}
{:name "color" :value "blue"}
{:name "shadow" :value "yes"}]))
(t/is (= (ctv/reorder-by-moving-to-position props 5 -1) [{:name "background" :value "none"}
{:name "border" :value "no"}
{:name "color" :value "blue"}
{:name "shadow" :value "yes"}]))
(t/is (= (ctv/reorder-by-moving-to-position props -1 5) [{:name "color" :value "blue"}
{:name "shadow" :value "yes"}
{:name "background" :value "none"}
{:name "border" :value "no"}])))))

View File

@@ -154,23 +154,8 @@
(transform-fill* state ids transform-attrs options)))) (transform-fill* state ids transform-attrs options))))
(defn swap-attrs [shape attr index new-index]
(let [first (get-in shape [attr index])
second (get-in shape [attr new-index])]
(-> shape
(assoc-in [attr index] second)
(assoc-in [attr new-index] first))))
(defn- swap-fills-index
[fills index new-index]
(let [first (get fills index)
second (get fills new-index)]
(-> fills
(assoc index second)
(assoc new-index first))))
(defn reorder-fills (defn reorder-fills
[ids index new-index] [ids from-pos to-space-between-pos]
(ptk/reify ::reorder-fills (ptk/reify ::reorder-fills
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
@@ -182,7 +167,7 @@
transform-attrs transform-attrs
(fn [object] (fn [object]
(update object :fills types.fills/update swap-fills-index index new-index))] (update object :fills types.fills/update d/reorder from-pos to-space-between-pos))]
(rx/concat (rx/concat
(rx/from (map #(dwt/update-text-with-function % transform-attrs) text-ids)) (rx/from (map #(dwt/update-text-with-function % transform-attrs) text-ids))
@@ -515,22 +500,22 @@
{:attrs [:strokes]})))))) {:attrs [:strokes]}))))))
(defn reorder-shadows (defn reorder-shadows
[ids index new-index] [ids from-pos to-space-between-pos]
(ptk/reify ::reorder-shadow (ptk/reify ::reorder-shadow
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ _] (watch [_ _ _]
(rx/of (dwsh/update-shapes (rx/of (dwsh/update-shapes
ids ids
#(swap-attrs % :shadow index new-index)))))) #(update % :shadow d/reorder from-pos to-space-between-pos))))))
(defn reorder-strokes (defn reorder-strokes
[ids index new-index] [ids from-pos to-space-between-pos]
(ptk/reify ::reorder-strokes (ptk/reify ::reorder-strokes
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ _] (watch [_ _ _]
(rx/of (dwsh/update-shapes (rx/of (dwsh/update-shapes
ids ids
#(swap-attrs % :strokes index new-index) #(update % :strokes d/reorder from-pos to-space-between-pos)
{:attrs [:strokes]}))))) {:attrs [:strokes]})))))
(defn picker-for-selected-shape (defn picker-for-selected-shape

View File

@@ -7,20 +7,20 @@
(ns app.main.ui.workspace.sidebar.options.common (ns app.main.ui.workspace.sidebar.options.common
(:require-macros [app.main.style :as stl]) (:require-macros [app.main.style :as stl])
(:require (:require
[app.common.data.macros :as dm]
[app.util.dom :as dom] [app.util.dom :as dom]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc advanced-options [{:keys [visible? class children]}] (mf/defc advanced-options*
[{:keys [class is-visible children]}]
(let [ref (mf/use-ref nil)] (let [ref (mf/use-ref nil)]
(mf/use-effect (mf/use-effect
(mf/deps visible?) (mf/deps is-visible)
(fn [] (fn []
(when-let [node (mf/ref-val ref)] (when-let [node (mf/ref-val ref)]
(when visible? (when is-visible
(dom/scroll-into-view-if-needed! node))))) (dom/scroll-into-view-if-needed! node)))))
(when visible? (when is-visible
[:div {:class (dm/str class " " (stl/css :advanced-options-wrapper)) [:div {:class [class (stl/css :advanced-options-wrapper)]
:ref ref} :ref ref}
children]))) children])))

View File

@@ -4,8 +4,8 @@
// //
// Copyright (c) KALEIDOS INC // Copyright (c) KALEIDOS INC
@use "refactor/common-refactor.scss" as deprecated;
.advanced-options-wrapper { .advanced-options-wrapper {
@include deprecated.flexColumn; display: flex;
flex-direction: column;
gap: var(--sp-xs);
} }

View File

@@ -128,8 +128,8 @@
on-reorder on-reorder
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [new-index index] (fn [from-pos to-space-between-pos]
(st/emit! (dc/reorder-fills ids index new-index)))) (st/emit! (dc/reorder-fills ids from-pos to-space-between-pos))))
on-remove on-remove
(mf/use-fn (mf/use-fn
@@ -196,13 +196,13 @@
(dom/set-attribute! checkbox "indeterminate" true) (dom/set-attribute! checkbox "indeterminate" true)
(dom/remove-attribute! checkbox "indeterminate")))) (dom/remove-attribute! checkbox "indeterminate"))))
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :fill-section)}
[:div {:class (stl/css :element-title)} [:div {:class (stl/css :fill-title)}
[:> title-bar* {:collapsable has-fills? [:> title-bar* {:collapsable has-fills?
:collapsed (not open?) :collapsed (not open?)
:on-collapsed toggle-content :on-collapsed toggle-content
:title label :title label
:class (stl/css-case :title-spacing-fill (not has-fills?))} :class (stl/css-case :fill-title-bar (not has-fills?))}
(when (not (= :multiple fills)) (when (not (= :multiple fills))
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
@@ -213,11 +213,11 @@
:icon i/add}])]] :icon i/add}])]]
(when open? (when open?
[:div {:class (stl/css :element-content)} [:div {:class (stl/css :fill-content)}
(cond (cond
(= :multiple fills) (= :multiple fills)
[:div {:class (stl/css :element-set-options-group)} [:div {:class (stl/css :fill-multiple)}
[:div {:class (stl/css :group-label)} [:div {:class (stl/css :fill-multiple-label)}
(tr "settings.multiple")] (tr "settings.multiple")]
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.fill.remove-fill") :aria-label (tr "workspace.options.fill.remove-fill")
@@ -252,7 +252,7 @@
(when (or (= type :frame) (when (or (= type :frame)
(and (= type :multiple) (and (= type :multiple)
(some? hide-on-export))) (some? hide-on-export)))
[:div {:class (stl/css :checkbox)} [:div {:class (stl/css :fill-checkbox)}
[:label {:for "show-fill-on-export" [:label {:for "show-fill-on-export"
:class (stl/css-case :global/checked (not hide-on-export))} :class (stl/css-case :global/checked (not hide-on-export))}
[:span {:class (stl/css-case :check-mark true [:span {:class (stl/css-case :check-mark true

View File

@@ -4,44 +4,61 @@
// //
// Copyright (c) KALEIDOS INC // Copyright (c) KALEIDOS INC
@use "ds/_sizes.scss" as *;
@use "ds/_borders.scss" as *;
@use "ds/typography.scss" as t;
@use "refactor/common-refactor.scss" as deprecated; @use "refactor/common-refactor.scss" as deprecated;
.element-set { .fill-section {
margin: 0; display: grid;
grid-template-columns: repeat(8, var(--sp-xxxl));
column-gap: var(--sp-xs);
} }
.element-title { .fill-title {
margin: 0; grid-column: span 8;
} }
.title-spacing-fill { .fill-title-bar {
padding-left: deprecated.$s-2; padding-inline-start: var(--sp-xxs);
margin: 0;
} }
.element-content { .fill-content {
grid-column: span 8;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: deprecated.$s-12; gap: var(--sp-m);
margin: deprecated.$s-4 0 deprecated.$s-8 0; margin: var(--sp-xs) 0 var(--sp-s) 0;
} }
.element-set-options-group { .fill-multiple {
@include deprecated.flexRow; display: flex;
align-items: center;
gap: var(--sp-xs);
} }
.group-label { .fill-multiple-label {
@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: var(--sp-s);
background-color: var(--color-background-tertiary);
color: var(--color-foreground-primary);
} }
.checkbox { .fill-checkbox {
// TODO create a checkbox component in the DS
@extend .input-checkbox; @extend .input-checkbox;
padding-left: deprecated.$s-8; padding-inline-start: var(--sp-s);
span.checked { span.checked {
background-color: var(--input-border-color-active); background-color: var(--color-accent-primary);
svg { svg {
@extend .button-icon-small; @extend .button-icon-small;
stroke: var(--input-details-color); stroke: var(--color-background-primary);
} }
} }
} }

View File

@@ -19,7 +19,7 @@
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]] [app.main.ui.workspace.sidebar.options.common :refer [advanced-options*]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[okulary.core :as l] [okulary.core :as l]
@@ -190,8 +190,8 @@
:icon i/remove}]]] :icon i/remove}]]]
(when (:display grid) (when (:display grid)
[:& advanced-options {:class (stl/css :grid-advanced-options) [:> advanced-options* {:class (stl/css :grid-advanced-options)
:visible? open? :is-visible open?
:on-close toggle-advanced-options} :on-close toggle-advanced-options}
;; square ;; square
(when (= :square type) (when (= :square type)

View File

@@ -15,17 +15,12 @@
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.colors :as dc] [app.main.data.workspace.colors :as dc]
[app.main.data.workspace.shapes :as dwsh] [app.main.data.workspace.shapes :as dwsh]
[app.main.data.workspace.undo :as dwu]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.reorder-handler :refer [reorder-handler*]]
[app.main.ui.components.select :refer [select]]
[app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]] [app.main.ui.workspace.sidebar.options.rows.shadow-row :refer [shadow-row*]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@@ -49,199 +44,6 @@
(filterv (fn [[idx _]] (not= idx index))) (filterv (fn [[idx _]] (not= idx index)))
(mapv second))) (mapv second)))
(mf/defc shadow-entry*
[{:keys [index shadow is-open
on-reorder
on-toggle-open
on-detach-color
on-update
on-remove
on-toggle-visibility]}]
(let [shadow-style (:style shadow)
shadow-id (:id shadow)
hidden? (:hidden shadow)
on-drop
(mf/use-fn
(mf/deps on-reorder index)
(fn [_ data]
(on-reorder index (:index data))))
[dprops dref]
(h/use-sortable
:data-type "penpot/shadow-entry"
:on-drop on-drop
:detect-center? false
:data {:id (dm/str "shadow-" index)
:index index
:name (dm/str "Border row" index)})
on-remove
(mf/use-fn (mf/deps index) #(on-remove index))
on-update-offset-x
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :offset-x value)))
on-update-offset-y
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :offset-y value)))
on-update-spread
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :spread value)))
on-update-blur
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :blur value)))
on-update-color
(mf/use-fn
(mf/deps index on-update)
(fn [color]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :color color)))
on-detach-color
(mf/use-fn (mf/deps index) #(on-detach-color index))
on-style-change
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :style (keyword value))))
on-toggle-visibility
(mf/use-fn
(mf/deps index)
(fn []
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-toggle-visibility index)))
on-toggle-open
(mf/use-fn
(mf/deps shadow-id on-toggle-open)
#(on-toggle-open shadow-id))
type-options
(mf/with-memo []
[{:value "drop-shadow" :label (tr "workspace.options.shadow-options.drop-shadow")}
{:value "inner-shadow" :label (tr "workspace.options.shadow-options.inner-shadow")}])
on-open-row
(mf/use-fn #(st/emit! (dwu/start-undo-transaction :color-row)))
on-close-row
(mf/use-fn #(st/emit! (dwu/commit-undo-transaction :color-row)))]
[:div {:class (stl/css-case :global/shadow-option true
:shadow-element true
:dnd-over-top (= (:over dprops) :top)
:dnd-over-bot (= (:over dprops) :bot))}
(when (some? on-reorder)
[:> reorder-handler* {:ref dref}])
[:*
[:div {:class (stl/css :basic-options)}
[:div {:class (stl/css-case :shadow-info true
:hidden hidden?)}
[:> icon-button* {:on-click on-toggle-open
:variant "secondary"
:disabled hidden?
:class (stl/css-case
:disabled hidden?
:more-options true
:selected is-open)
:aria-label "open more options"
:icon i/menu}]
[:div {:class (stl/css :type-select)}
[:& select
{:class (stl/css :shadow-type-select)
:default-value (d/name shadow-style)
:options type-options
:on-change on-style-change}]]]
[:div {:class (stl/css :actions)}
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.shadow-options.toggle-shadow")
:on-click on-toggle-visibility
:icon (if hidden? "hide" "shown")}]
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.shadow-options.remove-shadow")
:on-click on-remove
:icon i/remove}]]]
(when is-open
[:& advanced-options {:class (stl/css :shadow-advanced-options)
:visible? is-open
:on-close on-toggle-open}
[:div {:class (stl/css :first-row)}
[:div {:class (stl/css :offset-x-input)
:title (tr "workspace.options.shadow-options.offsetx")}
[:span {:class (stl/css :input-label)}
"X"]
[:> numeric-input* {:class (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change on-update-offset-x
:value (:offset-x shadow)}]]
[:div {:class (stl/css :blur-input)
:title (tr "workspace.options.shadow-options.blur")}
[:span {:class (stl/css :input-label)}
(tr "workspace.options.shadow-options.blur")]
[:> numeric-input* {:class (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change on-update-blur
:min 0
:value (:blur shadow)}]]
[:div {:class (stl/css :spread-input)
:title (tr "workspace.options.shadow-options.spread")}
[:span {:class (stl/css :input-label)}
(tr "workspace.options.shadow-options.spread")]
[:> numeric-input* {:class (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change on-update-spread
:value (:spread shadow)}]]]
[:div {:class (stl/css :second-row)}
[:div {:class (stl/css :offset-y-input)
:title (tr "workspace.options.shadow-options.offsety")}
[:span {:class (stl/css :input-label)}
"Y"]
[:> numeric-input* {:class (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change on-update-offset-y
:value (:offset-y shadow)}]]
[:> color-row* {:class (stl/css :shadow-color)
:color (:color shadow)
:title (tr "workspace.options.shadow-options.color")
:disable-gradient true
:disable-image true
:origin :shadow
:on-change on-update-color
:on-detach on-detach-color
:on-open on-open-row
:on-close on-close-row}]]])]]))
(def ^:private xf:add-index (def ^:private xf:add-index
(map-indexed (fn [index shadow] (map-indexed (fn [index shadow]
(assoc shadow ::index index)))) (assoc shadow ::index index))))
@@ -279,10 +81,10 @@
handle-reorder handle-reorder
(mf/use-fn (mf/use-fn
(fn [new-index index] (fn [from-pos to-space-between-pos]
(let [ids (mf/ref-val ids-ref)] (let [ids (mf/ref-val ids-ref)]
(st/emit! (dw/trigger-bounding-box-cloaking ids)) (st/emit! (dw/trigger-bounding-box-cloaking ids))
(st/emit! (dc/reorder-shadows ids index new-index))))) (st/emit! (dc/reorder-shadows ids from-pos to-space-between-pos)))))
on-add-shadow on-add-shadow
(mf/use-fn (mf/use-fn
@@ -325,8 +127,8 @@
(-> shadow (-> shadow
(assoc attr value) (assoc attr value)
(ctss/check-shadow))))))))))] (ctss/check-shadow))))))))))]
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :shadow-section)}
[:div {:class (stl/css :element-title)} [:div {:class (stl/css :shadow-title)}
[:> title-bar* {:collapsable has-shadows? [:> title-bar* {:collapsable has-shadows?
:collapsed (not show-content?) :collapsed (not show-content?)
:on-collapsed toggle-content :on-collapsed toggle-content
@@ -334,7 +136,7 @@
:multiple (tr "workspace.options.shadow-options.title.multiple") :multiple (tr "workspace.options.shadow-options.title.multiple")
:group (tr "workspace.options.shadow-options.title.group") :group (tr "workspace.options.shadow-options.title.group")
(tr "workspace.options.shadow-options.title")) (tr "workspace.options.shadow-options.title"))
:class (stl/css-case :title-spacing-shadow (not has-shadows?))} :class (stl/css-case :shadow-title-bar (not has-shadows?))}
(when-not (= :multiple shadows) (when-not (= :multiple shadows)
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
@@ -346,20 +148,20 @@
(when show-content? (when show-content?
(cond (cond
(= :multiple shadows) (= :multiple shadows)
[:div {:class (stl/css :element-set-content)} [:div {:class (stl/css :shadow-content)}
[:div {:class (stl/css :multiple-shadows)} [:div {:class (stl/css :shadow-multiple)}
[:div {:class (stl/css :label)} (tr "settings.multiple")] [:div {:class (stl/css :shadow-multiple-label)}
[:div {:class (stl/css :actions)} (tr "settings.multiple")]
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.shadow-options.remove-shadow") :aria-label (tr "workspace.options.shadow-options.remove-shadow")
:on-click on-remove-all :on-click on-remove-all
:icon i/remove}]]]] :icon i/remove}]]]
(some? shadows) (some? shadows)
[:> h/sortable-container* {} [:> h/sortable-container* {}
[:div {:class (stl/css :element-set-content)} [:div {:class (stl/css :shadow-content)}
(for [{:keys [::index id] :as shadow} shadows] (for [{:keys [::index id] :as shadow} shadows]
[:> shadow-entry* [:> shadow-row*
{:key (dm/str index) {:key (dm/str index)
:index index :index index
:shadow shadow :shadow shadow

View File

@@ -5,34 +5,39 @@
// Copyright (c) KALEIDOS INC // Copyright (c) KALEIDOS INC
@use "ds/_sizes.scss" as *; @use "ds/_sizes.scss" as *;
@use "ds/typography.scss" as t;
@use "ds/_borders.scss" as *; @use "ds/_borders.scss" as *;
@use "ds/_utils.scss" as *; @use "ds/typography.scss" as t;
@use "refactor/common-refactor.scss" as deprecated;
.element-set { .shadow-section {
margin: 0; display: grid;
grid-template-columns: repeat(8, var(--sp-xxxl));
column-gap: var(--sp-xs);
} }
.title-spacing-shadow { .shadow-title {
margin: 0; grid-column: span 8;
}
.shadow-title-bar {
padding-inline-start: var(--sp-xxs); padding-inline-start: var(--sp-xxs);
} }
.element-set-content { .shadow-content {
margin-block-start: var(--sp-xs); grid-column: span 8;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--sp-xs); gap: var(--sp-xs);
margin-block-start: var(--sp-xs);
} }
.multiple-shadows { .shadow-multiple {
display: flex; display: flex;
align-items: center; align-items: center;
gap: var(--sp-xs); gap: var(--sp-xs);
} }
.label { .shadow-multiple-label {
@include t.use-typography("body-small"); @include t.use-typography("body-small");
display: flex; display: flex;
align-items: center; align-items: center;
@@ -43,132 +48,3 @@
background-color: var(--color-background-tertiary); background-color: var(--color-background-tertiary);
color: var(--color-foreground-primary); color: var(--color-foreground-primary);
} }
.actions {
display: grid;
grid-template-columns: subgrid;
grid-column: span 2;
}
.shadow-element {
display: flex;
flex-direction: column;
gap: var(--sp-xs);
position: relative;
&:hover {
--reorder-icon-visibility: visible;
}
&.dnd-over-top {
--reorder-top-display: block;
}
&.dnd-over-bot {
--reorder-bottom-display: block;
}
}
.basic-options {
display: grid;
grid-template-columns: repeat(8, var(--sp-xxxl));
gap: var(--sp-xs);
}
.shadow-info {
grid-column: span 6;
display: flex;
align-items: center;
gap: px2rem(1);
}
.type-select {
padding: 0;
border-radius: 0 $br-8 $br-8 0;
flex-grow: 1;
}
.shadow-type-select {
flex-grow: 1;
border-radius: 0 $br-8 $br-8 0;
}
// TODO: Remove these nested classes by using DS component
.hidden {
.type-select {
cursor: default;
pointer-events: none;
box-sizing: border-box;
color: var(--color-foreground-secondary);
stroke: var(--color-foreground-secondary);
background-color: transparent;
}
.shadow-type-select {
cursor: default;
pointer-events: none;
box-sizing: border-box;
color: var(--color-foreground-secondary);
stroke: var(--color-foreground-secondary);
background-color: transparent;
border: $b-1 solid var(--color-background-quaternary);
}
}
.shadow-advanced-options {
display: grid;
grid-template-columns: repeat(8, var(--sp-xxxl));
gap: var(--sp-xs);
}
.first-row,
.second-row {
display: grid;
grid-column: 1 / -1;
grid-template-columns: subgrid;
}
.offset-x-input,
.blur-input,
.spread-input,
.offset-y-input {
// TODO remove this input by changing the input to DS component
@extend .input-element;
@include t.use-typography("body-small");
.input-label {
padding-inline-start: var(--sp-s);
inline-size: px2rem(60);
}
}
.offset-x-input {
grid-column: span 2;
}
.offset-y-input {
grid-column: span 2;
}
.blur-input {
grid-column: span 3;
}
.spread-input {
grid-column: span 3;
}
.shadow-color {
grid-column: span 6;
}
.more-options {
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);
}

View File

@@ -18,7 +18,7 @@
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.hooks :as h] [app.main.ui.hooks :as h]
[app.main.ui.workspace.sidebar.options.rows.stroke-row :refer [stroke-row]] [app.main.ui.workspace.sidebar.options.rows.stroke-row :refer [stroke-row*]]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[cuerdas.core :as str] [cuerdas.core :as str]
@@ -89,10 +89,9 @@
handle-reorder handle-reorder
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [new-index] (fn [from-pos to-space-between-pos]
(fn [index]
(st/emit! (udw/trigger-bounding-box-cloaking ids)) (st/emit! (udw/trigger-bounding-box-cloaking ids))
(st/emit! (dc/reorder-strokes ids index new-index))))) (st/emit! (dc/reorder-strokes ids from-pos to-space-between-pos))))
on-stroke-style-change on-stroke-style-change
(mf/use-fn (mf/use-fn
@@ -177,13 +176,13 @@
:token token :token token
:shape-ids ids}))))] :shape-ids ids}))))]
[:div {:class (stl/css :element-set)} [:div {:class (stl/css :stroke-section)}
[:div {:class (stl/css :element-title)} [:div {:class (stl/css :stroke-title)}
[:> title-bar* {:collapsable has-strokes? [:> title-bar* {:collapsable has-strokes?
:collapsed (not open?) :collapsed (not open?)
:on-collapsed toggle-content :on-collapsed toggle-content
:title label :title label
:class (stl/css-case :title-spacing-stroke (not has-strokes?))} :class (stl/css-case :stroke-title-bar (not has-strokes?))}
(when (not (= :multiple strokes)) (when (not (= :multiple strokes))
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.stroke.add-stroke") :aria-label (tr "workspace.options.stroke.add-stroke")
@@ -191,12 +190,12 @@
:icon i/add :icon i/add
:data-testid "add-stroke"}])]] :data-testid "add-stroke"}])]]
(when open? (when open?
[:div {:class (stl/css-case :element-content true [:div {:class (stl/css-case :stroke-content true
:empty-content (not has-strokes?))} :stroke-content-empty (not has-strokes?))}
(cond (cond
(= :multiple strokes) (= :multiple strokes)
[:div {:class (stl/css :element-set-options-group)} [:div {:class (stl/css :stroke-multiple)}
[:div {:class (stl/css :group-label)} [:div {:class (stl/css :stroke-multiple-label)}
(tr "settings.multiple")] (tr "settings.multiple")]
[:> icon-button* {:variant "ghost" [:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.stroke.remove-stroke") :aria-label (tr "workspace.options.stroke.remove-stroke")
@@ -205,7 +204,7 @@
(seq strokes) (seq strokes)
[:> h/sortable-container* {} [:> h/sortable-container* {}
(for [[index value] (d/enumerate (:strokes values []))] (for [[index value] (d/enumerate (:strokes values []))]
[:& stroke-row {:key (dm/str "stroke-" index) [:& stroke-row* {:key (dm/str "stroke-" index)
:stroke value :stroke value
:title (tr "workspace.options.stroke-color") :title (tr "workspace.options.stroke-color")
:index index :index index

View File

@@ -4,35 +4,51 @@
// //
// Copyright (c) KALEIDOS INC // Copyright (c) KALEIDOS INC
@use "refactor/common-refactor.scss" as deprecated; @use "ds/_sizes.scss" as *;
@use "ds/_borders.scss" as *;
@use "ds/typography.scss" as t;
.element-set { .stroke-section {
margin: 0; display: grid;
grid-template-columns: repeat(8, var(--sp-xxxl));
column-gap: var(--sp-xs);
} }
.element-title { .stroke-title {
margin: 0; grid-column: span 8;
} }
.title-spacing-stroke { .stroke-title-bar {
padding-left: deprecated.$s-2; padding-inline-start: var(--sp-xxs);
margin: 0;
} }
.element-content { .stroke-content {
grid-column: span 8;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: deprecated.$s-12; gap: var(--sp-m);
margin: deprecated.$s-4 0 deprecated.$s-8 0; margin: var(--sp-xs) 0 var(--sp-s) 0;
&.empty-content {
&.stroke-content-empty {
margin: 0; margin: 0;
} }
} }
.element-set-options-group { .stroke-multiple {
@include deprecated.flexRow; display: flex;
align-items: center;
gap: var(--sp-xs);
} }
.group-label { .stroke-multiple-label {
@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: var(--sp-s);
background-color: var(--color-background-tertiary);
color: var(--color-foreground-primary);
} }

View File

@@ -319,8 +319,10 @@
on-drop on-drop
(mf/use-fn (mf/use-fn
(mf/deps on-reorder index) (mf/deps on-reorder index)
(fn [_ data] (fn [relative-pos data]
(on-reorder index (:index data)))) (let [from-pos (:index data)
to-space-between-pos (if (= relative-pos :bot) (inc index) index)]
(on-reorder from-pos to-space-between-pos))))
[dprops dref] [dprops dref]
(if (some? on-reorder) (if (some? on-reorder)
@@ -329,9 +331,7 @@
:on-drop on-drop :on-drop on-drop
:disabled disable-drag :disabled disable-drag
:detect-center? false :detect-center? false
:data {:id (str "color-row-" index) :data {:index index})
:index index
:name (str "Color row" index)})
[nil nil]) [nil nil])
row-class row-class

View File

@@ -0,0 +1,210 @@
;; 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.rows.shadow-row
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.main.data.workspace :as dw]
[app.main.data.workspace.undo :as dwu]
[app.main.store :as st]
[app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.reorder-handler :refer [reorder-handler*]]
[app.main.ui.components.select :refer [select]]
[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.workspace.sidebar.options.common :refer [advanced-options*]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
(mf/defc shadow-row*
[{:keys [index shadow is-open
on-reorder
on-toggle-open
on-detach-color
on-update
on-remove
on-toggle-visibility]}]
(let [shadow-style (:style shadow)
shadow-id (:id shadow)
hidden? (:hidden shadow)
on-drop
(mf/use-fn
(mf/deps on-reorder index)
(fn [relative-pos data]
(let [from-pos (:index data)
to-space-between-pos (if (= relative-pos :bot) (inc index) index)]
(on-reorder from-pos to-space-between-pos))))
[dprops dref]
(h/use-sortable
:data-type "penpot/shadow-entry"
:on-drop on-drop
:detect-center? false
:data {:index index})
on-remove
(mf/use-fn (mf/deps index) #(on-remove index))
on-update-offset-x
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :offset-x value)))
on-update-offset-y
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :offset-y value)))
on-update-spread
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :spread value)))
on-update-blur
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :blur value)))
on-update-color
(mf/use-fn
(mf/deps index on-update)
(fn [color]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :color color)))
on-detach-color
(mf/use-fn (mf/deps index) #(on-detach-color index))
on-style-change
(mf/use-fn
(mf/deps index)
(fn [value]
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-update index :style (keyword value))))
on-toggle-visibility
(mf/use-fn
(mf/deps index)
(fn []
(st/emit! (dw/trigger-bounding-box-cloaking [shadow-id]))
(on-toggle-visibility index)))
on-toggle-open
(mf/use-fn
(mf/deps shadow-id on-toggle-open)
#(on-toggle-open shadow-id))
type-options
(mf/with-memo []
[{:value "drop-shadow" :label (tr "workspace.options.shadow-options.drop-shadow")}
{:value "inner-shadow" :label (tr "workspace.options.shadow-options.inner-shadow")}])
on-open-row
(mf/use-fn #(st/emit! (dwu/start-undo-transaction :color-row)))
on-close-row
(mf/use-fn #(st/emit! (dwu/commit-undo-transaction :color-row)))]
[:div {:class (stl/css-case :global/shadow-option true
:shadow-element true
:dnd-over-top (= (:over dprops) :top)
:dnd-over-bot (= (:over dprops) :bot))}
(when (some? on-reorder)
[:> reorder-handler* {:ref dref}])
[:*
[:div {:class (stl/css :shadow-basic)}
[:div {:class (stl/css :shadow-basic-info)}
[:> icon-button* {:variant "secondary"
:icon i/menu
:class (stl/css-case :shadow-basic-button true
:selected is-open)
:aria-label "open more options"
:disabled hidden?
:on-click on-toggle-open}]
[:& select {:class (stl/css :shadow-basic-select)
:default-value (d/name shadow-style)
:options type-options
:disabled hidden?
:on-change on-style-change}]]
[:div {:class (stl/css :shadow-basic-actions)}
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.shadow-options.toggle-shadow")
:on-click on-toggle-visibility
:icon (if hidden? "hide" "shown")}]
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.shadow-options.remove-shadow")
:on-click on-remove
:icon i/remove}]]]
(when is-open
[:> advanced-options* {:class (stl/css :shadow-advanced)
:is-visible is-open
:on-close on-toggle-open}
[:div {:class (stl/css :shadow-advanced-row)}
[:div {:class (stl/css :shadow-advanced-offset-x)
:title (tr "workspace.options.shadow-options.offsetx")}
[:span {:class (stl/css :shadow-advanced-label)}
"X"]
[:> numeric-input* {:no-validate true
:placeholder "--"
:on-change on-update-offset-x
:value (:offset-x shadow)}]]
[:div {:class (stl/css :shadow-advanced-blur)
:title (tr "workspace.options.shadow-options.blur")}
[:span {:class (stl/css :shadow-advanced-label)}
(tr "workspace.options.shadow-options.blur")]
[:> numeric-input* {:no-validate true
:placeholder "--"
:on-change on-update-blur
:min 0
:value (:blur shadow)}]]
[:div {:class (stl/css :shadow-advanced-spread)
:title (tr "workspace.options.shadow-options.spread")}
[:span {:class (stl/css :shadow-advanced-label)}
(tr "workspace.options.shadow-options.spread")]
[:> numeric-input* {:no-validate true
:placeholder "--"
:on-change on-update-spread
:value (:spread shadow)}]]]
[:div {:class (stl/css :shadow-advanced-row)}
[:div {:class (stl/css :shadow-advanced-offset-y)
:title (tr "workspace.options.shadow-options.offsety")}
[:span {:class (stl/css :shadow-advanced-label)}
"Y"]
[:> numeric-input* {:no-validate true
:placeholder "--"
:on-change on-update-offset-y
:value (:offset-y shadow)}]]
[:> color-row* {:class (stl/css :shadow-advanced-color)
:color (:color shadow)
:title (tr "workspace.options.shadow-options.color")
:disable-gradient true
:disable-image true
:origin :shadow
:on-change on-update-color
:on-detach on-detach-color
:on-open on-open-row
:on-close on-close-row}]]])]]))

View File

@@ -0,0 +1,112 @@
// 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/typography.scss" as t;
@use "ds/_borders.scss" as *;
@use "ds/_utils.scss" as *;
@use "refactor/common-refactor.scss" as deprecated;
.shadow-element {
display: flex;
flex-direction: column;
gap: var(--sp-xs);
position: relative;
&:hover {
--reorder-icon-visibility: visible;
}
&.dnd-over-top {
--reorder-top-display: block;
}
&.dnd-over-bot {
--reorder-bottom-display: block;
}
}
.shadow-basic {
display: grid;
grid-template-columns: repeat(8, var(--sp-xxxl));
gap: var(--sp-xs);
}
.shadow-basic-info {
grid-column: span 6;
display: flex;
align-items: center;
gap: px2rem(1);
}
.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);
}
}
.shadow-basic-select {
flex-grow: 1;
border-radius: 0 $br-8 $br-8 0;
}
.shadow-basic-actions {
display: grid;
grid-template-columns: subgrid;
grid-column: span 2;
}
.shadow-advanced {
display: grid;
grid-template-columns: repeat(8, var(--sp-xxxl));
gap: var(--sp-xs);
}
.shadow-advanced-row {
display: grid;
grid-column: 1 / -1;
grid-template-columns: subgrid;
}
.shadow-advanced-offset-x,
.shadow-advanced-blur,
.shadow-advanced-spread,
.shadow-advanced-offset-y {
// TODO remove this input by changing the input to DS component
@extend .input-element;
@include t.use-typography("body-small");
.shadow-advanced-label {
padding-inline-start: var(--sp-s);
inline-size: px2rem(60);
}
}
.shadow-advanced-offset-x {
grid-column: span 2;
}
.shadow-advanced-blur {
grid-column: span 3;
}
.shadow-advanced-spread {
grid-column: span 3;
}
.shadow-advanced-offset-y {
grid-column: span 2;
}
.shadow-advanced-color {
grid-column: span 6;
}

View File

@@ -14,14 +14,14 @@
[app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.reorder-handler :refer [reorder-handler*]] [app.main.ui.components.reorder-handler :refer [reorder-handler*]]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.select :refer [select]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
[app.main.ui.hooks :as h] [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.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc stroke-row (mf/defc stroke-row*
{::mf/wrap-props false}
[{:keys [index [{:keys [index
stroke stroke
title title
@@ -46,18 +46,21 @@
ids]}] ids]}]
(let [on-drop (let [on-drop
(fn [_ data] (mf/use-fn
(on-reorder (:index data))) (mf/deps on-reorder index)
(fn [relative-pos data]
(let [from-pos (:index data)
to-space-between-pos (if (= relative-pos :bot) (inc index) index)]
(on-reorder from-pos to-space-between-pos))))
[dprops dref] (if (some? on-reorder) [dprops dref]
(if (some? on-reorder)
(h/use-sortable (h/use-sortable
:data-type "penpot/stroke-row" :data-type "penpot/stroke-row"
:on-drop on-drop :on-drop on-drop
:disabled @disable-drag :disabled @disable-drag
:detect-center? false :detect-center? false
:data {:id (str "stroke-row-" index) :data {:index index})
:index index
:name (str "Border row" index)})
[nil nil]) [nil nil])
stroke-color-token (:stroke-color applied-tokens) stroke-color-token (:stroke-color applied-tokens)
@@ -191,52 +194,41 @@
;; Stroke Width, Alignment & Style ;; Stroke Width, Alignment & Style
[:div {:class (stl/css :stroke-options)} [:div {:class (stl/css :stroke-options)}
[:div {:class (stl/css :stroke-width-input-element) [:div {:class (stl/css :stroke-width-input)
:title (tr "workspace.options.stroke-width")} :title (tr "workspace.options.stroke-width")}
[:span {:class (stl/css :icon)} [:> icon* {:icon-id i/stroke-size
deprecated-icon/stroke-size] :size "s"}]
[:> numeric-input* [:> numeric-input* {:value stroke-width
{:min 0 :min 0
:className (stl/css :stroke-width-input)
:value stroke-width
:placeholder (tr "settings.multiple") :placeholder (tr "settings.multiple")
:on-change on-width-change :on-change on-width-change
:on-focus on-focus :on-focus on-focus
:select-on-focus select-on-focus :select-on-focus select-on-focus
:on-blur on-blur}]] :on-blur on-blur}]]
[:div {:class (stl/css :select-wrapper :stroke-alignment-select) [:div {:class (stl/css :stroke-alignment-select)
:data-testid "stroke.alignment"} :data-testid "stroke.alignment"}
[:& select [:& select {:default-value stroke-alignment
{:default-value stroke-alignment
:options stroke-alignment-options :options stroke-alignment-options
:on-change on-alignment-change}]] :on-change on-alignment-change}]]
(when-not disable-stroke-style (when-not disable-stroke-style
[:div {:class (stl/css :select-wrapper :stroke-style-select) [:div {:class (stl/css :stroke-style-select)
:data-testid "stroke.style"} :data-testid "stroke.style"}
[:& select [:& select {:default-value stroke-style
{:default-value stroke-style
:options stroke-style-options :options stroke-style-options
:on-change on-style-change}]])] :on-change on-style-change}]])]
;; Stroke Caps ;; Stroke Caps
(when show-caps (when show-caps
[:div {:class (stl/css :stroke-caps-options)} [:div {:class (stl/css :stroke-caps-options)}
[:div {:class (stl/css :cap-select)} [:& select {:default-value (:stroke-cap-start stroke)
[:& select
{:default-value (:stroke-cap-start stroke)
:dropdown-class (stl/css :stroke-cap-dropdown-start)
:options stroke-caps-options :options stroke-caps-options
:on-change on-caps-start-change}]] :on-change on-caps-start-change}]
[:> icon-button* {:variant "secondary"
[:button {:class (stl/css :swap-caps-btn) :aria-label (tr "labels.switch")
:on-click on-cap-switch} :on-click on-cap-switch
deprecated-icon/switch] :icon i/switch}]
[:& select {:default-value (:stroke-cap-end stroke)
[:div {:class (stl/css :cap-select)}
[:& select
{:default-value (:stroke-cap-end stroke)
:dropdown-class (stl/css :stroke-cap-dropdown)
:options stroke-caps-options :options stroke-caps-options
:on-change on-caps-end-change}]]])])) :on-change on-caps-end-change}]])]))

View File

@@ -4,10 +4,13 @@
// //
// Copyright (c) KALEIDOS INC // Copyright (c) KALEIDOS INC
@use "ds/typography.scss" as t;
@use "refactor/common-refactor.scss" as deprecated; @use "refactor/common-refactor.scss" as deprecated;
.stroke-data { .stroke-data {
@include deprecated.flexColumn; display: flex;
flex-direction: column;
gap: var(--sp-xs);
position: relative; position: relative;
@@ -31,64 +34,28 @@
align-items: center; align-items: center;
grid-template-columns: repeat(8, var(--sp-xxxl)); grid-template-columns: repeat(8, var(--sp-xxxl));
gap: var(--sp-xs); gap: var(--sp-xs);
}
.stroke-width-input-element { .stroke-width-input {
@extend .input-element;
@include deprecated.bodySmallTypography;
grid-column: span 2; grid-column: span 2;
}
.stroke-alignment-select { // TODO replace with numeric-input* from DS
grid-column: span 3; @extend .input-element;
}
.stroke-style-select { @include t.use-typography("body-small");
grid-column: span 3; padding-inline-start: var(--sp-xs);
}
} }
.stroke-alignment-select {
grid-column: span 3;
}
.stroke-style-select {
grid-column: span 3;
}
.stroke-caps-options { .stroke-caps-options {
/*
This element do not match the 8 column grid of sidebar
|___|-|___|-|___|-|___|-|___|-|___|-|___|-|___| -> 8 column grid, (--sp-xxxl) width each
|__________________|-|__________________|-|___| -> 2 inputs blocks + 1 button.
We need to calculate the total width of each input block:
- 3.5 columns of the the base grid (--sp-xxxl)
- plus 3 inter-column gaps (3 * --sp-xs)
- minus half a gap (--sp-xs / 2) because the last spacing is shared
with the next block, keeping the overall visual rhythm consistent.
*/
--input-width: calc(var(--sp-xxxl) * 3.5 + 3 * var(--sp-xs) - (var(--sp-xs) / 2));
display: grid; display: grid;
grid-template-columns: grid-template-columns: 1fr auto 1fr;
var(--input-width) /* first input block */ column-gap: var(--sp-xs);
var(--input-width) /* second input block */
var(--sp-xxxl); /* action button */
gap: var(--sp-xs);
}
.stroke-cap-dropdown,
.stroke-cap-dropdown-start {
min-width: deprecated.$s-124;
width: fit-content;
max-width: deprecated.$s-252;
right: 0;
left: unset;
}
.stroke-cap-dropdown-start {
left: 0;
right: unset;
}
.swap-caps-btn {
@extend .button-secondary;
height: var(--sp-xxxl);
width: var(--sp-xxxl);
svg {
@extend .button-icon;
}
} }

View File

@@ -2660,6 +2660,10 @@ msgstr "Styles"
msgid "labels.svg" msgid "labels.svg"
msgstr "SVG" msgstr "SVG"
#: src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs:250
msgid "labels.switch"
msgstr "Switch"
#: src/app/main/ui/onboarding/questions.cljs:256 #: src/app/main/ui/onboarding/questions.cljs:256
#, unused #, unused
msgid "labels.team-leader" msgid "labels.team-leader"
@@ -7577,7 +7581,7 @@ msgstr ""
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039
msgid "workspace.tokens.font-weight-value-enter" msgid "workspace.tokens.font-weight-value-enter"
msgstr "Enter a value (300, Bold, Regular Italic...) or an {alias}" msgstr "Font weight (300, Bold Italic...) or an {alias}"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:228 #: src/app/main/ui/workspace/tokens/management/context_menu.cljs:228
msgid "workspace.tokens.gaps" msgid "workspace.tokens.gaps"
@@ -7713,11 +7717,11 @@ msgstr "Add a theme (i.e. Light)"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1047 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1047
msgid "workspace.tokens.letter-spacing-value-enter-composite" msgid "workspace.tokens.letter-spacing-value-enter-composite"
msgstr "Add letter spacing or {alias}" msgstr "Letter spacing or {alias}"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1043 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1043
msgid "workspace.tokens.line-height-value-enter" msgid "workspace.tokens.line-height-value-enter"
msgstr "Enter line height multiplier, px, %, or {alias}" msgstr "Line height (multiplier, px, %) or {alias}"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:220 #: src/app/main/ui/workspace/tokens/management/context_menu.cljs:220
msgid "workspace.tokens.margins" msgid "workspace.tokens.margins"
@@ -7865,11 +7869,11 @@ msgstr "Stroke width must be greater than or equal to 0."
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1012, src/app/main/ui/workspace/tokens/management/create/form.cljs:1051 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1012, src/app/main/ui/workspace/tokens/management/create/form.cljs:1051
msgid "workspace.tokens.text-case-value-enter" msgid "workspace.tokens.text-case-value-enter"
msgstr "Enter: none | uppercase | lowercase | capitalize or {alias}" msgstr "none | uppercase | lowercase | capitalize or {alias}"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055
msgid "workspace.tokens.text-decoration-value-enter" msgid "workspace.tokens.text-decoration-value-enter"
msgstr "Enter text decoration: none | underline | strike-through" msgstr "none | underline | strike-through or {alias}"
#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130 #: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130
msgid "workspace.tokens.theme-name" msgid "workspace.tokens.theme-name"

View File

@@ -2630,6 +2630,10 @@ msgstr "Estilos"
msgid "labels.svg" msgid "labels.svg"
msgstr "SVG" msgstr "SVG"
#: src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs:250
msgid "labels.switch"
msgstr "Intercambiar"
#: src/app/main/ui/onboarding/questions.cljs:256 #: src/app/main/ui/onboarding/questions.cljs:256
#, unused #, unused
msgid "labels.team-leader" msgid "labels.team-leader"
@@ -7514,7 +7518,7 @@ msgstr ""
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039
msgid "workspace.tokens.font-weight-value-enter" msgid "workspace.tokens.font-weight-value-enter"
msgstr "Introduce un valor (300, Bold, Regular Italic...) o un {alias}" msgstr "Font weight (300, Bold, Regular Italic...) o un {alias}"
#: src/app/main/ui/workspace/tokens/style_dictionary.cljs #: src/app/main/ui/workspace/tokens/style_dictionary.cljs
#, unused #, unused
@@ -7625,11 +7629,11 @@ msgstr "Añade un Tema (p. ej. Claro)"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1047 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1047
msgid "workspace.tokens.letter-spacing-value-enter-composite" msgid "workspace.tokens.letter-spacing-value-enter-composite"
msgstr "Introduce letter spacing o {alias}" msgstr "Letter spacing o {alias}"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1043 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1043
msgid "workspace.tokens.line-height-value-enter" msgid "workspace.tokens.line-height-value-enter"
msgstr "Introduce line height multiplicador, px o % o {alias}" msgstr "Line height (multiplicador, px o %) o {alias}"
#: src/app/main/data/workspace/tokens/errors.cljs:57 #: src/app/main/data/workspace/tokens/errors.cljs:57
msgid "workspace.tokens.missing-references" msgid "workspace.tokens.missing-references"
@@ -7743,11 +7747,11 @@ msgstr "Stroke width debe ser mayor o igual a 0."
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1012, src/app/main/ui/workspace/tokens/management/create/form.cljs:1051 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1012, src/app/main/ui/workspace/tokens/management/create/form.cljs:1051
msgid "workspace.tokens.text-case-value-enter" msgid "workspace.tokens.text-case-value-enter"
msgstr "Introduce: none | uppercase | lowercase | capitalize o {alias}" msgstr "none | uppercase | lowercase | capitalize o {alias}"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055
msgid "workspace.tokens.text-decoration-value-enter" msgid "workspace.tokens.text-decoration-value-enter"
msgstr "Introduce text decoration: none | underline | strike-through" msgstr "none | underline | strike-through o {alias}"
#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130 #: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130
msgid "workspace.tokens.theme-name" msgid "workspace.tokens.theme-name"

View File

@@ -7230,7 +7230,7 @@ msgstr "Fichier unique"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039
msgid "workspace.tokens.font-weight-value-enter" msgid "workspace.tokens.font-weight-value-enter"
msgstr "Entrer : 400, Bold, 700 Italic ou {alias}" msgstr "Font weight (300, Bold, Regular, Italic...) ou {alias}"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:228 #: src/app/main/ui/workspace/tokens/management/context_menu.cljs:228
msgid "workspace.tokens.gaps" msgid "workspace.tokens.gaps"
@@ -7507,7 +7507,7 @@ msgstr "La largueur du tracé doit être plus grand ou égal à 0."
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055
msgid "workspace.tokens.text-decoration-value-enter" msgid "workspace.tokens.text-decoration-value-enter"
msgstr "Entrez la décoration de texte : Aucune | Souligné | Barré" msgstr "none | underline | strike-through ou {alias}"
#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130 #: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130
msgid "workspace.tokens.theme-name" msgid "workspace.tokens.theme-name"

View File

@@ -7589,10 +7589,6 @@ msgstr "ערכת עיצוב"
msgid "workspace.tokens.label.theme-placeholder" msgid "workspace.tokens.label.theme-placeholder"
msgstr "הוספת ערכת עיצוב (למשל: בהירה)" msgstr "הוספת ערכת עיצוב (למשל: בהירה)"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1047
msgid "workspace.tokens.letter-spacing-value-enter-composite"
msgstr "הוספת ריווח תווים או {alias}"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:220 #: src/app/main/ui/workspace/tokens/management/context_menu.cljs:220
msgid "workspace.tokens.margins" msgid "workspace.tokens.margins"
msgstr "שוליים" msgstr "שוליים"
@@ -7737,10 +7733,6 @@ msgstr "גודל"
msgid "workspace.tokens.stroke-width-range" msgid "workspace.tokens.stroke-width-range"
msgstr "עובי הקו חייב להיות גדול או שווה ל־0." msgstr "עובי הקו חייב להיות גדול או שווה ל־0."
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055
msgid "workspace.tokens.text-decoration-value-enter"
msgstr "נא למלא עיצוב טקסט: none | underline | strike-through"
#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130 #: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130
msgid "workspace.tokens.theme-name" msgid "workspace.tokens.theme-name"
msgstr "ערכת עיצוב %s" msgstr "ערכת עיצוב %s"

View File

@@ -7578,7 +7578,7 @@ msgstr ""
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039
msgid "workspace.tokens.font-weight-value-enter" msgid "workspace.tokens.font-weight-value-enter"
msgstr "Inserisci: 400, Bold, 700 Italico, o {alias}" msgstr "Font weight (300, Bold, Regular Italic...) o {alias}"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:228 #: src/app/main/ui/workspace/tokens/management/context_menu.cljs:228
msgid "workspace.tokens.gaps" msgid "workspace.tokens.gaps"
@@ -7723,11 +7723,11 @@ msgstr "Aggiungi un tema (es. Chiaro)"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1047 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1047
msgid "workspace.tokens.letter-spacing-value-enter-composite" msgid "workspace.tokens.letter-spacing-value-enter-composite"
msgstr "Aggiungi spaziatura tra lettere o {alias" msgstr "Letter spacing o {alias}"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1043 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1043
msgid "workspace.tokens.line-height-value-enter" msgid "workspace.tokens.line-height-value-enter"
msgstr "Inserisci interlinea — moltiplicatore, px, %, o {alias}" msgstr "Line height (moltiplicatore, px, %) o {alias}"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:220 #: src/app/main/ui/workspace/tokens/management/context_menu.cljs:220
msgid "workspace.tokens.margins" msgid "workspace.tokens.margins"
@@ -7879,11 +7879,11 @@ msgstr "La larghezza della traccia deve essere maggiore o uguale a 0."
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1012, src/app/main/ui/workspace/tokens/management/create/form.cljs:1051 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1012, src/app/main/ui/workspace/tokens/management/create/form.cljs:1051
msgid "workspace.tokens.text-case-value-enter" msgid "workspace.tokens.text-case-value-enter"
msgstr "Inserisci: none | uppercase | lowercase | capitalize or {alias}" msgstr "none | uppercase | lowercase | capitalize o {alias}"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055
msgid "workspace.tokens.text-decoration-value-enter" msgid "workspace.tokens.text-decoration-value-enter"
msgstr "Inserisci decorazione del testo: none | underline | strike-through" msgstr "none | underline | strike-through o {alias}"
#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130 #: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130
msgid "workspace.tokens.theme-name" msgid "workspace.tokens.theme-name"

View File

@@ -7588,7 +7588,7 @@ msgstr ""
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1024, src/app/main/ui/workspace/tokens/management/create/form.cljs:1039
msgid "workspace.tokens.font-weight-value-enter" msgid "workspace.tokens.font-weight-value-enter"
msgstr "Voer een waarde in (300, vet, normaal cursief...) of een {alias}" msgstr "Font weight (300, Bold Italic...) of een {alias}"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:228 #: src/app/main/ui/workspace/tokens/management/context_menu.cljs:228
msgid "workspace.tokens.gaps" msgid "workspace.tokens.gaps"
@@ -7733,11 +7733,11 @@ msgstr "Een thema toevoegen (bijv. Licht)"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1047 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1047
msgid "workspace.tokens.letter-spacing-value-enter-composite" msgid "workspace.tokens.letter-spacing-value-enter-composite"
msgstr "Letterafstand of {alias} toevoegen" msgstr "Letter spacing of {alias}"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1043 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1043
msgid "workspace.tokens.line-height-value-enter" msgid "workspace.tokens.line-height-value-enter"
msgstr "Voer de regelafstand in — vermenigvuldigingsfactor, px, % of {alias}" msgstr "Line height (vermenigvuldigingsfactor, px, %) of {alias}"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:220 #: src/app/main/ui/workspace/tokens/management/context_menu.cljs:220
msgid "workspace.tokens.margins" msgid "workspace.tokens.margins"
@@ -7889,11 +7889,11 @@ msgstr "De dikte van de streek moet groter zijn dan of gelijk zijn aan 0."
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1012, src/app/main/ui/workspace/tokens/management/create/form.cljs:1051 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1012, src/app/main/ui/workspace/tokens/management/create/form.cljs:1051
msgid "workspace.tokens.text-case-value-enter" msgid "workspace.tokens.text-case-value-enter"
msgstr "Voer in: none | uppercase | lowercase | capitalize of {alias}" msgstr "none | uppercase | lowercase | capitalize of {alias}"
#: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055 #: src/app/main/ui/workspace/tokens/management/create/form.cljs:1018, src/app/main/ui/workspace/tokens/management/create/form.cljs:1055
msgid "workspace.tokens.text-decoration-value-enter" msgid "workspace.tokens.text-decoration-value-enter"
msgstr "Voer tekstdecoratie in: none | underline | strike-through" msgstr "none | underline | strike-through of {alias}"
#: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130 #: src/app/main/ui/workspace/tokens/themes/create_modal.cljs:130
msgid "workspace.tokens.theme-name" msgid "workspace.tokens.theme-name"