mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 19:06:18 +00:00
♻️ Replace border radius inputs (#7953)
* ✨ Replace border radius numeric input * ✨ Add border radius token inputs on multiple selection
This commit is contained in:
parent
c98373658e
commit
dd2d03e6a0
@ -50,7 +50,7 @@ const setupTokensFile = async (page, options = {}) => {
|
|||||||
const {
|
const {
|
||||||
file = "workspace/get-file-tokens.json",
|
file = "workspace/get-file-tokens.json",
|
||||||
fileFragment = "workspace/get-file-fragment-tokens.json",
|
fileFragment = "workspace/get-file-fragment-tokens.json",
|
||||||
flags = [],
|
flags = ["enable-feature-token-input"],
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const workspacePage = new WorkspacePage(page);
|
const workspacePage = new WorkspacePage(page);
|
||||||
@ -2242,6 +2242,56 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("User applies border-radius token to a shape from sidebar", async ({ page }) => {
|
||||||
|
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
||||||
|
await setupTokensFile(page);
|
||||||
|
|
||||||
|
await page.getByRole("tab", { name: "Layers" }).click();
|
||||||
|
|
||||||
|
|
||||||
|
await workspacePage.layers.getByTestId("layer-row").nth(1).click();
|
||||||
|
|
||||||
|
// Open tokens sections on left sidebar
|
||||||
|
const tokensTabButton = page.getByRole("tab", { name: "Tokens" });
|
||||||
|
await tokensTabButton.click();
|
||||||
|
|
||||||
|
// Unfold border radius tokens
|
||||||
|
await page.getByRole("button", { name: "Border Radius 3" }).click();
|
||||||
|
await expect(
|
||||||
|
tokensSidebar.getByRole("button", { name: "borderRadius" }),
|
||||||
|
).toBeVisible();
|
||||||
|
await tokensSidebar.getByRole("button", { name: "borderRadius" }).click();
|
||||||
|
await expect(
|
||||||
|
tokensSidebar.getByRole("button", { name: "borderRadius.sm" }),
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
|
// Apply border radius token from token panels
|
||||||
|
await tokensSidebar.getByRole("button", { name: "borderRadius.sm" }).click();
|
||||||
|
|
||||||
|
// Check if border radius sections is visible on right sidebar
|
||||||
|
const borderRadiusSection = page.getByRole("region", {name: "border-radius-section"});
|
||||||
|
await expect(borderRadiusSection).toBeVisible();
|
||||||
|
|
||||||
|
// Check if token pill is visible on design tab on right sidebar
|
||||||
|
const brTokenPillSM = borderRadiusSection.getByRole('button', { name: 'borderRadius.sm' });
|
||||||
|
await expect(brTokenPillSM).toBeVisible();
|
||||||
|
await brTokenPillSM.click();
|
||||||
|
|
||||||
|
// Change token from dropdown
|
||||||
|
const brTokenOptionXl = borderRadiusSection.getByLabel('borderRadius.xl')
|
||||||
|
await expect(brTokenOptionXl).toBeVisible();
|
||||||
|
await brTokenOptionXl.click();
|
||||||
|
|
||||||
|
await expect(brTokenPillSM).not.toBeVisible();
|
||||||
|
const brTokenPillXL = borderRadiusSection.getByRole('button', { name: 'borderRadius.xl' });
|
||||||
|
await expect(brTokenPillXL).toBeVisible();
|
||||||
|
|
||||||
|
// Detach token from design tab on right sidebar
|
||||||
|
const detachButton = borderRadiusSection.getByRole('button', { name: 'Detach token' });
|
||||||
|
await detachButton.click();
|
||||||
|
await expect(brTokenPillXL).not.toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
test("User applies typography token to a text shape", async ({ page }) => {
|
test("User applies typography token to a text shape", async ({ page }) => {
|
||||||
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
||||||
await setupTypographyTokensFile(page);
|
await setupTypographyTokensFile(page);
|
||||||
@ -2417,12 +2467,13 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
const nameField = tokensUpdateCreateModal.getByLabel("Name");
|
const nameField = tokensUpdateCreateModal.getByLabel("Name");
|
||||||
await nameField.fill(newTokenTitle);
|
await nameField.fill(newTokenTitle);
|
||||||
|
|
||||||
const referenceTabButton =
|
const referenceTabButton = tokensUpdateCreateModal.getByRole("button", {
|
||||||
tokensUpdateCreateModal.getByRole('button', { name: 'Use a reference' });
|
name: "Use a reference",
|
||||||
|
});
|
||||||
referenceTabButton.click();
|
referenceTabButton.click();
|
||||||
|
|
||||||
const referenceField = tokensUpdateCreateModal.getByRole('textbox', {
|
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {
|
||||||
name: 'Reference'
|
name: "Reference",
|
||||||
});
|
});
|
||||||
await referenceField.fill("{Full}");
|
await referenceField.fill("{Full}");
|
||||||
|
|
||||||
@ -2782,14 +2833,18 @@ test.describe("Tokens: Remapping Feature", () => {
|
|||||||
.click();
|
.click();
|
||||||
await expect(tokensUpdateCreateModal).toBeVisible();
|
await expect(tokensUpdateCreateModal).toBeVisible();
|
||||||
|
|
||||||
nameField = tokensUpdateCreateModal.getByRole("textbox", {name: "Name"});
|
nameField = tokensUpdateCreateModal.getByRole("textbox", {
|
||||||
|
name: "Name",
|
||||||
|
});
|
||||||
await nameField.fill("derived-shadow");
|
await nameField.fill("derived-shadow");
|
||||||
|
|
||||||
const referenceToggle =
|
const referenceToggle =
|
||||||
tokensUpdateCreateModal.getByTestId("reference-opt");
|
tokensUpdateCreateModal.getByTestId("reference-opt");
|
||||||
await referenceToggle.click();
|
await referenceToggle.click();
|
||||||
|
|
||||||
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {name: "Reference"});
|
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {
|
||||||
|
name: "Reference",
|
||||||
|
});
|
||||||
await referenceField.fill("{base-shadow}");
|
await referenceField.fill("{base-shadow}");
|
||||||
|
|
||||||
submitButton = tokensUpdateCreateModal.getByRole("button", {
|
submitButton = tokensUpdateCreateModal.getByRole("button", {
|
||||||
@ -2878,7 +2933,9 @@ test.describe("Tokens: Remapping Feature", () => {
|
|||||||
tokensUpdateCreateModal.getByTestId("reference-opt");
|
tokensUpdateCreateModal.getByTestId("reference-opt");
|
||||||
await referenceToggle.click();
|
await referenceToggle.click();
|
||||||
|
|
||||||
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {name: "Reference"});
|
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {
|
||||||
|
name: "Reference",
|
||||||
|
});
|
||||||
await referenceField.fill("{primary-shadow}");
|
await referenceField.fill("{primary-shadow}");
|
||||||
|
|
||||||
submitButton = tokensUpdateCreateModal.getByRole("button", {
|
submitButton = tokensUpdateCreateModal.getByRole("button", {
|
||||||
@ -2950,7 +3007,8 @@ test.describe("Tokens: Remapping Feature", () => {
|
|||||||
|
|
||||||
// Verify the shape still has the shadow applied with the UPDATED color value
|
// Verify the shape still has the shadow applied with the UPDATED color value
|
||||||
// Expand the shadow section to access the color field
|
// Expand the shadow section to access the color field
|
||||||
const shadowSection = workspacePage.rightSidebar.getByTestId("shadow-section");
|
const shadowSection =
|
||||||
|
workspacePage.rightSidebar.getByTestId("shadow-section");
|
||||||
await expect(shadowSection).toBeVisible();
|
await expect(shadowSection).toBeVisible();
|
||||||
|
|
||||||
// Click to expand the shadow options (the menu button)
|
// Click to expand the shadow options (the menu button)
|
||||||
@ -3008,14 +3066,18 @@ test.describe("Tokens: Remapping Feature", () => {
|
|||||||
.click();
|
.click();
|
||||||
await expect(tokensUpdateCreateModal).toBeVisible();
|
await expect(tokensUpdateCreateModal).toBeVisible();
|
||||||
|
|
||||||
nameField = tokensUpdateCreateModal.getByRole("textbox", {name: "Name"});
|
nameField = tokensUpdateCreateModal.getByRole("textbox", {
|
||||||
|
name: "Name",
|
||||||
|
});
|
||||||
await nameField.fill("body-text");
|
await nameField.fill("body-text");
|
||||||
|
|
||||||
const referenceToggle =
|
const referenceToggle =
|
||||||
tokensUpdateCreateModal.getByTestId("reference-opt");
|
tokensUpdateCreateModal.getByTestId("reference-opt");
|
||||||
await referenceToggle.click();
|
await referenceToggle.click();
|
||||||
|
|
||||||
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {name: "Reference"})
|
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {
|
||||||
|
name: "Reference",
|
||||||
|
});
|
||||||
await referenceField.fill("{base-text}");
|
await referenceField.fill("{base-text}");
|
||||||
|
|
||||||
submitButton = tokensUpdateCreateModal.getByRole("button", {
|
submitButton = tokensUpdateCreateModal.getByRole("button", {
|
||||||
@ -3096,14 +3158,18 @@ test.describe("Tokens: Remapping Feature", () => {
|
|||||||
.click();
|
.click();
|
||||||
await expect(tokensUpdateCreateModal).toBeVisible();
|
await expect(tokensUpdateCreateModal).toBeVisible();
|
||||||
|
|
||||||
nameField = tokensUpdateCreateModal.getByRole("textbox", {name: "Name"});
|
nameField = tokensUpdateCreateModal.getByRole("textbox", {
|
||||||
|
name: "Name",
|
||||||
|
});
|
||||||
await nameField.fill("paragraph-style");
|
await nameField.fill("paragraph-style");
|
||||||
|
|
||||||
const referenceToggle =
|
const referenceToggle =
|
||||||
tokensUpdateCreateModal.getByTestId("reference-opt");
|
tokensUpdateCreateModal.getByTestId("reference-opt");
|
||||||
await referenceToggle.click();
|
await referenceToggle.click();
|
||||||
|
|
||||||
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {name: "Reference"});
|
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {
|
||||||
|
name: "Reference",
|
||||||
|
});
|
||||||
await referenceField.fill("{body-style}");
|
await referenceField.fill("{body-style}");
|
||||||
|
|
||||||
submitButton = tokensUpdateCreateModal.getByRole("button", {
|
submitButton = tokensUpdateCreateModal.getByRole("button", {
|
||||||
|
|||||||
@ -633,6 +633,43 @@
|
|||||||
:shape-ids shape-ids
|
:shape-ids shape-ids
|
||||||
:on-update-shape on-update-shape}))))))))
|
:on-update-shape on-update-shape}))))))))
|
||||||
|
|
||||||
|
(defn toggle-border-radius-token
|
||||||
|
[{:keys [token attrs shape-ids expand-with-children]}]
|
||||||
|
(ptk/reify ::on-toggle-border-radius-token
|
||||||
|
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 all-attributes]}
|
||||||
|
(get token-properties (:type token))
|
||||||
|
|
||||||
|
unapply-tokens?
|
||||||
|
(cft/shapes-token-applied? token shapes (or attrs all-attributes attributes))
|
||||||
|
|
||||||
|
shape-ids (map :id shapes)]
|
||||||
|
|
||||||
|
(if unapply-tokens?
|
||||||
|
(rx/of
|
||||||
|
(unapply-token {:attributes (or attrs all-attributes attributes)
|
||||||
|
:token token
|
||||||
|
:shape-ids shape-ids}))
|
||||||
|
(rx/of
|
||||||
|
(apply-token {:attributes attrs
|
||||||
|
:token token
|
||||||
|
:shape-ids shape-ids
|
||||||
|
:on-update-shape update-shape-radius-for-corners})))))))
|
||||||
|
|
||||||
|
|
||||||
(defn apply-token-on-selected
|
(defn apply-token-on-selected
|
||||||
[color-operations token]
|
[color-operations token]
|
||||||
|
|||||||
@ -183,6 +183,7 @@
|
|||||||
[:map
|
[:map
|
||||||
[:id {:optional true} :string]
|
[:id {:optional true} :string]
|
||||||
[:class {:optional true} :string]
|
[:class {:optional true} :string]
|
||||||
|
[:inner-class {:optional true} :string]
|
||||||
[:value {:optional true} [:maybe [:or
|
[:value {:optional true} [:maybe [:or
|
||||||
:int
|
:int
|
||||||
:float
|
:float
|
||||||
@ -209,7 +210,8 @@
|
|||||||
|
|
||||||
(mf/defc numeric-input*
|
(mf/defc numeric-input*
|
||||||
{::mf/schema schema:numeric-input}
|
{::mf/schema schema:numeric-input}
|
||||||
[{:keys [id class value default placeholder icon disabled
|
[{:keys [id class value default placeholder
|
||||||
|
icon disabled inner-class
|
||||||
min max max-length step
|
min max max-length step
|
||||||
is-selected-on-focus nillable
|
is-selected-on-focus nillable
|
||||||
tokens applied-token empty-to-end
|
tokens applied-token empty-to-end
|
||||||
@ -624,6 +626,7 @@
|
|||||||
(mf/spread-props props {:ref ref
|
(mf/spread-props props {:ref ref
|
||||||
:type "text"
|
:type "text"
|
||||||
:id id
|
:id id
|
||||||
|
:class inner-class
|
||||||
:placeholder (if is-multiple?
|
:placeholder (if is-multiple?
|
||||||
(tr "labels.mixed-values")
|
(tr "labels.mixed-values")
|
||||||
placeholder)
|
placeholder)
|
||||||
@ -644,7 +647,7 @@
|
|||||||
:class (stl/css :icon)}]]))
|
:class (stl/css :icon)}]]))
|
||||||
:slot-end (when-not disabled
|
:slot-end (when-not disabled
|
||||||
(when (some? tokens)
|
(when (some? tokens)
|
||||||
(mf/html [:> icon-button* {:variant "action"
|
(mf/html [:> icon-button* {:variant "ghost"
|
||||||
:icon i/tokens
|
:icon i/tokens
|
||||||
:class (stl/css :invisible-button)
|
:class (stl/css :invisible-button)
|
||||||
:aria-label (tr "ds.inputs.numeric-input.open-token-list-dropdown")
|
:aria-label (tr "ds.inputs.numeric-input.open-token-list-dropdown")
|
||||||
@ -669,6 +672,7 @@
|
|||||||
:on-token-key-down on-token-key-down
|
:on-token-key-down on-token-key-down
|
||||||
:disabled disabled
|
:disabled disabled
|
||||||
:on-blur on-blur
|
:on-blur on-blur
|
||||||
|
:class inner-class
|
||||||
:slot-start (when icon
|
:slot-start (when icon
|
||||||
(mf/html [:> tooltip*
|
(mf/html [:> tooltip*
|
||||||
{:content property
|
{:content property
|
||||||
|
|||||||
@ -33,12 +33,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.invisible-button {
|
.invisible-button {
|
||||||
|
position: absolute;
|
||||||
|
inset-inline-end: 0;
|
||||||
|
inset-block-start: 0;
|
||||||
opacity: var(--opacity-button);
|
opacity: var(--opacity-button);
|
||||||
|
background-color: var(--color-background-quaternary);
|
||||||
&:hover {
|
&:hover {
|
||||||
|
background-color: var(--color-background-quaternary);
|
||||||
--opacity-button: 1;
|
--opacity-button: 1;
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
|
background-color: var(--color-background-quaternary);
|
||||||
--opacity-button: 1;
|
--opacity-button: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
[:map
|
[:map
|
||||||
[:id {:optional true} :string]
|
[:id {:optional true} :string]
|
||||||
[:resolved-value {:optional true}
|
[:resolved-value {:optional true}
|
||||||
[:or :int :string]]
|
[:or :int :string :float]]
|
||||||
[:name {:optional true} :string]
|
[:name {:optional true} :string]
|
||||||
[:icon {:optional true} schema:icon-list]
|
[:icon {:optional true} schema:icon-list]
|
||||||
[:label {:optional true} :string]
|
[:label {:optional true} :string]
|
||||||
|
|||||||
@ -30,11 +30,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.left-align {
|
.left-align {
|
||||||
left: 0;
|
left: var(--dropdown-offset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-align {
|
.right-align {
|
||||||
right: 0;
|
right: var(--dropdown-offset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-separator {
|
.option-separator {
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
[:map
|
[:map
|
||||||
[:id {:optiona true} :string]
|
[:id {:optiona true} :string]
|
||||||
[:ref some?]
|
[:ref some?]
|
||||||
[:resolved {:optional true} [:or :int :string]]
|
[:resolved {:optional true} [:or :int :string :float]]
|
||||||
[:name {:optional true} :string]
|
[:name {:optional true} :string]
|
||||||
[:on-click {:optional true} fn?]
|
[:on-click {:optional true} fn?]
|
||||||
[:selected {:optional true} :boolean]
|
[:selected {:optional true} :boolean]
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
(def ^:private schema:input-field
|
(def ^:private schema:input-field
|
||||||
[:map
|
[:map
|
||||||
[:class {:optional true} :string]
|
[:class {:optional true} [:maybe :string]]
|
||||||
[:aria-label {:optional true} [:maybe :string]]
|
[:aria-label {:optional true} [:maybe :string]]
|
||||||
[:id :string]
|
[:id :string]
|
||||||
[:icon {:optional true}
|
[:icon {:optional true}
|
||||||
@ -44,9 +44,10 @@
|
|||||||
tooltip-id (mf/use-id)
|
tooltip-id (mf/use-id)
|
||||||
|
|
||||||
props (mf/spread-props props
|
props (mf/spread-props props
|
||||||
{:class (stl/css-case
|
{:class [class
|
||||||
:input true
|
(stl/css-case
|
||||||
:input-with-icon (some? icon))
|
:input true
|
||||||
|
:input-with-icon (some? icon))]
|
||||||
:ref (or ref input-ref)
|
:ref (or ref input-ref)
|
||||||
:aria-invalid (when (and has-hint
|
:aria-invalid (when (and has-hint
|
||||||
(= hint-type "error"))
|
(= hint-type "error"))
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
(def ^:private schema:token-field
|
(def ^:private schema:token-field
|
||||||
[:map
|
[:map
|
||||||
|
[:class {:optional true} [:maybe :string]]
|
||||||
[:id {:optional true} [:maybe :string]]
|
[:id {:optional true} [:maybe :string]]
|
||||||
[:label {:optional true} [:maybe :string]]
|
[:label {:optional true} [:maybe :string]]
|
||||||
[:value :any]
|
[:value :any]
|
||||||
@ -32,7 +33,7 @@
|
|||||||
|
|
||||||
(mf/defc token-field*
|
(mf/defc token-field*
|
||||||
{::mf/schema schema:token-field}
|
{::mf/schema schema:token-field}
|
||||||
[{:keys [id label value slot-start disabled
|
[{: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
|
||||||
token-wrapper-ref token-detach-btn-ref on-focus]}]
|
token-wrapper-ref token-detach-btn-ref on-focus]}]
|
||||||
(let [set-active? (some? id)
|
(let [set-active? (some? id)
|
||||||
@ -48,14 +49,11 @@
|
|||||||
(fn [event]
|
(fn [event]
|
||||||
(when-not ^boolean disabled
|
(when-not ^boolean disabled
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(dom/focus! (mf/ref-val token-wrapper-ref)))))
|
(dom/focus! (mf/ref-val token-wrapper-ref)))))]
|
||||||
|
|
||||||
class
|
[:div {:class [class (stl/css-case :token-field true
|
||||||
(stl/css-case :token-field true
|
:with-icon (some? slot-start)
|
||||||
:with-icon (some? slot-start)
|
:token-field-disabled disabled)]
|
||||||
:token-field-disabled disabled)]
|
|
||||||
|
|
||||||
[:div {:class class
|
|
||||||
:on-click focus-wrapper
|
:on-click focus-wrapper
|
||||||
:disabled disabled
|
:disabled disabled
|
||||||
:on-key-down on-token-key-down
|
:on-key-down on-token-key-down
|
||||||
@ -80,7 +78,7 @@
|
|||||||
[:div {:class (stl/css :pill-dot)}])]]
|
[:div {:class (stl/css :pill-dot)}])]]
|
||||||
|
|
||||||
(when-not ^boolean disabled
|
(when-not ^boolean disabled
|
||||||
[:> icon-button* {:variant "action"
|
[:> icon-button* {:variant "ghost"
|
||||||
:class (stl/css :invisible-button)
|
:class (stl/css :invisible-button)
|
||||||
:icon i/broken-link
|
:icon i/broken-link
|
||||||
:ref token-detach-btn-ref
|
:ref token-detach-btn-ref
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
@use "ds/_sizes.scss" as *;
|
@use "ds/_sizes.scss" as *;
|
||||||
@use "ds/typography.scss" as t;
|
@use "ds/typography.scss" as t;
|
||||||
@use "ds/colors.scss" as *;
|
@use "ds/colors.scss" as *;
|
||||||
|
@use "ds/mixins.scss" as *;
|
||||||
|
|
||||||
.token-field {
|
.token-field {
|
||||||
--token-field-bg-color: var(--color-background-tertiary);
|
--token-field-bg-color: var(--color-background-tertiary);
|
||||||
@ -16,9 +17,7 @@
|
|||||||
--token-field-outline-color: none;
|
--token-field-outline-color: none;
|
||||||
--token-field-height: var(--sp-xxxl);
|
--token-field-height: var(--sp-xxxl);
|
||||||
--token-field-margin: unset;
|
--token-field-margin: unset;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr auto;
|
|
||||||
column-gap: var(--sp-xs);
|
column-gap: var(--sp-xs);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -27,6 +26,7 @@
|
|||||||
border-radius: $br-8;
|
border-radius: $br-8;
|
||||||
padding: var(--sp-xs);
|
padding: var(--sp-xs);
|
||||||
outline: $b-1 solid var(--token-field-outline-color);
|
outline: $b-1 solid var(--token-field-outline-color);
|
||||||
|
position: relative;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
--token-field-bg-color: var(--color-background-quaternary);
|
--token-field-bg-color: var(--color-background-quaternary);
|
||||||
@ -39,7 +39,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.with-icon {
|
.with-icon {
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template-columns: auto 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.token-field-disabled {
|
.token-field-disabled {
|
||||||
@ -57,14 +57,17 @@
|
|||||||
--pill-bg-color: var(--color-background-tertiary);
|
--pill-bg-color: var(--color-background-tertiary);
|
||||||
--pill-fg-color: var(--color-token-foreground);
|
--pill-fg-color: var(--color-token-foreground);
|
||||||
@include t.use-typography("code-font");
|
@include t.use-typography("code-font");
|
||||||
height: var(--sp-xxl);
|
@include textEllipsis;
|
||||||
width: fit-content;
|
display: block;
|
||||||
|
block-size: var(--sp-xxl);
|
||||||
|
inline-size: fit-content;
|
||||||
background: var(--pill-bg-color);
|
background: var(--pill-bg-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: $b-1 solid var(--pill-border-color);
|
border: $b-1 solid var(--pill-border-color);
|
||||||
color: var(--pill-fg-color);
|
color: var(--pill-fg-color);
|
||||||
border-radius: $br-6;
|
border-radius: $br-6;
|
||||||
padding-inline: $sz-6;
|
padding-inline: $sz-6;
|
||||||
|
max-inline-size: 100%;
|
||||||
&:hover {
|
&:hover {
|
||||||
--pill-bg-color: var(--color-token-background);
|
--pill-bg-color: var(--color-token-background);
|
||||||
--pill-fg-color: var(--color-foreground-primary);
|
--pill-fg-color: var(--color-foreground-primary);
|
||||||
@ -103,24 +106,29 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.pill-dot {
|
.pill-dot {
|
||||||
width: $sz-6;
|
inline-size: $sz-6;
|
||||||
height: $sz-6;
|
block-size: $sz-6;
|
||||||
outline: var(--sp-xxs) solid var(--color-background-primary);
|
outline: var(--sp-xxs) solid var(--color-background-primary);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: var(--color-foreground-error);
|
background-color: var(--color-foreground-error);
|
||||||
margin-left: var(--sp-xs);
|
margin-inline-start: var(--sp-xs);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
inset-inline-end: 0;
|
||||||
top: 0;
|
inset-block-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invisible-button {
|
.invisible-button {
|
||||||
|
position: absolute;
|
||||||
|
inset-inline-end: 0;
|
||||||
|
inset-block-start: 0;
|
||||||
opacity: var(--opacity-button);
|
opacity: var(--opacity-button);
|
||||||
|
background-color: var(--color-background-quaternary);
|
||||||
&:hover {
|
&:hover {
|
||||||
|
background-color: var(--color-background-quaternary);
|
||||||
--opacity-button: 1;
|
--opacity-button: 1;
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
|
background-color: var(--color-background-quaternary);
|
||||||
--opacity-button: 1;
|
--opacity-button: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -159,4 +159,6 @@ $arrow-side: 12px;
|
|||||||
block-size: fit-content;
|
block-size: fit-content;
|
||||||
inline-size: fit-content;
|
inline-size: fit-content;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
|
display: grid;
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,10 +3,15 @@
|
|||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.types.shape.radius :as ctsr]
|
[app.common.types.shape.radius :as ctsr]
|
||||||
|
[app.common.types.token :as tk]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
|
[app.main.data.workspace.tokens.application :as dwta]
|
||||||
|
[app.main.features :as features]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.numeric-input :as deprecated-input]
|
[app.main.ui.components.numeric-input :as deprecated-input]
|
||||||
|
[app.main.ui.context :as muc]
|
||||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||||
|
[app.main.ui.ds.controls.numeric-input :refer [numeric-input*]]
|
||||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
||||||
[app.main.ui.hooks :as hooks]
|
[app.main.ui.hooks :as hooks]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
@ -21,11 +26,17 @@
|
|||||||
(defn- check-border-radius-menu-props
|
(defn- check-border-radius-menu-props
|
||||||
[old-props new-props]
|
[old-props new-props]
|
||||||
(let [old-values (unchecked-get old-props "values")
|
(let [old-values (unchecked-get old-props "values")
|
||||||
new-values (unchecked-get new-props "values")]
|
new-values (unchecked-get new-props "values")
|
||||||
|
old-applied-tokens (unchecked-get old-props "appliedTokens")
|
||||||
|
new-applied-tokens (unchecked-get new-props "appliedTokens")]
|
||||||
(and (identical? (unchecked-get old-props "class")
|
(and (identical? (unchecked-get old-props "class")
|
||||||
(unchecked-get new-props "class"))
|
(unchecked-get new-props "class"))
|
||||||
(identical? (unchecked-get old-props "ids")
|
(identical? (unchecked-get old-props "ids")
|
||||||
(unchecked-get new-props "ids"))
|
(unchecked-get new-props "ids"))
|
||||||
|
(identical? (unchecked-get old-props "shapes")
|
||||||
|
(unchecked-get new-props "shapes"))
|
||||||
|
(identical? old-applied-tokens
|
||||||
|
new-applied-tokens)
|
||||||
(identical? (get old-values :r1)
|
(identical? (get old-values :r1)
|
||||||
(get new-values :r1))
|
(get new-values :r1))
|
||||||
(identical? (get old-values :r2)
|
(identical? (get old-values :r2)
|
||||||
@ -35,13 +46,114 @@
|
|||||||
(identical? (get old-values :r4)
|
(identical? (get old-values :r4)
|
||||||
(get new-values :r4)))))
|
(get new-values :r4)))))
|
||||||
|
|
||||||
|
(mf/defc numeric-input-wrapper*
|
||||||
|
{::mf/private true}
|
||||||
|
[{:keys [values name applied-tokens align on-detach radius] :rest props}]
|
||||||
|
(let [tokens (mf/use-ctx muc/active-tokens-by-type)
|
||||||
|
tokens (mf/with-memo [tokens name]
|
||||||
|
(delay
|
||||||
|
(-> (deref tokens)
|
||||||
|
(select-keys (get tk/tokens-by-input name))
|
||||||
|
(not-empty))))
|
||||||
|
|
||||||
|
on-detach-attr
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps on-detach name)
|
||||||
|
#(on-detach % name))
|
||||||
|
|
||||||
|
r1-value (get applied-tokens :r1)
|
||||||
|
all-token-equal? (and (seq applied-tokens) (all-equal? applied-tokens))
|
||||||
|
all-values-equal? (all-equal? values)
|
||||||
|
|
||||||
|
applied-token (cond
|
||||||
|
(not (seq applied-tokens))
|
||||||
|
nil
|
||||||
|
|
||||||
|
(and (= radius :all) (or (not all-values-equal?) (not all-token-equal?)))
|
||||||
|
:multiple
|
||||||
|
|
||||||
|
(and all-token-equal? all-values-equal? (= radius :all))
|
||||||
|
r1-value
|
||||||
|
|
||||||
|
:else
|
||||||
|
(get applied-tokens radius))
|
||||||
|
|
||||||
|
|
||||||
|
placeholder (if (= radius :all)
|
||||||
|
(cond
|
||||||
|
(or (not all-values-equal?)
|
||||||
|
(not all-token-equal?))
|
||||||
|
(tr "settings.multiple")
|
||||||
|
:else
|
||||||
|
"--")
|
||||||
|
|
||||||
|
(cond
|
||||||
|
(or (= :multiple (:applied-tokens values))
|
||||||
|
(= :multiple (get values name)))
|
||||||
|
(tr "settings.multiple")
|
||||||
|
:else
|
||||||
|
"--"))
|
||||||
|
|
||||||
|
|
||||||
|
props (mf/spread-props props
|
||||||
|
{:placeholder placeholder
|
||||||
|
:applied-token applied-token
|
||||||
|
:tokens (if (delay? tokens) @tokens tokens)
|
||||||
|
:align align
|
||||||
|
:on-detach on-detach-attr
|
||||||
|
:value values})]
|
||||||
|
[:> numeric-input* props]))
|
||||||
|
|
||||||
(mf/defc border-radius-menu*
|
(mf/defc border-radius-menu*
|
||||||
{::mf/wrap [#(mf/memo' % check-border-radius-menu-props)]}
|
{::mf/wrap [#(mf/memo' % check-border-radius-menu-props)]}
|
||||||
[{:keys [class ids values]}]
|
[{:keys [class ids values applied-tokens]}]
|
||||||
(let [all-equal? (all-equal? values)
|
(let [token-numeric-inputs
|
||||||
|
(features/use-feature "tokens/numeric-input")
|
||||||
|
|
||||||
|
all-values-equal? (all-equal? values)
|
||||||
|
|
||||||
radius-expanded* (mf/use-state false)
|
radius-expanded* (mf/use-state false)
|
||||||
radius-expanded (deref radius-expanded*)
|
radius-expanded (deref radius-expanded*)
|
||||||
|
|
||||||
|
;; DETACH
|
||||||
|
on-detach-token
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps ids)
|
||||||
|
(fn [token attr]
|
||||||
|
(st/emit! (dwta/unapply-token {:token (first token)
|
||||||
|
:attributes #{attr}
|
||||||
|
:shape-ids ids}))))
|
||||||
|
|
||||||
|
on-detach-all
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps on-detach-token)
|
||||||
|
(fn [token]
|
||||||
|
(run! #(on-detach-token token %) [:r1 :r2 :r3 :r4])))
|
||||||
|
|
||||||
|
on-detach-r1
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps on-detach-token)
|
||||||
|
(fn [token]
|
||||||
|
(on-detach-token token :r1)))
|
||||||
|
|
||||||
|
on-detach-r2
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps on-detach-token)
|
||||||
|
(fn [token]
|
||||||
|
(on-detach-token token :r2)))
|
||||||
|
|
||||||
|
on-detach-r3
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps on-detach-token)
|
||||||
|
(fn [token]
|
||||||
|
(on-detach-token token :r3)))
|
||||||
|
|
||||||
|
on-detach-r4
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps on-detach-token)
|
||||||
|
(fn [token]
|
||||||
|
(on-detach-token token :r4)))
|
||||||
|
|
||||||
change-radius
|
change-radius
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps ids)
|
(mf/deps ids)
|
||||||
@ -54,31 +166,54 @@
|
|||||||
{:reg-objects? true
|
{:reg-objects? true
|
||||||
:attrs [:r1 :r2 :r3 :r4]})))
|
:attrs [:r1 :r2 :r3 :r4]})))
|
||||||
|
|
||||||
|
change-one-radius
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps ids)
|
||||||
|
(fn [update-fn attr]
|
||||||
|
(dwsh/update-shapes ids
|
||||||
|
(fn [shape]
|
||||||
|
(if (ctsr/has-radius? shape)
|
||||||
|
(update-fn shape)
|
||||||
|
shape))
|
||||||
|
{:reg-objects? true
|
||||||
|
:attrs [attr]})))
|
||||||
|
|
||||||
toggle-radius-mode
|
toggle-radius-mode
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps radius-expanded)
|
(mf/deps radius-expanded)
|
||||||
(fn []
|
(fn []
|
||||||
(swap! radius-expanded* not)))
|
(swap! radius-expanded* not)))
|
||||||
|
|
||||||
|
|
||||||
|
on-all-radius-change
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps change-radius ids)
|
||||||
|
(fn [value]
|
||||||
|
(if (or (string? value) (number? value))
|
||||||
|
(st/emit!
|
||||||
|
(change-radius (fn [shape]
|
||||||
|
(ctsr/set-radius-to-all-corners shape value))))
|
||||||
|
(doseq [attr [:r1 :r2 :r3 :r4]]
|
||||||
|
(st/emit!
|
||||||
|
(dwta/toggle-token {:token (first value)
|
||||||
|
:attrs #{attr}
|
||||||
|
:shape-ids ids}))))))
|
||||||
|
|
||||||
|
|
||||||
on-single-radius-change
|
on-single-radius-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps ids change-radius)
|
(mf/deps change-one-radius ids)
|
||||||
(fn [value]
|
|
||||||
(st/emit!
|
|
||||||
(change-radius (fn [shape]
|
|
||||||
(ctsr/set-radius-to-all-corners shape value))))))
|
|
||||||
|
|
||||||
|
|
||||||
on-radius-4-change
|
|
||||||
(mf/use-fn
|
|
||||||
(mf/deps ids change-radius)
|
|
||||||
(fn [value attr]
|
(fn [value attr]
|
||||||
(st/emit! (change-radius #(ctsr/set-radius-to-single-corner % attr value)))))
|
(if (or (string? value) (number? value))
|
||||||
|
(st/emit! (change-one-radius #(ctsr/set-radius-to-single-corner % attr value) attr))
|
||||||
|
(st/emit! (dwta/toggle-border-radius-token {:token (first value)
|
||||||
|
:attrs #{attr}
|
||||||
|
:shape-ids ids})))))
|
||||||
|
|
||||||
on-radius-r1-change #(on-radius-4-change % :r1)
|
on-radius-r1-change #(on-single-radius-change % :r1)
|
||||||
on-radius-r2-change #(on-radius-4-change % :r2)
|
on-radius-r2-change #(on-single-radius-change % :r2)
|
||||||
on-radius-r3-change #(on-radius-4-change % :r3)
|
on-radius-r3-change #(on-single-radius-change % :r3)
|
||||||
on-radius-r4-change #(on-radius-4-change % :r4)
|
on-radius-r4-change #(on-single-radius-change % :r4)
|
||||||
|
|
||||||
expand-stream
|
expand-stream
|
||||||
(mf/with-memo []
|
(mf/with-memo []
|
||||||
@ -92,58 +227,139 @@
|
|||||||
(mf/with-effect [ids]
|
(mf/with-effect [ids]
|
||||||
(reset! radius-expanded* false))
|
(reset! radius-expanded* false))
|
||||||
|
|
||||||
[:div {:class (dm/str class " " (stl/css :radius))}
|
[:section {:class (dm/str class " " (stl/css :radius))
|
||||||
|
:aria-label "border-radius-section"}
|
||||||
(if (not radius-expanded)
|
(if (not radius-expanded)
|
||||||
[:div {:class (stl/css :radius-1)
|
(if token-numeric-inputs
|
||||||
:title (tr "workspace.options.radius")}
|
[:> numeric-input-wrapper*
|
||||||
[:> icon* {:icon-id i/corner-radius
|
{:on-change on-all-radius-change
|
||||||
:size "s"
|
:on-detach on-detach-all
|
||||||
:class (stl/css :icon)}]
|
:icon i/corner-radius
|
||||||
[:> deprecated-input/numeric-input*
|
|
||||||
{:placeholder (cond
|
|
||||||
(not all-equal?)
|
|
||||||
(tr "settings.multiple")
|
|
||||||
(= :multiple (:r1 values))
|
|
||||||
(tr "settings.multiple")
|
|
||||||
:else
|
|
||||||
"--")
|
|
||||||
:min 0
|
|
||||||
:nillable true
|
|
||||||
:on-change on-single-radius-change
|
|
||||||
:value (if all-equal? (:r1 values) nil)}]]
|
|
||||||
|
|
||||||
[:div {:class (stl/css :radius-4)}
|
|
||||||
[:div {:class (stl/css :small-input)}
|
|
||||||
[:> deprecated-input/numeric-input*
|
|
||||||
{:placeholder "--"
|
|
||||||
:title (tr "workspace.options.radius-top-left")
|
|
||||||
:min 0
|
:min 0
|
||||||
:on-change on-radius-r1-change
|
:name :border-radius
|
||||||
:value (:r1 values)}]]
|
:nillable true
|
||||||
|
:property (tr "workspace.options.radius")
|
||||||
|
:class (stl/css :radius-wrapper)
|
||||||
|
:applied-tokens applied-tokens
|
||||||
|
:radius :all
|
||||||
|
:align :right
|
||||||
|
:values (if all-values-equal?
|
||||||
|
(if (nil? (:r1 values))
|
||||||
|
0
|
||||||
|
(:r1 values))
|
||||||
|
nil)}]
|
||||||
|
|
||||||
[:div {:class (stl/css :small-input)}
|
[:div {:class (stl/css :radius-1)
|
||||||
[:> deprecated-input/numeric-input*
|
:title (tr "workspace.options.radius")}
|
||||||
{:placeholder "--"
|
[:> icon* {:icon-id i/corner-radius
|
||||||
:title (tr "workspace.options.radius-top-right")
|
:size "s"
|
||||||
:min 0
|
:class (stl/css :icon)}]
|
||||||
:on-change on-radius-r2-change
|
[:> deprecated-input/numeric-input*
|
||||||
:value (:r2 values)}]]
|
{: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 :small-input)}
|
(if token-numeric-inputs
|
||||||
[:> deprecated-input/numeric-input*
|
[:div {:class (stl/css :radius-4)}
|
||||||
{:placeholder "--"
|
[:> numeric-input-wrapper*
|
||||||
:title (tr "workspace.options.radius-bottom-left")
|
{:on-change on-radius-r1-change
|
||||||
:min 0
|
:on-detach on-detach-r1
|
||||||
:on-change on-radius-r4-change
|
:min 0
|
||||||
:value (:r4 values)}]]
|
:name :border-radius
|
||||||
|
:property (tr "workspace.options.radius-top-left")
|
||||||
|
:applied-tokens applied-tokens
|
||||||
|
:radius :r1
|
||||||
|
:align :right
|
||||||
|
:class (stl/css :radius-wrapper :dropdown-offset)
|
||||||
|
:inner-class (stl/css :no-icon-input)
|
||||||
|
:values (:r1 values)}]
|
||||||
|
|
||||||
[:div {:class (stl/css :small-input)}
|
[:> numeric-input-wrapper*
|
||||||
[:> deprecated-input/numeric-input*
|
{:on-change on-radius-r2-change
|
||||||
{:placeholder "--"
|
:on-detach on-detach-r2
|
||||||
:title (tr "workspace.options.radius-bottom-right")
|
:min 0
|
||||||
:min 0
|
:name :border-radius
|
||||||
:on-change on-radius-r3-change
|
:nillable true
|
||||||
:value (:r3 values)}]]])
|
:property (tr "workspace.options.radius-top-right")
|
||||||
|
:applied-tokens applied-tokens
|
||||||
|
:align :right
|
||||||
|
:class (stl/css :radius-wrapper)
|
||||||
|
:inner-class (stl/css :no-icon-input)
|
||||||
|
:radius :r2
|
||||||
|
:values (:r2 values)}]
|
||||||
|
|
||||||
|
[:> numeric-input-wrapper*
|
||||||
|
{:on-change on-radius-r4-change
|
||||||
|
:on-detach on-detach-r4
|
||||||
|
:min 0
|
||||||
|
:name :border-radius
|
||||||
|
:nillable true
|
||||||
|
:property (tr "workspace.options.radius-bottom-left")
|
||||||
|
:applied-tokens applied-tokens
|
||||||
|
:class (stl/css :radius-wrapper :dropdown-offset)
|
||||||
|
:inner-class (stl/css :no-icon-input)
|
||||||
|
:radius :r4
|
||||||
|
:align :right
|
||||||
|
:values (:r4 values)}]
|
||||||
|
|
||||||
|
[:> numeric-input-wrapper*
|
||||||
|
{:on-change on-radius-r3-change
|
||||||
|
:on-detach on-detach-r3
|
||||||
|
:min 0
|
||||||
|
:name :border-radius
|
||||||
|
:nillable true
|
||||||
|
:property (tr "workspace.options.radius-bottom-right")
|
||||||
|
:applied-tokens applied-tokens
|
||||||
|
:radius :r3
|
||||||
|
:align :right
|
||||||
|
:class (stl/css :radius-wrapper)
|
||||||
|
:inner-class (stl/css :no-icon-input)
|
||||||
|
:values (:r3 values)}]]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :radius-4)}
|
||||||
|
[:div {:class (stl/css :small-input)}
|
||||||
|
[:> deprecated-input/numeric-input*
|
||||||
|
{:placeholder "--"
|
||||||
|
:title (tr "workspace.options.radius-top-left")
|
||||||
|
:min 0
|
||||||
|
:on-change on-radius-r1-change
|
||||||
|
:value (:r1 values)}]]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :small-input)}
|
||||||
|
[:> deprecated-input/numeric-input*
|
||||||
|
{:placeholder "--"
|
||||||
|
:title (tr "workspace.options.radius-top-right")
|
||||||
|
:min 0
|
||||||
|
:on-change on-radius-r2-change
|
||||||
|
:value (:r2 values)}]]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :small-input)}
|
||||||
|
[:> deprecated-input/numeric-input*
|
||||||
|
{:placeholder "--"
|
||||||
|
:title (tr "workspace.options.radius-bottom-left")
|
||||||
|
:min 0
|
||||||
|
:on-change on-radius-r4-change
|
||||||
|
:value (:r4 values)}]]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :small-input)}
|
||||||
|
[:> deprecated-input/numeric-input*
|
||||||
|
{:placeholder "--"
|
||||||
|
:title (tr "workspace.options.radius-bottom-right")
|
||||||
|
:min 0
|
||||||
|
:on-change on-radius-r3-change
|
||||||
|
:value (:r3 values)}]]]))
|
||||||
|
|
||||||
[:> icon-button* {:variant "ghost"
|
[:> icon-button* {:variant "ghost"
|
||||||
:on-click toggle-radius-mode
|
:on-click toggle-radius-mode
|
||||||
|
|||||||
@ -5,6 +5,8 @@
|
|||||||
// Copyright (c) KALEIDOS INC
|
// Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
@use "refactor/common-refactor.scss" as deprecated;
|
@use "refactor/common-refactor.scss" as deprecated;
|
||||||
|
@use "ds/typography" as t;
|
||||||
|
@use "ds/_utils.scss" as *;
|
||||||
|
|
||||||
.radius {
|
.radius {
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -14,7 +16,7 @@
|
|||||||
|
|
||||||
.radius-1 {
|
.radius-1 {
|
||||||
@extend .input-element;
|
@extend .input-element;
|
||||||
@include deprecated.bodySmallTypography;
|
@include t.use-typography("body-small");
|
||||||
}
|
}
|
||||||
|
|
||||||
.radius-4 {
|
.radius-4 {
|
||||||
@ -25,9 +27,27 @@
|
|||||||
|
|
||||||
.small-input {
|
.small-input {
|
||||||
@extend .input-element;
|
@extend .input-element;
|
||||||
@include deprecated.bodySmallTypography;
|
@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);
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
margin-inline: deprecated.$s-4;
|
margin-inline: var(--sp-xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.radius-wrapper {
|
||||||
|
--dropdown-width: var(--7-columns-dropdown-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-icon-input {
|
||||||
|
padding-inline-start: px2rem(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-offset {
|
||||||
|
--dropdown-offset: #{px2rem(-65)};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,7 +78,7 @@
|
|||||||
(nil? (get values name)))
|
(nil? (get values name)))
|
||||||
(tr "settings.multiple")
|
(tr "settings.multiple")
|
||||||
"--")
|
"--")
|
||||||
:class (stl/css :numeric-input-measures)
|
:class (stl/css :numeric-input-layout)
|
||||||
:applied-token (get applied-tokens name)
|
:applied-token (get applied-tokens name)
|
||||||
:tokens tokens
|
:tokens tokens
|
||||||
:align align
|
:align align
|
||||||
|
|||||||
@ -358,6 +358,6 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.numeric-input-measures {
|
.numeric-input-layout {
|
||||||
--dropdown-width: var(--7-columns-dropdown-width);
|
--dropdown-width: var(--7-columns-dropdown-width);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -600,10 +600,7 @@
|
|||||||
[:> border-radius-menu* {:class (stl/css :border-radius)
|
[:> border-radius-menu* {:class (stl/css :border-radius)
|
||||||
:ids ids
|
:ids ids
|
||||||
:values values
|
:values values
|
||||||
:applied-tokens applied-tokens
|
:applied-tokens applied-tokens}])])
|
||||||
:shapes shapes
|
|
||||||
:shape shape}])])
|
|
||||||
|
|
||||||
(when (or (options :clip-content)
|
(when (or (options :clip-content)
|
||||||
(options :show-in-viewer))
|
(options :show-in-viewer))
|
||||||
[:div {:class (stl/css :clip-show)}
|
[:div {:class (stl/css :clip-show)}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
@use "refactor/common-refactor.scss" as deprecated;
|
@use "refactor/common-refactor.scss" as deprecated;
|
||||||
@use "../../../sidebar/common/sidebar.scss" as sidebar;
|
@use "../../../sidebar/common/sidebar.scss" as sidebar;
|
||||||
|
@use "ds/_utils.scss" as *;
|
||||||
|
|
||||||
.element-set {
|
.element-set {
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -156,7 +157,6 @@
|
|||||||
gap: deprecated.$s-4;
|
gap: deprecated.$s-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add a proper variable to this sizing
|
|
||||||
.numeric-input-measures {
|
.numeric-input-measures {
|
||||||
--dropdown-width: var(--7-columns-dropdown-width);
|
--dropdown-width: var(--7-columns-dropdown-width);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -223,7 +223,6 @@
|
|||||||
(cond
|
(cond
|
||||||
(= existing ::not-found) (assoc acc t-attr new-val)
|
(= existing ::not-found) (assoc acc t-attr new-val)
|
||||||
(= existing new-val) acc
|
(= existing new-val) acc
|
||||||
(nil? new-val) acc
|
|
||||||
:else (assoc acc t-attr :multiple))))
|
:else (assoc acc t-attr :multiple))))
|
||||||
|
|
||||||
merge-shape-attr
|
merge-shape-attr
|
||||||
@ -237,10 +236,8 @@
|
|||||||
(fn [acc shape-attrs applied-tokens]
|
(fn [acc shape-attrs applied-tokens]
|
||||||
"Merges token values across all shape attributes.
|
"Merges token values across all shape attributes.
|
||||||
For each shape attribute, its corresponding token attributes are merged
|
For each shape attribute, its corresponding token attributes are merged
|
||||||
into the accumulator. If applied tokens are empty, the accumulator is returned unchanged."
|
into the accumulator."
|
||||||
(if (seq applied-tokens)
|
(reduce #(merge-shape-attr %1 applied-tokens %2) acc shape-attrs))
|
||||||
(reduce #(merge-shape-attr %1 applied-tokens %2) acc shape-attrs)
|
|
||||||
acc))
|
|
||||||
|
|
||||||
extract-attrs
|
extract-attrs
|
||||||
(fn [[ids values token-acc] {:keys [id type applied-tokens] :as shape}]
|
(fn [[ids values token-acc] {:keys [id type applied-tokens] :as shape}]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user