♻️ Refactor small numeric inputs (#8660)
* ♻️ Refactor individual border radius inputs * ♻️ Refactor layer opacity input * ♻️ Refactor stroke width inputs and add icon only selects * ♻️ Fix comments on PR
@@ -72,7 +72,7 @@ test.describe("Tokens: Apply token", () => {
|
||||
|
||||
// Check if border radius sections is visible on right sidebar
|
||||
const borderRadiusSection = page.getByRole("region", {
|
||||
name: "border-radius-section",
|
||||
name: "Border radius section",
|
||||
});
|
||||
await expect(borderRadiusSection).toBeVisible();
|
||||
|
||||
@@ -135,7 +135,7 @@ test.describe("Tokens: Apply token", () => {
|
||||
|
||||
// Check if opacity sections is visible on right sidebar
|
||||
const layerMenuSection = page.getByRole("region", {
|
||||
name: "layer-menu-section",
|
||||
name: "Layer menu section",
|
||||
});
|
||||
await expect(layerMenuSection).toBeVisible();
|
||||
|
||||
@@ -688,7 +688,7 @@ test.describe("Tokens: Apply token", () => {
|
||||
|
||||
// Check if border radius sections is visible on right sidebar
|
||||
const borderRadiusSection = page.getByRole("region", {
|
||||
name: "border-radius-section",
|
||||
name: "Border radius section",
|
||||
});
|
||||
await expect(borderRadiusSection).toBeVisible();
|
||||
|
||||
@@ -897,7 +897,7 @@ test.describe("Tokens: Detach token", () => {
|
||||
|
||||
// Check if border radius sections is visible on right sidebar
|
||||
const borderRadiusSection = page.getByRole("region", {
|
||||
name: "border-radius-section",
|
||||
name: "Border radius section",
|
||||
});
|
||||
await expect(borderRadiusSection).toBeVisible();
|
||||
|
||||
|
||||
5
frontend/resources/images/icons/stroke-center.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path fill="#8f9da3" fill-opacity="0.2" stroke="none" fill-rule="evenodd" d="M0 0h16v16H0z M6 6h4v4H6z"/>
|
||||
<rect x="3.5" y="3.5" width="9" height="9"/>
|
||||
<path d="M3 3h.01M13 3h.01M3 13h.01M13 13h.01" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 371 B |
3
frontend/resources/images/icons/stroke-dashed.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 8h4M10 8h4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 176 B |
3
frontend/resources/images/icons/stroke-dotted.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 8h.01M8 8h.01M13 8h.01"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 205 B |
5
frontend/resources/images/icons/stroke-inside.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path fill="#8f9da3" fill-opacity="0.2" stroke="none" fill-rule="evenodd" d="M0 0h16v16H0z M6 6h4v4H6z"/>
|
||||
<rect x="5.5" y="5.5" width="5" height="5"/>
|
||||
<path d="M5 5h.01M11 5h.01M5 11h.01M11 11h.01" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 371 B |
4
frontend/resources/images/icons/stroke-mixed.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 8h5"/>
|
||||
<path d="M13 8h.01" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 210 B |
5
frontend/resources/images/icons/stroke-outside.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path fill="#8f9da3" fill-opacity="0.2" stroke="none" fill-rule="evenodd" d="M0 0h16v16H0z M6 6h4v4H6z"/>
|
||||
<rect x="1.5" y="1.5" width="13" height="13"/>
|
||||
<path d="M1 1h.01M15 1h.01M1 15h.01M15 15h.01" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 373 B |
3
frontend/resources/images/icons/stroke-solid.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 8h10"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 171 B |
@@ -822,9 +822,50 @@
|
||||
:shape-ids shape-ids
|
||||
:on-update-shape on-update-shape}))))))))
|
||||
|
||||
(defn apply-token-on-selected
|
||||
(defn apply-token-from-input
|
||||
[{:keys [token attrs shape-ids expand-with-children]}]
|
||||
(ptk/reify ::apply-token-from-input
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (dsh/lookup-page-objects state)
|
||||
shapes (into [] (keep (d/getf objects)) shape-ids)
|
||||
|
||||
shapes
|
||||
(if expand-with-children
|
||||
(into []
|
||||
(mapcat (fn [shape]
|
||||
(if (= (:type shape) :group)
|
||||
(keep objects (:shapes shape))
|
||||
[shape])))
|
||||
shapes)
|
||||
shapes)
|
||||
|
||||
{:keys [attributes _ on-update-shape]}
|
||||
(get token-properties (:type token))
|
||||
|
||||
on-update-shape
|
||||
(if (seq attrs)
|
||||
(or (get attr->shape-update (first attrs)) on-update-shape)
|
||||
on-update-shape)]
|
||||
|
||||
(rx/of
|
||||
(cond
|
||||
(and (= (:type token) :spacing)
|
||||
(nil? attrs))
|
||||
(apply-spacing-token-separated {:token token
|
||||
:attr attrs
|
||||
:shapes shapes})
|
||||
|
||||
:else
|
||||
(apply-token {:attributes (if (empty? attrs) attributes attrs)
|
||||
:token token
|
||||
:shape-ids shape-ids
|
||||
:on-update-shape on-update-shape})))))))
|
||||
|
||||
|
||||
(defn apply-token-on-color-selected
|
||||
[color-operations token]
|
||||
(ptk/reify ::apply-token-on-selected
|
||||
(ptk/reify ::apply-token-on-color-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(let [undo-id (js/Symbol)]
|
||||
|
||||
@@ -140,6 +140,8 @@
|
||||
[:on-focus {:optional true} fn?]
|
||||
[:on-detach {:optional true} fn?]
|
||||
[:property {:optional true} :string]
|
||||
[:tooltip-placement {:optional true}
|
||||
[:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]]
|
||||
[:align {:optional true} [:maybe [:enum :left :right]]]])
|
||||
|
||||
(mf/defc numeric-input*
|
||||
@@ -151,7 +153,7 @@
|
||||
tokens applied-token empty-to-end
|
||||
on-change on-blur on-focus on-detach
|
||||
property align ref name
|
||||
text-icon]
|
||||
tooltip-placement text-icon]
|
||||
:rest props}]
|
||||
|
||||
(let [;; NOTE: we use mfu/bean here for transparently handle
|
||||
@@ -574,9 +576,9 @@
|
||||
:icon i/tokens
|
||||
:tooltip-class (stl/css :button-tooltip)
|
||||
:class (stl/css :invisible-button)
|
||||
:tooltip-placement "top-left"
|
||||
:aria-label (tr "ds.inputs.numeric-input.open-token-list-dropdown")
|
||||
:ref open-dropdown-ref
|
||||
:tooltip-placement tooltip-placement
|
||||
:on-click open-dropdown}])))
|
||||
:max-length max-length})
|
||||
|
||||
@@ -603,6 +605,7 @@
|
||||
:class inner-class
|
||||
:property property
|
||||
:is-open is-open
|
||||
:tooltip-placement tooltip-placement
|
||||
:slot-start (when (or icon text-icon)
|
||||
(mf/html
|
||||
(cond
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
[app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.ui.ds.controls.shared.options-dropdown :refer [options-dropdown* schema:option]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
||||
[app.main.ui.ds.tooltip.tooltip :refer [tooltip*]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.object :as obj]
|
||||
@@ -50,15 +52,17 @@
|
||||
[:map
|
||||
[:options [:vector {:min 1} schema:option]]
|
||||
[:class {:optional true} :string]
|
||||
[:wrapper-class {:optional true} :string]
|
||||
[:disabled {:optional true} :boolean]
|
||||
[:default-selected {:optional true} :string]
|
||||
[:empty-to-end {:optional true} [:maybe :boolean]]
|
||||
[:on-change {:optional true} fn?]
|
||||
[:variant {:optional true} [:maybe [:enum "default" "ghost"]]]])
|
||||
[:dropdown-alignment {:optional true} [:maybe [:enum :left :right]]]
|
||||
[:variant {:optional true} [:maybe [:enum "default" "ghost" "icon-only"]]]])
|
||||
|
||||
(mf/defc select*
|
||||
{::mf/schema schema:select}
|
||||
[{:keys [options class disabled default-selected empty-to-end on-change variant] :rest props}]
|
||||
[{:keys [options class disabled default-selected empty-to-end on-change variant wrapper-class dropdown-alignment] :rest props}]
|
||||
(let [;; NOTE: we use mfu/bean here for transparently handle
|
||||
;; options provide as clojure data structures or javascript
|
||||
;; plain objects and lists.
|
||||
@@ -192,26 +196,40 @@
|
||||
(some? icon)
|
||||
|
||||
dimmed?
|
||||
(:dimmed selected-option)]
|
||||
(:dimmed selected-option)
|
||||
|
||||
icon-ref (mf/use-ref nil)
|
||||
icon-id (mf/use-id)]
|
||||
|
||||
(mf/with-effect [options]
|
||||
(mf/set-ref-val! options-ref options))
|
||||
|
||||
[:div {:class (stl/css :select-wrapper)
|
||||
[:div {:class [wrapper-class (stl/css :select-wrapper)]
|
||||
:on-click on-click
|
||||
:ref select-ref
|
||||
:on-blur on-blur}
|
||||
|
||||
[:> :button props
|
||||
[:span {:class (stl/css-case :select-header true
|
||||
:header-icon has-icon?)}
|
||||
:header-icon has-icon?
|
||||
:header-icon-only (= variant "icon-only"))}
|
||||
(when ^boolean has-icon?
|
||||
[:> icon* {:icon-id icon
|
||||
:size "s"
|
||||
:aria-hidden true}])
|
||||
[:span {:class (stl/css-case :header-label true
|
||||
:header-label-dimmed (or empty-selected-id? dimmed?))}
|
||||
(if ^boolean empty-selected-id? "--" label)]]
|
||||
(if (= variant "icon-only")
|
||||
[:> tooltip* {:content label
|
||||
:trigger-ref icon-ref
|
||||
:id (dm/str icon-id "-name")
|
||||
:class (stl/css :option-text)}
|
||||
[:> icon* {:icon-id icon
|
||||
:ref icon-ref
|
||||
:aria-labelledby (dm/str icon-id "-name")}]]
|
||||
[:> icon* {:icon-id icon
|
||||
:size "s"
|
||||
:aria-hidden true}]))
|
||||
|
||||
(when-not ^boolean (= variant "icon-only")
|
||||
[:span {:class (stl/css-case :header-label true
|
||||
:header-label-dimmed (or empty-selected-id? dimmed?))}
|
||||
(if ^boolean empty-selected-id? "--" label)])]
|
||||
|
||||
[:> icon* {:icon-id i/arrow-down
|
||||
:class (stl/css :arrow)
|
||||
@@ -224,5 +242,6 @@
|
||||
:options options
|
||||
:selected selected-id
|
||||
:focused focused-id
|
||||
:align dropdown-alignment
|
||||
:empty-to-end empty-to-end
|
||||
:ref set-option-ref}])]))
|
||||
|
||||
@@ -109,3 +109,8 @@
|
||||
grid-template-columns: auto 1fr;
|
||||
color: var(--select-icon-color);
|
||||
}
|
||||
|
||||
.header-icon-only {
|
||||
grid-template-columns: 1fr;
|
||||
color: var(--select-icon-color);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import Components from "@target/components";
|
||||
|
||||
const { Select } = Components;
|
||||
|
||||
const variants = ["default", "ghost"];
|
||||
const variants = ["default", "ghost", "icon-only"];
|
||||
|
||||
const options = [
|
||||
{ id: "option-code", label: "Code" },
|
||||
@@ -75,3 +75,10 @@ export const EmptyToEnd = {
|
||||
emptyToEnd: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const OnlyWithIcons = {
|
||||
args: {
|
||||
options: optionsWithIcons,
|
||||
variant: variants[2],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
[:resolved-value {:optional true}
|
||||
[:or :int :string :float]]
|
||||
[:name {:optional true} :string]
|
||||
[:value {:optional true} :keyword]
|
||||
[:icon {:optional true} schema:icon-list]
|
||||
[:label {:optional true} :string]
|
||||
[:aria-label {:optional true} :string]])
|
||||
|
||||
@@ -31,12 +31,14 @@
|
||||
[:on-token-key-down fn?]
|
||||
[:on-blur {:optional true} fn?]
|
||||
[:on-focus {:optional true} fn?]
|
||||
[:tooltip-placement {:optional true}
|
||||
[:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]]
|
||||
[:detach-token fn?]])
|
||||
|
||||
(mf/defc token-field*
|
||||
{::mf/schema schema:token-field}
|
||||
[{:keys [id label value slot-start disabled class
|
||||
on-click on-token-key-down on-blur detach-token
|
||||
on-click on-token-key-down on-blur detach-token tooltip-placement
|
||||
token-wrapper-ref token-detach-btn-ref on-focus property is-open]}]
|
||||
(let [set-active? (some? id)
|
||||
content (if set-active?
|
||||
@@ -92,8 +94,8 @@
|
||||
:class (stl/css-case :invisible-button true
|
||||
:invisible-btn-dropdown-open is-open)
|
||||
:tooltip-class (stl/css :button-tooltip)
|
||||
:tooltip-placement tooltip-placement
|
||||
:icon i/broken-link
|
||||
:ref token-detach-btn-ref
|
||||
:tooltip-placement "top-left"
|
||||
:aria-label (tr "ds.inputs.token-field.detach-token")
|
||||
:on-click detach-token}])]]))
|
||||
|
||||
@@ -245,12 +245,19 @@
|
||||
(def ^:icon-id status-update "status-update")
|
||||
(def ^:icon-id status-wrong "status-wrong")
|
||||
(def ^:icon-id stroke-arrow "stroke-arrow")
|
||||
(def ^:icon-id stroke-center "stroke-center")
|
||||
(def ^:icon-id stroke-circle "stroke-circle")
|
||||
(def ^:icon-id stroke-dashed "stroke-dashed")
|
||||
(def ^:icon-id stroke-diamond "stroke-diamond")
|
||||
(def ^:icon-id stroke-dotted "stroke-dotted")
|
||||
(def ^:icon-id stroke-inside "stroke-inside")
|
||||
(def ^:icon-id stroke-mixed "stroke-mixed")
|
||||
(def ^:icon-id stroke-outside "stroke-outside")
|
||||
(def ^:icon-id stroke-rectangle "stroke-rectangle")
|
||||
(def ^:icon-id stroke-rounded "stroke-rounded")
|
||||
(def ^:icon-id stroke-size "stroke-size")
|
||||
(def ^:icon-id stroke-squared "stroke-squared")
|
||||
(def ^:icon-id stroke-solid "stroke-solid")
|
||||
(def ^:icon-id stroke-triangle "stroke-triangle")
|
||||
(def ^:icon-id svg "svg")
|
||||
(def ^:icon-id swatches "swatches")
|
||||
|
||||
@@ -43,11 +43,15 @@ $column-number: 8; // total number of columns
|
||||
// -> 8 columns (32px each) + 7 gaps (4px each) = 284px
|
||||
|
||||
// Derived widths
|
||||
$options-width: calc(#{$column-width} * #{$column-number} + #{$column-gap} * calc(#{$column-number} - 1));
|
||||
$seven-column-width: calc(
|
||||
#{$column-width} * calc(#{$column-number} - 1) + #{$column-gap} * calc(#{$column-number} - 2)
|
||||
);
|
||||
@function grid-width($cols) {
|
||||
@return calc(#{$column-width} * #{$cols} + #{$column-gap} * #{$cols - 1});
|
||||
}
|
||||
|
||||
$options-width: grid-width($column-number);
|
||||
$two-column-width: grid-width(2);
|
||||
$three-column-width: grid-width(3);
|
||||
$four-column-width: grid-width(4);
|
||||
$seven-column-width: grid-width(7);
|
||||
// ------------------------------------------------------------
|
||||
// Grid mixin — applies the standard structure to any container
|
||||
// ------------------------------------------------------------
|
||||
@@ -73,16 +77,28 @@ $seven-column-width: calc(
|
||||
// |___|-|___|-|___|-|___|-|___|-|___|-|___|-|___|
|
||||
// -> 8 columns (32px each) + 7 gaps (4px each) = 284px
|
||||
//
|
||||
// But one block (grid-exception-input) doesn’t fit perfectly:
|
||||
// But two blocks don’t fit perfectly:
|
||||
// First (grid-exception-input-width)
|
||||
// |__________________|-|__________________|-|___|
|
||||
//
|
||||
// We calculate the width of that grid-exception-input as:
|
||||
// We calculate the width of that grid-exception-input-width as:
|
||||
//
|
||||
// - 3.5 columns of base grid width
|
||||
// - + 3 inter-column gaps
|
||||
// - − half a gap (because it’s visually shared with the next block)
|
||||
|
||||
$grid-exception-input-width: calc(#{$sz-32} * 3.5 + 3 * var(--sp-xs) - (var(--sp-xs) / 2));
|
||||
//
|
||||
// |___|-|___|-|___|-|___|-|___|-|___|-|___|-|___|
|
||||
//
|
||||
// Second (grid-exception-input-width-small)
|
||||
// |__________________|-|____________|-|___|-|___|
|
||||
//
|
||||
// We calculate the width of that grid-exception-input-width-small as:
|
||||
//
|
||||
// - 2.5 columns of base grid width
|
||||
// - + 2 inter-column gaps
|
||||
// - − half a gap (because it’s visually shared with the next block)
|
||||
|
||||
$grid-exception-input-width-small: calc(#{$sz-32} * 2.5 + 2 * var(--sp-xs) - (var(--sp-xs) / 2));
|
||||
|
||||
// ============================================================
|
||||
// CSS VARIABLES (exposed for runtime use)
|
||||
@@ -95,7 +111,11 @@ $grid-exception-input-width: calc(#{$sz-32} * 3.5 + 3 * var(--sp-xs) - (var(--sp
|
||||
--left-sidebar-width-max: #{$left-sidebar-width-max};
|
||||
--right-sidebar-width: #{$right-sidebar-width};
|
||||
--right-sidebar-width-max: #{$right-sidebar-width-max};
|
||||
--7-columns-dropdown-width: #{$seven-column-width};
|
||||
--2-columns-width: #{$two-column-width};
|
||||
--3-columns-width: #{$three-column-width};
|
||||
--4-columns-width: #{$four-column-width};
|
||||
--7-columns-width: #{$seven-column-width};
|
||||
--options-width: #{$options-width};
|
||||
--grid-exception-input-width: #{$grid-exception-input-width};
|
||||
--grid-exception-input-width-small: #{$grid-exception-input-width-small};
|
||||
}
|
||||
|
||||
@@ -164,64 +164,50 @@
|
||||
(mf/with-effect [ids]
|
||||
(reset! radius-expanded* false))
|
||||
|
||||
[:section {:class (dm/str class " " (stl/css :radius))
|
||||
:aria-label "border-radius-section"}
|
||||
(if (not radius-expanded)
|
||||
(if token-numeric-inputs
|
||||
[:> numeric-input-wrapper*
|
||||
{:on-change on-all-radius-change
|
||||
:on-detach on-detach-all
|
||||
:icon i/corner-radius
|
||||
:min 0
|
||||
:attr :border-radius
|
||||
:nillable true
|
||||
:property (tr "workspace.options.radius")
|
||||
:applied-token (cond
|
||||
(not (seq applied-tokens))
|
||||
nil
|
||||
(if token-numeric-inputs
|
||||
[:section {:class (dm/str class " " (stl/css :radius-token))
|
||||
:aria-label (tr "workspace.options.radius.radius-section")}
|
||||
[:div {:class (stl/css :radius-first-row)}
|
||||
[:> numeric-input-wrapper*
|
||||
{:on-change on-all-radius-change
|
||||
:on-detach on-detach-all
|
||||
:icon i/corner-radius
|
||||
:min 0
|
||||
:attr :border-radius
|
||||
:nillable true
|
||||
:property (tr "workspace.options.radius")
|
||||
:applied-token (cond
|
||||
(not (seq applied-tokens))
|
||||
nil
|
||||
|
||||
(or (not all-values-equal?) (not all-token-equal?))
|
||||
:multiple
|
||||
(or (not all-values-equal?) (not all-token-equal?))
|
||||
:multiple
|
||||
|
||||
:else
|
||||
(get applied-tokens :r1))
|
||||
:align :right
|
||||
:placeholder (cond
|
||||
(or (not all-values-equal?)
|
||||
(not all-token-equal?))
|
||||
(tr "settings.multiple")
|
||||
:else
|
||||
"--")
|
||||
:value (if all-values-equal?
|
||||
(if (nil? (:r1 values))
|
||||
0
|
||||
(:r1 values))
|
||||
nil)}]
|
||||
|
||||
[:div {:class (stl/css :radius-1)
|
||||
:title (tr "workspace.options.radius")}
|
||||
[:> icon* {:icon-id i/corner-radius
|
||||
:size "s"
|
||||
:class (stl/css :icon)}]
|
||||
[:> deprecated-input/numeric-input*
|
||||
{:placeholder (cond
|
||||
(not all-values-equal?)
|
||||
(tr "settings.multiple")
|
||||
(= :multiple (:r1 values))
|
||||
(tr "settings.multiple")
|
||||
:else
|
||||
"--")
|
||||
:min 0
|
||||
:nillable true
|
||||
:on-change on-all-radius-change
|
||||
:value (if all-values-equal?
|
||||
(if (nil? (:r1 values))
|
||||
0
|
||||
(:r1 values))
|
||||
nil)}]])
|
||||
(get applied-tokens :r1))
|
||||
:align :right
|
||||
:placeholder (cond
|
||||
(or (not all-values-equal?)
|
||||
(not all-token-equal?))
|
||||
(tr "settings.multiple")
|
||||
:else
|
||||
"--")
|
||||
:value (if all-values-equal?
|
||||
(if (nil? (:r1 values))
|
||||
0
|
||||
(:r1 values))
|
||||
nil)}]
|
||||
[:> icon-button* {:class (stl/css-case :selected radius-expanded)
|
||||
:variant "ghost"
|
||||
:tooltip-placement "top-left"
|
||||
:on-click toggle-radius-mode
|
||||
:aria-label (if radius-expanded
|
||||
(tr "workspace.options.radius.hide-all-corners")
|
||||
(tr "workspace.options.radius.show-single-corners"))
|
||||
:icon i/corner-radius}]]
|
||||
|
||||
(if token-numeric-inputs
|
||||
[:div {:class (stl/css :radius-4)}
|
||||
(when radius-expanded
|
||||
[:div {:class (stl/css :radius-4-token)}
|
||||
[:> numeric-input-wrapper*
|
||||
{:on-change on-radius-r1-change
|
||||
:on-detach on-detach-r1
|
||||
@@ -249,6 +235,7 @@
|
||||
:property (tr "workspace.options.radius-top-right")
|
||||
:applied-token (get applied-tokens :r2)
|
||||
:align :right
|
||||
:tooltip-placement "top-left"
|
||||
:inner-class (stl/css :no-icon-input)
|
||||
:placeholder (cond
|
||||
(or (= :multiple (get applied-tokens :r2))
|
||||
@@ -293,9 +280,33 @@
|
||||
"--")
|
||||
:align :right
|
||||
:class (stl/css :radius-wrapper)
|
||||
:tooltip-placement "top-left"
|
||||
:inner-class (stl/css :no-icon-input)
|
||||
:value (:r3 values)}]]
|
||||
|
||||
:value (:r3 values)}]])]
|
||||
[:section {:class (dm/str class " " (stl/css :radius))
|
||||
:aria-label (tr "workspace.options.radius.radius-section")}
|
||||
(if (not radius-expanded)
|
||||
[:div {:class (stl/css :radius-1)
|
||||
:title (tr "workspace.options.radius")}
|
||||
[:> icon* {:icon-id i/corner-radius
|
||||
:size "s"
|
||||
:class (stl/css :icon)}]
|
||||
[:> deprecated-input/numeric-input*
|
||||
{:placeholder (cond
|
||||
(not all-values-equal?)
|
||||
(tr "settings.multiple")
|
||||
(= :multiple (:r1 values))
|
||||
(tr "settings.multiple")
|
||||
:else
|
||||
"--")
|
||||
:min 0
|
||||
:nillable true
|
||||
:on-change on-all-radius-change
|
||||
:value (if all-values-equal?
|
||||
(if (nil? (:r1 values))
|
||||
0
|
||||
(:r1 values))
|
||||
nil)}]]
|
||||
[:div {:class (stl/css :radius-4)}
|
||||
[:div {:class (stl/css :small-input)}
|
||||
[:> deprecated-input/numeric-input*
|
||||
@@ -327,12 +338,11 @@
|
||||
:title (tr "workspace.options.radius-bottom-right")
|
||||
:min 0
|
||||
:on-change on-radius-r3-change
|
||||
:value (:r3 values)}]]]))
|
||||
|
||||
[:> icon-button* {:class (stl/css-case :selected radius-expanded)
|
||||
:variant "ghost"
|
||||
:on-click toggle-radius-mode
|
||||
:aria-label (if radius-expanded
|
||||
(tr "workspace.options.radius.hide-all-corners")
|
||||
(tr "workspace.options.radius.show-single-corners"))
|
||||
:icon i/corner-radius}]]))
|
||||
:value (:r3 values)}]]])
|
||||
[:> icon-button* {:class (stl/css-case :selected radius-expanded)
|
||||
:variant "ghost"
|
||||
:on-click toggle-radius-mode
|
||||
:aria-label (if radius-expanded
|
||||
(tr "workspace.options.radius.hide-all-corners")
|
||||
(tr "workspace.options.radius.show-single-corners"))
|
||||
:icon i/corner-radius}]])))
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.radius-1 {
|
||||
.radius-1,
|
||||
.small-input {
|
||||
@extend .input-element;
|
||||
@include t.use-typography("body-small");
|
||||
}
|
||||
@@ -25,23 +26,12 @@
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.small-input {
|
||||
@extend .input-element;
|
||||
@include t.use-typography("body-small");
|
||||
}
|
||||
|
||||
.selected {
|
||||
border-color: var(--button-icon-border-color-selected);
|
||||
background-color: var(--button-icon-background-color-selected);
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.selected {
|
||||
border-color: var(--button-icon-border-color-selected);
|
||||
background-color: var(--button-icon-background-color-selected);
|
||||
color: var(--button-icon-foreground-color-selected);
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-inline: var(--sp-xs);
|
||||
}
|
||||
@@ -53,3 +43,20 @@
|
||||
.dropdown-offset {
|
||||
--dropdown-offset: #{px2rem(-65)};
|
||||
}
|
||||
|
||||
.radius-token {
|
||||
display: grid;
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.radius-first-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.radius-4-token {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
[color-operations _] (retrieve-color-operations groups old-color prev-colors)]
|
||||
(mf/set-ref-val! prev-colors-ref
|
||||
(conj prev-colors color))
|
||||
(st/emit! (dwta/apply-token-on-selected color-operations token)))))]
|
||||
(st/emit! (dwta/apply-token-on-color-selected color-operations token)))))]
|
||||
|
||||
[:div {:class (stl/css :element-set)}
|
||||
[:div {:class (stl/css :element-title)}
|
||||
|
||||
@@ -174,10 +174,10 @@
|
||||
(mf/deps ids)
|
||||
(fn [_ token]
|
||||
(st/emit!
|
||||
(dwta/toggle-token {:token token
|
||||
:attrs #{:fill}
|
||||
:shape-ids ids
|
||||
:expand-with-children true}))))
|
||||
(dwta/apply-token-from-input {:token token
|
||||
:attrs #{:fill}
|
||||
:shape-ids ids
|
||||
:expand-with-children true}))))
|
||||
|
||||
on-detach-token
|
||||
(mf/use-fn
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
.numeric-input-wrapper {
|
||||
--dropdown-width: var(--7-columns-dropdown-width);
|
||||
--dropdown-width: var(--7-columns-width);
|
||||
}
|
||||
|
||||
@@ -138,14 +138,13 @@
|
||||
|
||||
on-opacity-change
|
||||
(mf/use-fn
|
||||
(mf/deps on-change handle-opacity-change)
|
||||
(mf/deps handle-opacity-change)
|
||||
(fn [value]
|
||||
(if (or (string? value) (number? value))
|
||||
(handle-opacity-change value)
|
||||
(do
|
||||
(st/emit! (dwta/toggle-token {:token (first value)
|
||||
:attrs #{:opacity}
|
||||
:shape-ids ids}))))))
|
||||
(st/emit! (dwta/apply-token-from-input {:token (first value)
|
||||
:attrs #{:opacity}
|
||||
:shape-ids ids})))))
|
||||
|
||||
handle-set-hidden
|
||||
(mf/use-fn
|
||||
@@ -205,20 +204,25 @@
|
||||
preview-complete?))
|
||||
(swap! state* assoc :selected-blend-mode current-blend-mode)))
|
||||
|
||||
[:section {:class (stl/css-case :element-set-content true
|
||||
:hidden hidden?)
|
||||
:aria-label "layer-menu-section"}
|
||||
[:div {:class (stl/css :select)}
|
||||
[:& select
|
||||
{:default-value selected-blend-mode
|
||||
:options options
|
||||
:on-change handle-change-blend-mode
|
||||
:is-open? option-highlighted?
|
||||
:class (stl/css-case :hidden-select hidden?)
|
||||
:on-pointer-enter-option handle-blend-mode-enter
|
||||
:on-pointer-leave-option handle-blend-mode-leave}]]
|
||||
;; NOTE:
|
||||
;; This code is temporarily duplicated because the UI is changing with a new feature.
|
||||
;; The new implementation is currently behind a feature/config flag and not yet released.
|
||||
;; Once the feature is released, the duplicated ClojureScript and SCSS code should be removed.
|
||||
;; https://tree.taiga.io/project/penpot/task/13704
|
||||
|
||||
(if token-numeric-inputs
|
||||
;; TODO: When duplicated code is remove rename this class removing the "token" reference from it
|
||||
[:section {:class (stl/css :element-set-content-token)
|
||||
:aria-label (tr "workspace.options.layer-options.layer-section")}
|
||||
[:& select
|
||||
{:default-value selected-blend-mode
|
||||
:options options
|
||||
:on-change handle-change-blend-mode
|
||||
:is-open? option-highlighted?
|
||||
:class (stl/css-case :hidden-select hidden?)
|
||||
:on-pointer-enter-option handle-blend-mode-enter
|
||||
:on-pointer-leave-option handle-blend-mode-leave}]
|
||||
|
||||
(if token-numeric-inputs
|
||||
[:> numeric-input-wrapper*
|
||||
{:on-change on-opacity-change
|
||||
:on-detach on-detach-token
|
||||
@@ -233,10 +237,54 @@
|
||||
(tr "settings.multiple")
|
||||
"--")
|
||||
:align :right
|
||||
:disabled hidden?
|
||||
:class (stl/css :numeric-input-wrapper)
|
||||
:value (* 100
|
||||
(or (get values :opacity) 1))}]
|
||||
|
||||
(cond
|
||||
(or (= :multiple hidden?) (not hidden?))
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.layer-options.toggle-layer")
|
||||
:on-click handle-set-hidden
|
||||
:tooltip-placement "top-left"
|
||||
:icon i/shown}]
|
||||
|
||||
:else
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.layer-options.toggle-layer")
|
||||
:on-click handle-set-visible
|
||||
:tooltip-placement "top-left"
|
||||
:icon i/hide}])
|
||||
|
||||
(cond
|
||||
(or (= :multiple blocked?) (not blocked?))
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.shape.menu.lock")
|
||||
:on-click handle-set-blocked
|
||||
:tooltip-placement "top-left"
|
||||
:icon i/unlock}]
|
||||
|
||||
:else
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.shape.menu.unlock")
|
||||
:on-click handle-set-unblocked
|
||||
:tooltip-placement "top-left"
|
||||
:icon i/lock}])]
|
||||
|
||||
[:section {:class (stl/css-case :element-set-content true
|
||||
:hidden hidden?)
|
||||
:aria-label (tr "workspace.options.layer-options.layer-section")}
|
||||
[:div {:class (stl/css :select)}
|
||||
[:& select
|
||||
{:default-value selected-blend-mode
|
||||
:options options
|
||||
:on-change handle-change-blend-mode
|
||||
:is-open? option-highlighted?
|
||||
:class (stl/css-case :hidden-select hidden?)
|
||||
:on-pointer-enter-option handle-blend-mode-enter
|
||||
:on-pointer-leave-option handle-blend-mode-leave}]]
|
||||
|
||||
[:div {:class (stl/css :input)
|
||||
:title (tr "workspace.options.opacity")}
|
||||
[:span {:class (stl/css :icon)} "%"]
|
||||
@@ -246,31 +294,31 @@
|
||||
:on-change handle-opacity-change
|
||||
:min 0
|
||||
:max 100
|
||||
:className (stl/css :numeric-input)}]])
|
||||
:className (stl/css :numeric-input)}]]
|
||||
|
||||
[:div {:class (stl/css :actions)}
|
||||
(cond
|
||||
(or (= :multiple hidden?) (not hidden?))
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.layer-options.toggle-layer")
|
||||
:on-click handle-set-hidden
|
||||
:icon i/shown}]
|
||||
[:div {:class (stl/css :actions)}
|
||||
(cond
|
||||
(or (= :multiple hidden?) (not hidden?))
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.layer-options.toggle-layer")
|
||||
:on-click handle-set-hidden
|
||||
:icon i/shown}]
|
||||
|
||||
:else
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.layer-options.toggle-layer")
|
||||
:on-click handle-set-visible
|
||||
:icon i/hide}])
|
||||
:else
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.options.layer-options.toggle-layer")
|
||||
:on-click handle-set-visible
|
||||
:icon i/hide}])
|
||||
|
||||
(cond
|
||||
(or (= :multiple blocked?) (not blocked?))
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.shape.menu.lock")
|
||||
:on-click handle-set-blocked
|
||||
:icon i/unlock}]
|
||||
(cond
|
||||
(or (= :multiple blocked?) (not blocked?))
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.shape.menu.lock")
|
||||
:on-click handle-set-blocked
|
||||
:icon i/unlock}]
|
||||
|
||||
:else
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.shape.menu.unlock")
|
||||
:on-click handle-set-unblocked
|
||||
:icon i/lock}])]]))
|
||||
:else
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.shape.menu.unlock")
|
||||
:on-click handle-set-unblocked
|
||||
:icon i/lock}])]])))
|
||||
|
||||
@@ -7,18 +7,23 @@
|
||||
@use "refactor/common-refactor.scss" as deprecated;
|
||||
@use "../../../sidebar/common/sidebar.scss" as sidebar;
|
||||
@use "ds/_utils.scss" as *;
|
||||
@use "ds/_sizes.scss" as *;
|
||||
@use "ds/_borders.scss" as *;
|
||||
@use "ds/typography.scss" as t;
|
||||
|
||||
// This code should be remove when numeric-input-tokens are activated
|
||||
// https://tree.taiga.io/project/penpot/task/13704
|
||||
.element-set-content {
|
||||
@include sidebar.option-grid-structure;
|
||||
height: deprecated.$s-32;
|
||||
margin-bottom: deprecated.$s-8;
|
||||
block-size: $sz-32;
|
||||
margin-block-end: var(--sp-s);
|
||||
.select {
|
||||
grid-column: span 4;
|
||||
padding: 0;
|
||||
}
|
||||
.input {
|
||||
@extend .input-element;
|
||||
@include deprecated.bodySmallTypography;
|
||||
@include t.use-typography("body-small");
|
||||
grid-column: span 2;
|
||||
}
|
||||
.actions {
|
||||
@@ -29,12 +34,22 @@
|
||||
|
||||
&.hidden {
|
||||
.hidden-select {
|
||||
@include deprecated.hiddenElement;
|
||||
border: deprecated.$s-1 solid var(--input-border-color-disabled);
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
box-sizing: border-box;
|
||||
color: var(--input-foreground-color-disabled);
|
||||
stroke: var(--input-foreground-color-disabled);
|
||||
background-color: transparent;
|
||||
border: $b-1 solid var(--input-border-color-disabled);
|
||||
}
|
||||
.input {
|
||||
@include deprecated.hiddenElement;
|
||||
border: deprecated.$s-1 solid var(--input-border-color-disabled);
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
box-sizing: border-box;
|
||||
color: var(--input-foreground-color-disabled);
|
||||
stroke: var(--input-foreground-color-disabled);
|
||||
background-color: transparent;
|
||||
border: $b-1 solid var(--input-border-color-disabled);
|
||||
.icon {
|
||||
stroke: var(--input-foreground-color-disabled);
|
||||
}
|
||||
@@ -45,7 +60,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
// This code should remain when numeric-input-tokens are activated
|
||||
// https://tree.taiga.io/project/penpot/task/13704
|
||||
|
||||
// This rule should be rename when numeric-input-tokens are
|
||||
// activated removing the token reference on the class
|
||||
.element-set-content-token {
|
||||
@include sidebar.option-grid-structure;
|
||||
block-size: $sz-32;
|
||||
margin-block-end: var(--sp-s);
|
||||
grid-template-columns: var(--grid-exception-input-width) var(--grid-exception-input-width-small) auto auto;
|
||||
}
|
||||
|
||||
.hidden-select {
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
box-sizing: border-box;
|
||||
color: var(--input-foreground-color-disabled);
|
||||
stroke: var(--input-foreground-color-disabled);
|
||||
background-color: transparent;
|
||||
border: $b-1 solid var(--input-border-color-disabled);
|
||||
}
|
||||
|
||||
.numeric-input-wrapper {
|
||||
grid-column: span 2;
|
||||
--dropdown-offset: #{px2rem(-35)};
|
||||
}
|
||||
|
||||
@@ -463,9 +463,9 @@
|
||||
(if (or (string? value) (number? value))
|
||||
(on-change :multiple attr value event)
|
||||
(do
|
||||
(st/emit! (dwta/toggle-token {:token (first value)
|
||||
:attrs #{attr}
|
||||
:shape-ids ids}))))))
|
||||
(st/emit! (dwta/apply-token-from-input {:token (first value)
|
||||
:attrs #{attr}
|
||||
:shape-ids ids}))))))
|
||||
|
||||
on-focus
|
||||
(mf/use-fn
|
||||
|
||||
@@ -283,9 +283,9 @@
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
||||
(udw/update-dimensions ids attr value))
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
||||
(dwta/toggle-token {:token (first value)
|
||||
:attrs #{attr}
|
||||
:shape-ids ids})))))
|
||||
(dwta/apply-token-from-input {:token (first value)
|
||||
:attrs #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-proportion-lock-change
|
||||
(mf/use-fn
|
||||
@@ -304,9 +304,9 @@
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||
(st/emit! (udw/update-positions ids {attr value})))
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
||||
(dwta/toggle-token {:token (first value)
|
||||
:attrs #{attr}
|
||||
:shape-ids ids})))))
|
||||
(dwta/apply-token-from-input {:token (first value)
|
||||
:attrs #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-rotation-change
|
||||
(mf/use-fn
|
||||
@@ -317,9 +317,9 @@
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||
(st/emit! (udw/increase-rotation ids value)))
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
||||
(dwta/toggle-token {:token (first value)
|
||||
:attrs #{:rotation}
|
||||
:shape-ids ids})))))
|
||||
(dwta/apply-token-from-input {:token (first value)
|
||||
:attrs #{:rotation}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-width-change
|
||||
(mf/use-fn (mf/deps on-size-change) #(on-size-change % :width))
|
||||
|
||||
@@ -191,5 +191,5 @@
|
||||
|
||||
// TODO: Add a proper variable to this sizing
|
||||
.numeric-input-measures {
|
||||
--dropdown-width: var(--7-columns-dropdown-width);
|
||||
--dropdown-width: var(--7-columns-width);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
[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.controls.select :refer [select*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
||||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.workspace.sidebar.options.common :as soc]
|
||||
@@ -108,9 +109,9 @@
|
||||
(d/concat-vec
|
||||
(when (= :multiple stroke-alignment)
|
||||
[{:value :multiple :label "--"}])
|
||||
[{:value :center :label (tr "workspace.options.stroke.center")}
|
||||
{:value :inner :label (tr "workspace.options.stroke.inner")}
|
||||
{:value :outer :label (tr "workspace.options.stroke.outer")}]))
|
||||
[{:value :center :label (tr "workspace.options.stroke.center") :id "center" :icon "stroke-center"}
|
||||
{:value :inner :label (tr "workspace.options.stroke.inner") :id "inner" :icon "stroke-inside"}
|
||||
{:value :outer :label (tr "workspace.options.stroke.outer") :id "outer" :icon "stroke-outside"}]))
|
||||
|
||||
on-alignment-change
|
||||
(mf/use-fn
|
||||
@@ -122,10 +123,10 @@
|
||||
(mf/deps ids)
|
||||
(fn [_ token]
|
||||
(st/emit!
|
||||
(dwta/toggle-token {:token token
|
||||
:attrs #{:stroke-color}
|
||||
:shape-ids ids
|
||||
:expand-with-children true}))))
|
||||
(dwta/apply-token-from-input {:token token
|
||||
:attrs #{:stroke-color}
|
||||
:shape-ids ids
|
||||
:expand-with-children true}))))
|
||||
|
||||
stroke-style (or (:stroke-style stroke) :solid)
|
||||
|
||||
@@ -134,10 +135,10 @@
|
||||
(d/concat-vec
|
||||
(when (= :multiple stroke-style)
|
||||
[{:value :multiple :label "--"}])
|
||||
[{:value :solid :label (tr "workspace.options.stroke.solid")}
|
||||
{:value :dotted :label (tr "workspace.options.stroke.dotted")}
|
||||
{:value :dashed :label (tr "workspace.options.stroke.dashed")}
|
||||
{:value :mixed :label (tr "workspace.options.stroke.mixed")}]))
|
||||
[{:value :solid :label (tr "workspace.options.stroke.solid") :id "solid" :icon "stroke-solid"}
|
||||
{:value :dotted :label (tr "workspace.options.stroke.dotted") :id "dotted" :icon "stroke-dotted"}
|
||||
{:value :dashed :label (tr "workspace.options.stroke.dashed") :id "dashed" :icon "stroke-dashed"}
|
||||
{:value :mixed :label (tr "workspace.options.stroke.mixed") :id "mixed" :icon "stroke-mixed"}]))
|
||||
|
||||
on-style-change
|
||||
(mf/use-fn
|
||||
@@ -212,8 +213,8 @@
|
||||
:on-blur on-blur}]
|
||||
|
||||
;; Stroke Width, Alignment & Style
|
||||
[:div {:class (stl/css :stroke-options)}
|
||||
(if token-numeric-inputs
|
||||
(if token-numeric-inputs
|
||||
[:div {:class (stl/css :stroke-options-tokens)}
|
||||
[:> numeric-input-wrapper* {:on-change on-width-change
|
||||
:on-detach on-detach-token-width
|
||||
:icon i/stroke-size
|
||||
@@ -225,7 +226,23 @@
|
||||
:property (tr "workspace.options.stroke-width")
|
||||
:applied-token (get applied-tokens :stroke-width)
|
||||
:value stroke-width}]
|
||||
[:> select* {:default-selected (d/name stroke-alignment)
|
||||
:options stroke-alignment-options
|
||||
:variant "icon-only"
|
||||
:data-testid "stroke.alignment"
|
||||
:wrapper-class (stl/css :stroke-align-icon-select)
|
||||
:on-change on-alignment-change}]
|
||||
|
||||
(when-not disable-stroke-style
|
||||
[:> select* {:default-selected (d/name stroke-style)
|
||||
:options stroke-style-options
|
||||
:wrapper-class (stl/css :stroke-style-icon-select)
|
||||
:data-testid "stroke.style"
|
||||
:variant "icon-only"
|
||||
:dropdown-alignment :right
|
||||
:on-change on-style-change}])]
|
||||
|
||||
[:div {:class (stl/css :stroke-options)}
|
||||
[:div {:class (stl/css :stroke-width-input)
|
||||
:title (tr "workspace.options.stroke-width")}
|
||||
[:> icon* {:icon-id i/stroke-size
|
||||
@@ -236,20 +253,19 @@
|
||||
:on-change on-width-change
|
||||
:on-focus on-focus
|
||||
:select-on-focus select-on-focus
|
||||
:on-blur on-blur}]])
|
||||
:on-blur on-blur}]]
|
||||
[:div {:class (stl/css :stroke-alignment-select)
|
||||
:data-testid "stroke.alignment"}
|
||||
[:& select {:default-value stroke-alignment
|
||||
:options stroke-alignment-options
|
||||
:on-change on-alignment-change}]]
|
||||
|
||||
[:div {:class (stl/css :stroke-alignment-select)
|
||||
:data-testid "stroke.alignment"}
|
||||
[:& select {:default-value stroke-alignment
|
||||
:options stroke-alignment-options
|
||||
:on-change on-alignment-change}]]
|
||||
|
||||
(when-not disable-stroke-style
|
||||
[:div {:class (stl/css :stroke-style-select)
|
||||
:data-testid "stroke.style"}
|
||||
[:& select {:default-value stroke-style
|
||||
:options stroke-style-options
|
||||
:on-change on-style-change}]])]
|
||||
(when-not disable-stroke-style
|
||||
[:div {:class (stl/css :stroke-style-select)
|
||||
:data-testid "stroke.style"}
|
||||
[:& select {:default-value stroke-style
|
||||
:options stroke-style-options
|
||||
:on-change on-style-change}]])])
|
||||
|
||||
;; Stroke Caps
|
||||
(when show-caps
|
||||
|
||||
@@ -38,17 +38,12 @@
|
||||
.stroke-width-input {
|
||||
grid-column: span 2;
|
||||
|
||||
// TODO replace with numeric-input* from DS
|
||||
@extend .input-element;
|
||||
|
||||
@include t.use-typography("body-small");
|
||||
padding-inline-start: var(--sp-xs);
|
||||
}
|
||||
|
||||
.numeric-input-wrapper {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.stroke-alignment-select {
|
||||
grid-column: span 3;
|
||||
}
|
||||
@@ -62,3 +57,18 @@
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
column-gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.stroke-options-tokens {
|
||||
@include sidebar.option-grid-structure;
|
||||
grid-template-columns: var(--3-columns-width) var(--grid-exception-input-width-small) var(
|
||||
--grid-exception-input-width-small
|
||||
);
|
||||
}
|
||||
|
||||
.stroke-align-icon-select {
|
||||
--dropdown-width: var(--4-columns-width);
|
||||
}
|
||||
|
||||
.stroke-style-icon-select {
|
||||
--dropdown-width: var(--4-columns-width);
|
||||
}
|
||||
|
||||
@@ -6845,6 +6845,10 @@ msgstr "Selected layers"
|
||||
msgid "workspace.options.layer-options.toggle-layer"
|
||||
msgstr "Toggle layer visibility"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/layer.cljs:255
|
||||
msgid "workspace.options.layer-options.layer-section"
|
||||
msgstr "Layer menu section"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs
|
||||
#, unused
|
||||
msgid "workspace.options.layout-item.advanced-ops"
|
||||
@@ -7029,6 +7033,10 @@ msgstr "Collapse independent radius"
|
||||
msgid "workspace.options.radius.show-single-corners"
|
||||
msgstr "Show independent radius"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs:341
|
||||
msgid "workspace.options.radius.radius-section"
|
||||
msgstr "Border radius section"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:191
|
||||
msgid "workspace.options.recent-fonts"
|
||||
msgstr "Recent"
|
||||
|
||||
@@ -6762,6 +6762,10 @@ msgstr "Capas seleccionadas"
|
||||
msgid "workspace.options.layer-options.toggle-layer"
|
||||
msgstr "Mostrar/ocultar capa"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/layer.cljs:255
|
||||
msgid "workspace.options.layer-options.layer-section"
|
||||
msgstr "Sección del menú de capas"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs
|
||||
#, unused
|
||||
msgid "workspace.options.layout-item.advanced-ops"
|
||||
@@ -6946,6 +6950,10 @@ msgstr "Colapsar radios individuales"
|
||||
msgid "workspace.options.radius.show-single-corners"
|
||||
msgstr "Mostrar radios individuales"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs:341
|
||||
msgid "workspace.options.radius.radius-section"
|
||||
msgstr "Sección de radios de borde"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:191
|
||||
msgid "workspace.options.recent-fonts"
|
||||
msgstr "Recientes"
|
||||
|
||||