mirror of
https://github.com/penpot/penpot.git
synced 2026-01-20 20:32:22 -05:00
Compare commits
4 Commits
develop
...
eva-replac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd91fc6d9c | ||
|
|
4af0ad17fd | ||
|
|
49eef0771b | ||
|
|
875155e032 |
@@ -474,8 +474,8 @@
|
|||||||
:height #{:sizing :dimensions}
|
:height #{:sizing :dimensions}
|
||||||
:max-width #{:sizing :dimensions}
|
:max-width #{:sizing :dimensions}
|
||||||
:max-height #{:sizing :dimensions}
|
:max-height #{:sizing :dimensions}
|
||||||
:x #{:spacing :dimensions}
|
:x #{:dimensions}
|
||||||
:y #{:spacing :dimensions}
|
:y #{:dimensions}
|
||||||
:rotation #{:number :rotation}
|
:rotation #{:number :rotation}
|
||||||
:border-radius #{:border-radius :dimensions}
|
:border-radius #{:border-radius :dimensions}
|
||||||
:row-gap #{:spacing :dimensions}
|
:row-gap #{:spacing :dimensions}
|
||||||
@@ -488,6 +488,7 @@
|
|||||||
:sided-margins #{:spacing :dimensions}
|
:sided-margins #{:spacing :dimensions}
|
||||||
:line-height #{:line-height :number}
|
:line-height #{:line-height :number}
|
||||||
:opacity #{:opacity}
|
:opacity #{:opacity}
|
||||||
|
:stroke-width #{:stroke-width}
|
||||||
:font-size #{:font-size}
|
:font-size #{:font-size}
|
||||||
:letter-spacing #{:letter-spacing}
|
:letter-spacing #{:letter-spacing}
|
||||||
:fill #{:color}
|
:fill #{:color}
|
||||||
|
|||||||
@@ -149,12 +149,14 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
await detachButton.click();
|
await detachButton.click();
|
||||||
|
|
||||||
// Open dropdown from input
|
// Open dropdown from input
|
||||||
const dropdownBtn = layerMenuSection.getByLabel('Open token list');
|
const dropdownBtn = layerMenuSection.getByLabel("Open token list");
|
||||||
await expect(dropdownBtn).toBeVisible();
|
await expect(dropdownBtn).toBeVisible();
|
||||||
await dropdownBtn.click();
|
await dropdownBtn.click();
|
||||||
|
|
||||||
// Change token from dropdown
|
// Change token from dropdown
|
||||||
const opacityLowOption = layerMenuSection.getByRole('option', { name: 'opacity.low' });
|
const opacityLowOption = layerMenuSection.getByRole("option", {
|
||||||
|
name: "opacity.low",
|
||||||
|
});
|
||||||
await expect(opacityLowOption).toBeVisible();
|
await expect(opacityLowOption).toBeVisible();
|
||||||
await opacityLowOption.click();
|
await opacityLowOption.click();
|
||||||
|
|
||||||
@@ -482,4 +484,219 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
await expect(shadowSection).toHaveCount(2);
|
await expect(shadowSection).toHaveCount(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("User applies dimension token to a shape on width and height", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
||||||
|
await setupTokensFile(page);
|
||||||
|
|
||||||
|
// Unfolds dimensions on token panel
|
||||||
|
await page.getByRole("tab", { name: "Layers" }).click();
|
||||||
|
|
||||||
|
await workspacePage.layers.getByTestId("layer-row").nth(1).click();
|
||||||
|
|
||||||
|
const tokensTabButton = page.getByRole("tab", { name: "Tokens" });
|
||||||
|
await tokensTabButton.click();
|
||||||
|
|
||||||
|
unfoldTokenTree(tokensSidebar, "dimensions", "dimension.dimension.sm");
|
||||||
|
|
||||||
|
// Apply token to width and height token from token panel
|
||||||
|
await tokensSidebar.getByRole("button", { name: "dimension.sm" }).click();
|
||||||
|
|
||||||
|
// Check if measures sections is visible on right sidebar
|
||||||
|
const measuresSection = page.getByRole("region", {
|
||||||
|
name: "shape-measures-section",
|
||||||
|
});
|
||||||
|
await expect(measuresSection).toBeVisible();
|
||||||
|
|
||||||
|
// Check if token pill is visible on design tab on right sidebar
|
||||||
|
const dimensionSMTokenPill = measuresSection.getByRole("button", {
|
||||||
|
name: "dimension.sm",
|
||||||
|
});
|
||||||
|
await expect(dimensionSMTokenPill).toHaveCount(2);
|
||||||
|
await dimensionSMTokenPill.nth(1).click();
|
||||||
|
|
||||||
|
// Change token from dropdown
|
||||||
|
const dimensionTokenOptionXl = measuresSection.getByLabel("dimension.xl");
|
||||||
|
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||||
|
await dimensionTokenOptionXl.click();
|
||||||
|
|
||||||
|
await expect(dimensionSMTokenPill).toHaveCount(1);
|
||||||
|
const dimensionXLTokenPill = measuresSection.getByRole("button", {
|
||||||
|
name: "dimension.xl",
|
||||||
|
});
|
||||||
|
await expect(dimensionXLTokenPill).toBeVisible();
|
||||||
|
|
||||||
|
// Detach token from design tab on right sidebar
|
||||||
|
const detachButton = measuresSection.getByRole("button", {
|
||||||
|
name: "Detach token",
|
||||||
|
});
|
||||||
|
await detachButton.nth(1).click();
|
||||||
|
await expect(dimensionXLTokenPill).not.toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("User applies dimension token to a shape on x position", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
||||||
|
await setupTokensFile(page);
|
||||||
|
|
||||||
|
// Unfolds dimensions on token panel
|
||||||
|
await page.getByRole("tab", { name: "Layers" }).click();
|
||||||
|
|
||||||
|
await workspacePage.layers.getByTestId("layer-row").nth(1).click();
|
||||||
|
|
||||||
|
const tokensTabButton = page.getByRole("tab", { name: "Tokens" });
|
||||||
|
await tokensTabButton.click();
|
||||||
|
|
||||||
|
unfoldTokenTree(tokensSidebar, "dimensions", "dimension.dimension.sm");
|
||||||
|
|
||||||
|
// Apply token to width and height token from token panel
|
||||||
|
await tokensSidebar
|
||||||
|
.getByRole("button", { name: "dimension.sm" })
|
||||||
|
.click({ button: "right" });
|
||||||
|
await tokenContextMenuForToken.getByText("AxisX").click();
|
||||||
|
|
||||||
|
// Check if measures sections is visible on right sidebar
|
||||||
|
const measuresSection = page.getByRole("region", {
|
||||||
|
name: "shape-measures-section",
|
||||||
|
});
|
||||||
|
await expect(measuresSection).toBeVisible();
|
||||||
|
|
||||||
|
// Check if token pill is visible on design tab on right sidebar
|
||||||
|
const dimensionSMTokenPill = measuresSection.getByRole("button", {
|
||||||
|
name: "dimension.sm",
|
||||||
|
});
|
||||||
|
await expect(dimensionSMTokenPill).toBeVisible();
|
||||||
|
await dimensionSMTokenPill.click();
|
||||||
|
|
||||||
|
// Change token from dropdown
|
||||||
|
const dimensionTokenOptionXl = measuresSection.getByLabel("dimension.xl");
|
||||||
|
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||||
|
await dimensionTokenOptionXl.click();
|
||||||
|
|
||||||
|
await expect(dimensionSMTokenPill).not.toBeVisible();
|
||||||
|
const dimensionXLTokenPill = measuresSection.getByRole("button", {
|
||||||
|
name: "dimension.xl",
|
||||||
|
});
|
||||||
|
await expect(dimensionXLTokenPill).toBeVisible();
|
||||||
|
|
||||||
|
// Detach token from design tab on right sidebar
|
||||||
|
const detachButton = measuresSection.getByRole("button", {
|
||||||
|
name: "Detach token",
|
||||||
|
});
|
||||||
|
await detachButton.nth(0).click();
|
||||||
|
await expect(dimensionXLTokenPill).not.toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("User applies dimension token to a shape on y position", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
||||||
|
await setupTokensFile(page);
|
||||||
|
|
||||||
|
// Unfolds dimensions on token panel
|
||||||
|
await page.getByRole("tab", { name: "Layers" }).click();
|
||||||
|
|
||||||
|
await workspacePage.layers.getByTestId("layer-row").nth(1).click();
|
||||||
|
|
||||||
|
const tokensTabButton = page.getByRole("tab", { name: "Tokens" });
|
||||||
|
await tokensTabButton.click();
|
||||||
|
|
||||||
|
unfoldTokenTree(tokensSidebar, "dimensions", "dimension.dimension.sm");
|
||||||
|
|
||||||
|
// Apply token to width and height token from token panel
|
||||||
|
await tokensSidebar
|
||||||
|
.getByRole("button", { name: "dimension.sm" })
|
||||||
|
.click({ button: "right" });
|
||||||
|
await tokenContextMenuForToken.getByText("Y").click();
|
||||||
|
|
||||||
|
// Check if measures sections is visible on right sidebar
|
||||||
|
const measuresSection = page.getByRole("region", {
|
||||||
|
name: "shape-measures-section",
|
||||||
|
});
|
||||||
|
await expect(measuresSection).toBeVisible();
|
||||||
|
|
||||||
|
// Check if token pill is visible on design tab on right sidebar
|
||||||
|
const dimensionSMTokenPill = measuresSection.getByRole("button", {
|
||||||
|
name: "dimension.sm",
|
||||||
|
});
|
||||||
|
await expect(dimensionSMTokenPill).toBeVisible();
|
||||||
|
await dimensionSMTokenPill.click();
|
||||||
|
|
||||||
|
// Change token from dropdown
|
||||||
|
const dimensionTokenOptionXl = measuresSection.getByLabel("dimension.xl");
|
||||||
|
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||||
|
await dimensionTokenOptionXl.click();
|
||||||
|
|
||||||
|
await expect(dimensionSMTokenPill).not.toBeVisible();
|
||||||
|
const dimensionXLTokenPill = measuresSection.getByRole("button", {
|
||||||
|
name: "dimension.xl",
|
||||||
|
});
|
||||||
|
await expect(dimensionXLTokenPill).toBeVisible();
|
||||||
|
|
||||||
|
// Detach token from design tab on right sidebar
|
||||||
|
const detachButton = measuresSection.getByRole("button", {
|
||||||
|
name: "Detach token",
|
||||||
|
});
|
||||||
|
await detachButton.nth(0).click();
|
||||||
|
await expect(dimensionXLTokenPill).not.toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("User applies dimension token to a shape border-radius", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const { workspacePage, tokensSidebar, tokenContextMenuForToken } =
|
||||||
|
await setupTokensFile(page);
|
||||||
|
|
||||||
|
// Unfolds dimensions on token panel
|
||||||
|
await page.getByRole("tab", { name: "Layers" }).click();
|
||||||
|
|
||||||
|
await workspacePage.layers.getByTestId("layer-row").nth(2).click();
|
||||||
|
|
||||||
|
const tokensTabButton = page.getByRole("tab", { name: "Tokens" });
|
||||||
|
await tokensTabButton.click();
|
||||||
|
|
||||||
|
unfoldTokenTree(tokensSidebar, "dimensions", "dimension.dimension.xs");
|
||||||
|
|
||||||
|
// Apply token to width and height token from token panel
|
||||||
|
await tokensSidebar
|
||||||
|
.getByRole("button", { name: "dimension.xs" })
|
||||||
|
.click({ button: "right" });
|
||||||
|
await tokenContextMenuForToken.getByText("Border radius").hover();
|
||||||
|
await tokenContextMenuForToken.getByText("RadiusAll").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 dimensionXSTokenPill = borderRadiusSection.getByRole("button", {
|
||||||
|
name: "dimension.xs",
|
||||||
|
});
|
||||||
|
await expect(dimensionXSTokenPill).toBeVisible();
|
||||||
|
await dimensionXSTokenPill.click();
|
||||||
|
|
||||||
|
// Change token from dropdown
|
||||||
|
const dimensionTokenOptionXl = borderRadiusSection.getByLabel("dimension.xl");
|
||||||
|
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||||
|
await dimensionTokenOptionXl.click();
|
||||||
|
|
||||||
|
await expect(dimensionXSTokenPill).not.toBeVisible();
|
||||||
|
const dimensionXLTokenPill = borderRadiusSection.getByRole("button", {
|
||||||
|
name: "dimension.xl",
|
||||||
|
});
|
||||||
|
await expect(dimensionXLTokenPill).toBeVisible();
|
||||||
|
|
||||||
|
// Detach token from design tab on right sidebar
|
||||||
|
const detachButton = borderRadiusSection.getByRole("button", {
|
||||||
|
name: "Detach token",
|
||||||
|
});
|
||||||
|
await detachButton.nth(0).click();
|
||||||
|
await expect(dimensionXLTokenPill).not.toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -191,16 +191,6 @@
|
|||||||
(when (:fill attributes) (update-fill value shape-ids attributes page-id))
|
(when (:fill attributes) (update-fill value shape-ids attributes page-id))
|
||||||
(when (:stroke-color attributes) (update-stroke-color value shape-ids attributes page-id)))))))
|
(when (:stroke-color attributes) (update-stroke-color value shape-ids attributes page-id)))))))
|
||||||
|
|
||||||
(defn update-shape-dimensions
|
|
||||||
([value shape-ids attributes] (update-shape-dimensions value shape-ids attributes nil))
|
|
||||||
([value shape-ids attributes page-id]
|
|
||||||
(ptk/reify ::update-shape-dimensions
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ _ _]
|
|
||||||
(when (number? value)
|
|
||||||
(rx/of
|
|
||||||
(when (:width attributes) (dwtr/update-dimensions shape-ids :width value {:ignore-touched true :page-id page-id}))
|
|
||||||
(when (:height attributes) (dwtr/update-dimensions shape-ids :height value {:ignore-touched true :page-id page-id}))))))))
|
|
||||||
|
|
||||||
(defn- attributes->layout-gap [attributes value]
|
(defn- attributes->layout-gap [attributes value]
|
||||||
(let [layout-gap (-> (set/intersection attributes #{:column-gap :row-gap})
|
(let [layout-gap (-> (set/intersection attributes #{:column-gap :row-gap})
|
||||||
@@ -248,21 +238,6 @@
|
|||||||
{:ignore-touched true
|
{:ignore-touched true
|
||||||
:page-id page-id}))))))))
|
:page-id page-id}))))))))
|
||||||
|
|
||||||
(defn update-layout-spacing
|
|
||||||
([value shape-ids attributes] (update-layout-spacing value shape-ids attributes nil))
|
|
||||||
([value shape-ids attributes page-id]
|
|
||||||
(ptk/reify ::update-layout-spacing
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state _]
|
|
||||||
(when (number? value)
|
|
||||||
(let [ids-with-layout (shape-ids-with-layout state (or page-id (:current-page-id state)) shape-ids)
|
|
||||||
layout-attributes (attributes->layout-gap attributes value)]
|
|
||||||
(rx/of
|
|
||||||
(dwsl/update-layout ids-with-layout
|
|
||||||
layout-attributes
|
|
||||||
{:ignore-touched true
|
|
||||||
:page-id page-id}))))))))
|
|
||||||
|
|
||||||
(defn update-shape-position
|
(defn update-shape-position
|
||||||
([value shape-ids attributes] (update-shape-position value shape-ids attributes nil))
|
([value shape-ids attributes] (update-shape-position value shape-ids attributes nil))
|
||||||
([value shape-ids attributes page-id]
|
([value shape-ids attributes page-id]
|
||||||
@@ -276,6 +251,20 @@
|
|||||||
{:ignore-touched true
|
{:ignore-touched true
|
||||||
:page-id page-id})))))))))
|
:page-id page-id})))))))))
|
||||||
|
|
||||||
|
(defn update-layout-gap
|
||||||
|
[value shape-ids attributes page-id]
|
||||||
|
(ptk/reify ::update-layout-gao
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state _]
|
||||||
|
(when (number? value)
|
||||||
|
(let [ids-with-layout (shape-ids-with-layout state (or page-id (:current-page-id state)) shape-ids)
|
||||||
|
layout-attributes (attributes->layout-gap attributes value)]
|
||||||
|
(rx/of
|
||||||
|
(dwsl/update-layout ids-with-layout
|
||||||
|
layout-attributes
|
||||||
|
{:ignore-touched true
|
||||||
|
:page-id page-id})))))))
|
||||||
|
|
||||||
(defn update-layout-sizing-limits
|
(defn update-layout-sizing-limits
|
||||||
([value shape-ids attributes] (update-layout-sizing-limits value shape-ids attributes nil))
|
([value shape-ids attributes] (update-layout-sizing-limits value shape-ids attributes nil))
|
||||||
([value shape-ids attributes page-id]
|
([value shape-ids attributes page-id]
|
||||||
@@ -470,20 +459,126 @@
|
|||||||
value
|
value
|
||||||
[shape-ids attributes page-id])))))
|
[shape-ids attributes page-id])))))
|
||||||
|
|
||||||
(defn update-typography-interactive
|
(defn update-shape-dimensions
|
||||||
([value shape-ids attributes] (update-typography value shape-ids attributes nil))
|
([value shape-ids attributes] (update-shape-dimensions value shape-ids attributes nil))
|
||||||
([value shape-ids attributes page-id]
|
([value shape-ids attributes page-id]
|
||||||
(when (map? value)
|
(ptk/reify ::update-shape-dimensions
|
||||||
(rx/merge
|
ptk/WatchEvent
|
||||||
(apply-functions-map
|
(watch [_ _ _]
|
||||||
{:font-size update-font-size
|
(when (number? value)
|
||||||
:font-family update-font-family-interactive
|
(rx/of
|
||||||
:font-weight update-font-weight-interactive
|
(when (:width attributes) (dwtr/update-dimensions shape-ids :width value {:ignore-touched true :page-id page-id}))
|
||||||
:letter-spacing update-letter-spacing
|
(when (:height attributes) (dwtr/update-dimensions shape-ids :height value {:ignore-touched true :page-id page-id}))))))))
|
||||||
:text-case update-text-case
|
|
||||||
:text-decoration update-text-decoration-interactive}
|
(defn- attributes->actions
|
||||||
value
|
[{:keys [value shape-ids attributes page-id]}]
|
||||||
[shape-ids attributes page-id])))))
|
(cond-> []
|
||||||
|
(some attributes #{:width :height})
|
||||||
|
(conj #(update-shape-dimensions
|
||||||
|
value shape-ids
|
||||||
|
(set (filter attributes #{:width :height}))
|
||||||
|
page-id))
|
||||||
|
|
||||||
|
(some attributes #{:x :y})
|
||||||
|
(conj #(update-shape-position
|
||||||
|
value shape-ids
|
||||||
|
(set (filter attributes #{:x :y}))
|
||||||
|
page-id))
|
||||||
|
|
||||||
|
(some attributes #{:p1 :p2 :p3 :p4})
|
||||||
|
(conj #(update-layout-padding
|
||||||
|
value shape-ids
|
||||||
|
(set (filter attributes #{:p1 :p2 :p3 :p4}))
|
||||||
|
page-id))
|
||||||
|
|
||||||
|
(some attributes #{:m1 :m2 :m3 :m4})
|
||||||
|
(conj #(update-layout-item-margin
|
||||||
|
value shape-ids
|
||||||
|
(set (filter attributes #{:m1 :m2 :m3 :m4}))
|
||||||
|
page-id))
|
||||||
|
|
||||||
|
(some attributes #{:row-gap :column-gap})
|
||||||
|
(conj #(update-layout-gap
|
||||||
|
value shape-ids
|
||||||
|
(set (filter attributes #{:row-gap :column-gap}))
|
||||||
|
page-id))
|
||||||
|
|
||||||
|
(some attributes #{:r1 :r2 :r3 :r4})
|
||||||
|
(conj #(if (= attributes #{:r1 :r2 :r3 :r4})
|
||||||
|
(update-shape-radius-all value shape-ids attributes page-id)
|
||||||
|
(update-shape-radius-for-corners
|
||||||
|
value shape-ids
|
||||||
|
(set (filter attributes #{:r1 :r2 :r3 :r4}))
|
||||||
|
page-id)))
|
||||||
|
|
||||||
|
(some attributes #{:strole-width})
|
||||||
|
(conj #(update-stroke-width
|
||||||
|
value shape-ids
|
||||||
|
#{:strole-width}
|
||||||
|
page-id))
|
||||||
|
(some attributes #{:max-width :max-height})
|
||||||
|
(conj #(update-layout-sizing-limits
|
||||||
|
value shape-ids
|
||||||
|
(set (filter attributes #{:max-width :max-height}))
|
||||||
|
page-id))))
|
||||||
|
|
||||||
|
(defn use-dimensions-token
|
||||||
|
([value shape-ids attributes] (use-dimensions-token value shape-ids attributes nil))
|
||||||
|
([value shape-ids attributes page-id]
|
||||||
|
(ptk/reify ::use-dimensions-token
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state _]
|
||||||
|
(when (number? value)
|
||||||
|
(let [actions (attributes->actions
|
||||||
|
{:value value
|
||||||
|
:shape-ids shape-ids
|
||||||
|
:attributes attributes
|
||||||
|
:page-id page-id
|
||||||
|
:state state})]
|
||||||
|
(apply rx/of (map #(%) actions))))))))
|
||||||
|
|
||||||
|
(defn use-spacing-token
|
||||||
|
([value shape-ids attributes] (use-spacing-token value shape-ids attributes nil))
|
||||||
|
([value shape-ids attributes page-id]
|
||||||
|
(ptk/reify ::use-spacing-token
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state _]
|
||||||
|
(let [spacing-attrs
|
||||||
|
#{:row-gap :column-gap
|
||||||
|
:m1 :m2 :m3 :m4
|
||||||
|
:p1 :p2 :p3 :p4}]
|
||||||
|
(when (and (number? value)
|
||||||
|
(set? attributes)
|
||||||
|
(set/subset? attributes spacing-attrs))
|
||||||
|
|
||||||
|
(let [actions (attributes->actions
|
||||||
|
{:value value
|
||||||
|
:shape-ids shape-ids
|
||||||
|
:attributes attributes
|
||||||
|
:page-id page-id
|
||||||
|
:state state})]
|
||||||
|
(apply rx/of (map #(%) actions)))))))))
|
||||||
|
|
||||||
|
(defn use-sizing-token
|
||||||
|
([value shape-ids attributes] (use-sizing-token value shape-ids attributes nil))
|
||||||
|
([value shape-ids attributes page-id]
|
||||||
|
(ptk/reify ::use-sizing-token
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state _]
|
||||||
|
(let [sizing-attrs
|
||||||
|
#{:width :height
|
||||||
|
:max-width :max-height}]
|
||||||
|
(when (and (number? value)
|
||||||
|
(set? attributes)
|
||||||
|
(set/subset? attributes sizing-attrs))
|
||||||
|
|
||||||
|
(let [actions (attributes->actions
|
||||||
|
{:value value
|
||||||
|
:shape-ids shape-ids
|
||||||
|
:attributes attributes
|
||||||
|
:page-id page-id
|
||||||
|
:state state})]
|
||||||
|
(apply rx/of (map #(%) actions)))))))))
|
||||||
|
|
||||||
;; Events to apply / unapply tokens to shapes ------------------------------------------------------------
|
;; Events to apply / unapply tokens to shapes ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -623,54 +718,19 @@
|
|||||||
:token token
|
:token token
|
||||||
:shape-ids shape-ids}))
|
:shape-ids shape-ids}))
|
||||||
(rx/of
|
(rx/of
|
||||||
(case (:type token)
|
(cond
|
||||||
:spacing
|
(and (= (:type token) :spacing)
|
||||||
|
(nil? attrs))
|
||||||
(apply-spacing-token {:token token
|
(apply-spacing-token {:token token
|
||||||
:attr attrs
|
:attr attrs
|
||||||
:shapes shapes})
|
:shapes shapes})
|
||||||
|
|
||||||
|
:else
|
||||||
(apply-token {:attributes (if (empty? attrs) attributes attrs)
|
(apply-token {:attributes (if (empty? attrs) attributes attrs)
|
||||||
:token token
|
:token token
|
||||||
: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]
|
||||||
(ptk/reify ::apply-token-on-selected
|
(ptk/reify ::apply-token-on-selected
|
||||||
@@ -800,7 +860,7 @@
|
|||||||
{:title "Sizing"
|
{:title "Sizing"
|
||||||
:attributes #{:width :height}
|
:attributes #{:width :height}
|
||||||
:all-attributes ctt/sizing-keys
|
:all-attributes ctt/sizing-keys
|
||||||
:on-update-shape update-shape-dimensions
|
:on-update-shape use-sizing-token
|
||||||
:modal {:key :tokens/sizing
|
:modal {:key :tokens/sizing
|
||||||
:fields [{:label "Sizing"
|
:fields [{:label "Sizing"
|
||||||
:key :sizing}]}}
|
:key :sizing}]}}
|
||||||
@@ -813,7 +873,7 @@
|
|||||||
ctt/border-radius-keys
|
ctt/border-radius-keys
|
||||||
ctt/axis-keys
|
ctt/axis-keys
|
||||||
ctt/stroke-width-keys)
|
ctt/stroke-width-keys)
|
||||||
:on-update-shape update-shape-dimensions
|
:on-update-shape use-dimensions-token
|
||||||
:modal {:key :tokens/dimensions
|
:modal {:key :tokens/dimensions
|
||||||
:fields [{:label "Dimensions"
|
:fields [{:label "Dimensions"
|
||||||
:key :dimensions}]}}
|
:key :dimensions}]}}
|
||||||
@@ -846,7 +906,7 @@
|
|||||||
{:title "Spacing"
|
{:title "Spacing"
|
||||||
:attributes #{:column-gap :row-gap}
|
:attributes #{:column-gap :row-gap}
|
||||||
:all-attributes ctt/spacing-keys
|
:all-attributes ctt/spacing-keys
|
||||||
:on-update-shape update-layout-spacing
|
:on-update-shape use-spacing-token
|
||||||
:modal {:key :tokens/spacing
|
:modal {:key :tokens/spacing
|
||||||
:fields [{:label "Spacing"
|
:fields [{:label "Spacing"
|
||||||
:key :spacing}]}}))
|
:key :spacing}]}}))
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
{ctt/border-radius-keys dwta/update-shape-radius-for-corners
|
{ctt/border-radius-keys dwta/update-shape-radius-for-corners
|
||||||
ctt/color-keys dwta/update-fill-stroke
|
ctt/color-keys dwta/update-fill-stroke
|
||||||
ctt/stroke-width-keys dwta/update-stroke-width
|
ctt/stroke-width-keys dwta/update-stroke-width
|
||||||
ctt/sizing-keys dwta/update-shape-dimensions
|
ctt/sizing-keys dwta/use-dimensions-token
|
||||||
ctt/opacity-keys dwta/update-opacity
|
ctt/opacity-keys dwta/update-opacity
|
||||||
ctt/rotation-keys dwta/update-rotation
|
ctt/rotation-keys dwta/update-rotation
|
||||||
|
|
||||||
@@ -73,8 +73,8 @@
|
|||||||
#{:x :y} dwta/update-shape-position
|
#{:x :y} dwta/update-shape-position
|
||||||
#{:p1 :p2 :p3 :p4} dwta/update-layout-padding
|
#{:p1 :p2 :p3 :p4} dwta/update-layout-padding
|
||||||
#{:m1 :m2 :m3 :m4} dwta/update-layout-item-margin
|
#{:m1 :m2 :m3 :m4} dwta/update-layout-item-margin
|
||||||
#{:column-gap :row-gap} dwta/update-layout-spacing
|
#{:column-gap :row-gap} dwta/update-layout-gap
|
||||||
#{:width :height} dwta/update-shape-dimensions
|
#{:width :height} dwta/use-dimensions-token
|
||||||
#{:layout-item-min-w :layout-item-min-h :layout-item-max-w :layout-item-max-h} dwta/update-layout-sizing-limits})
|
#{:layout-item-min-w :layout-item-min-h :layout-item-max-w :layout-item-max-h} dwta/update-layout-sizing-limits})
|
||||||
|
|
||||||
(def ^:private attribute-actions-map
|
(def ^:private attribute-actions-map
|
||||||
|
|||||||
@@ -192,11 +192,10 @@
|
|||||||
(st/emit!
|
(st/emit!
|
||||||
(change-radius (fn [shape]
|
(change-radius (fn [shape]
|
||||||
(ctsr/set-radius-to-all-corners shape value))))
|
(ctsr/set-radius-to-all-corners shape value))))
|
||||||
(doseq [attr [:r1 :r2 :r3 :r4]]
|
|
||||||
(st/emit!
|
(st/emit!
|
||||||
(dwta/toggle-token {:token (first value)
|
(dwta/toggle-token {:token (first value)
|
||||||
:attrs #{attr}
|
:attrs #{:r1 :r2 :r3 :r4}
|
||||||
:shape-ids ids}))))))
|
:shape-ids ids})))))
|
||||||
|
|
||||||
|
|
||||||
on-single-radius-change
|
on-single-radius-change
|
||||||
@@ -205,9 +204,10 @@
|
|||||||
(fn [value attr]
|
(fn [value attr]
|
||||||
(if (or (string? value) (number? value))
|
(if (or (string? value) (number? value))
|
||||||
(st/emit! (change-one-radius #(ctsr/set-radius-to-single-corner % attr value) attr))
|
(st/emit! (change-one-radius #(ctsr/set-radius-to-single-corner % attr value) attr))
|
||||||
(st/emit! (dwta/toggle-border-radius-token {:token (first value)
|
(st/emit! (st/emit!
|
||||||
|
(dwta/toggle-token {:token (first value)
|
||||||
:attrs #{attr}
|
:attrs #{attr}
|
||||||
:shape-ids ids})))))
|
:shape-ids ids}))))))
|
||||||
|
|
||||||
on-radius-r1-change #(on-single-radius-change % :r1)
|
on-radius-r1-change #(on-single-radius-change % :r1)
|
||||||
on-radius-r2-change #(on-single-radius-change % :r2)
|
on-radius-r2-change #(on-single-radius-change % :r2)
|
||||||
|
|||||||
@@ -369,12 +369,12 @@
|
|||||||
(if (or (string? value) (int? value))
|
(if (or (string? value) (int? value))
|
||||||
(on-change :simple attr value event)
|
(on-change :simple attr value event)
|
||||||
(do
|
(do
|
||||||
(let [resolved-value (:resolved-value (first value))
|
(st/emit!
|
||||||
updated-attr (if (= :p1 attr) #{:p1 :p3} #{:p2 :p4})]
|
(dwta/toggle-token {:token (first value)
|
||||||
(st/emit! (dwta/toggle-token {:token (first value)
|
:attrs (if (= :p1 attr)
|
||||||
:attrs updated-attr
|
#{:p1 :p3}
|
||||||
:shape-ids ids}))
|
#{:p2 :p4})
|
||||||
(on-change :simple attr resolved-value event))))))
|
:shape-ids ids}))))))
|
||||||
|
|
||||||
on-detach-token
|
on-detach-token
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@@ -483,11 +483,9 @@
|
|||||||
(if (or (string? value) (int? value))
|
(if (or (string? value) (int? value))
|
||||||
(on-change :multiple attr value event)
|
(on-change :multiple attr value event)
|
||||||
(do
|
(do
|
||||||
(let [resolved-value (:resolved-value (first value))]
|
|
||||||
(st/emit! (dwta/toggle-token {:token (first value)
|
(st/emit! (dwta/toggle-token {:token (first value)
|
||||||
:attrs #{attr}
|
:attrs #{attr}
|
||||||
:shape-ids ids}))
|
:shape-ids ids}))))))
|
||||||
(on-change :multiple attr resolved-value event))))))
|
|
||||||
|
|
||||||
on-focus
|
on-focus
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@@ -716,11 +714,12 @@
|
|||||||
(if (or (string? value) (int? value))
|
(if (or (string? value) (int? value))
|
||||||
(on-change (= "nowrap" wrap-type) attr value event)
|
(on-change (= "nowrap" wrap-type) attr value event)
|
||||||
(do
|
(do
|
||||||
(let [resolved-value (:resolved-value (first value))]
|
(st/emit!
|
||||||
(st/emit! (dwta/toggle-token {:token (first value)
|
(dwta/toggle-token {:token (first value)
|
||||||
:attrs #{attr}
|
:attrs (if (= "nowrap" wrap-type)
|
||||||
:shape-ids ids}))
|
#{:row-gap :colum-gap}
|
||||||
(on-change (= "nowrap" wrap-type) attr resolved-value event))))))
|
#{attr})
|
||||||
|
:shape-ids ids}))))))
|
||||||
|
|
||||||
on-detach-token
|
on-detach-token
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
|||||||
@@ -284,28 +284,17 @@
|
|||||||
(st/emit! (udw/change-orientation ids (keyword orientation)))))
|
(st/emit! (udw/change-orientation ids (keyword orientation)))))
|
||||||
|
|
||||||
;; SIZE AND PROPORTION LOCK
|
;; SIZE AND PROPORTION LOCK
|
||||||
do-size-change
|
|
||||||
(mf/use-fn
|
|
||||||
(mf/deps ids)
|
|
||||||
(fn [value attr]
|
|
||||||
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
|
||||||
(udw/update-dimensions ids attr value))))
|
|
||||||
|
|
||||||
on-size-change
|
on-size-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps ids shapes)
|
(mf/deps ids shapes)
|
||||||
(fn [value attr]
|
(fn [value attr]
|
||||||
(if (or (string? value) (number? value))
|
(if (or (string? value) (number? value))
|
||||||
(do
|
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
||||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
(udw/update-dimensions ids attr value))
|
||||||
(run! #(do-size-change value attr) shapes))
|
|
||||||
(do
|
|
||||||
(let [resolved-value (:resolved-value (first value))]
|
|
||||||
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
||||||
(dwta/toggle-token {:token (first value)
|
(dwta/toggle-token {:token (first value)
|
||||||
:attrs #{attr}
|
:attrs #{attr}
|
||||||
:shape-ids ids}))
|
:shape-ids ids})))))
|
||||||
(run! #(do-size-change resolved-value attr) shapes))))))
|
|
||||||
|
|
||||||
on-proportion-lock-change
|
on-proportion-lock-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@@ -315,11 +304,6 @@
|
|||||||
(run! #(st/emit! (udw/set-shape-proportion-lock % new-lock)) ids))))
|
(run! #(st/emit! (udw/set-shape-proportion-lock % new-lock)) ids))))
|
||||||
|
|
||||||
;; POSITION
|
;; POSITION
|
||||||
do-position-change
|
|
||||||
(mf/use-fn
|
|
||||||
(fn [shape' value attr]
|
|
||||||
(st/emit! (udw/update-position (:id shape') {attr value}))))
|
|
||||||
|
|
||||||
on-position-change
|
on-position-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps ids)
|
(mf/deps ids)
|
||||||
@@ -327,21 +311,11 @@
|
|||||||
(if (or (string? value) (number? value))
|
(if (or (string? value) (number? value))
|
||||||
(do
|
(do
|
||||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||||
(run! #(do-position-change %1 value attr) shapes))
|
(st/emit! (udw/update-position ids {attr value})))
|
||||||
(do
|
|
||||||
(let [resolved-value (:resolved-value (first value))]
|
|
||||||
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
||||||
(dwta/toggle-token {:token (first value)
|
(dwta/toggle-token {:token (first value)
|
||||||
:attrs #{attr}
|
:attrs #{attr}
|
||||||
:shape-ids ids}))
|
:shape-ids ids})))))
|
||||||
(run! #(do-position-change %1 resolved-value attr) shapes))))))
|
|
||||||
|
|
||||||
;; ROTATION
|
|
||||||
do-rotation-change
|
|
||||||
(mf/use-fn
|
|
||||||
(mf/deps ids)
|
|
||||||
(fn [value]
|
|
||||||
(st/emit! (udw/increase-rotation ids value))))
|
|
||||||
|
|
||||||
on-rotation-change
|
on-rotation-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@@ -350,14 +324,11 @@
|
|||||||
(if (or (string? value) (number? value))
|
(if (or (string? value) (number? value))
|
||||||
(do
|
(do
|
||||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||||
(run! #(do-rotation-change value) shapes))
|
(st/emit! (udw/increase-rotation ids value)))
|
||||||
(do
|
|
||||||
(let [resolved-value (:resolved-value (first value))]
|
|
||||||
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
(st/emit! (udw/trigger-bounding-box-cloaking ids)
|
||||||
(dwta/toggle-token {:token (first value)
|
(dwta/toggle-token {:token (first value)
|
||||||
:attrs #{:rotation}
|
:attrs #{:rotation}
|
||||||
:shape-ids ids}))
|
:shape-ids ids})))))
|
||||||
(run! #(do-rotation-change resolved-value) shapes))))))
|
|
||||||
|
|
||||||
on-width-change
|
on-width-change
|
||||||
(mf/use-fn (mf/deps on-size-change) #(on-size-change % :width))
|
(mf/use-fn (mf/deps on-size-change) #(on-size-change % :width))
|
||||||
@@ -410,7 +381,8 @@
|
|||||||
(fn []
|
(fn []
|
||||||
(st/emit! (dwt/selected-fit-content))))]
|
(st/emit! (dwt/selected-fit-content))))]
|
||||||
|
|
||||||
[:div {:class (stl/css :element-set)}
|
[:section {:class (stl/css :element-set)
|
||||||
|
:aria-label "shape-measures-section"}
|
||||||
(when (and (options :presets)
|
(when (and (options :presets)
|
||||||
(or (nil? all-types) (= (count all-types) 1)))
|
(or (nil? all-types) (= (count all-types) 1)))
|
||||||
[:div {:class (stl/css :presets)}
|
[:div {:class (stl/css :presets)}
|
||||||
|
|||||||
@@ -9,18 +9,50 @@
|
|||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.types.color :as ctc]
|
[app.common.types.color :as ctc]
|
||||||
|
[app.common.types.token :as tk]
|
||||||
[app.main.data.workspace.tokens.application :as dwta]
|
[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 :refer [numeric-input*]]
|
[app.main.ui.components.numeric-input :as deprecated-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.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 h]
|
[app.main.ui.hooks :as h]
|
||||||
[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 numeric-input-wrapper*
|
||||||
|
{::mf/private true}
|
||||||
|
[{:keys [values name applied-tokens align on-detach] :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))
|
||||||
|
|
||||||
|
applied-token (get applied-tokens name)
|
||||||
|
|
||||||
|
props (mf/spread-props props
|
||||||
|
{:placeholder (if (= :multiple values)
|
||||||
|
(tr "settings.multiple")
|
||||||
|
"--")
|
||||||
|
:applied-token applied-token
|
||||||
|
:tokens (if (delay? tokens) @tokens tokens)
|
||||||
|
:align align
|
||||||
|
:on-detach on-detach-attr
|
||||||
|
:name name
|
||||||
|
:value values})]
|
||||||
|
[:> numeric-input* props]))
|
||||||
|
|
||||||
(mf/defc stroke-row*
|
(mf/defc stroke-row*
|
||||||
[{:keys [index
|
[{:keys [index
|
||||||
stroke
|
stroke
|
||||||
@@ -45,7 +77,10 @@
|
|||||||
select-on-focus
|
select-on-focus
|
||||||
ids]}]
|
ids]}]
|
||||||
|
|
||||||
(let [on-drop
|
(let [token-numeric-inputs
|
||||||
|
(features/use-feature "tokens/numeric-input")
|
||||||
|
|
||||||
|
on-drop
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps on-reorder index)
|
(mf/deps on-reorder index)
|
||||||
(fn [relative-pos data]
|
(fn [relative-pos data]
|
||||||
@@ -88,7 +123,13 @@
|
|||||||
on-width-change
|
on-width-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps index on-stroke-width-change)
|
(mf/deps index on-stroke-width-change)
|
||||||
#(on-stroke-width-change index %))
|
(fn [value]
|
||||||
|
(if (or (string? value) (int? value))
|
||||||
|
(on-stroke-width-change index value)
|
||||||
|
(do
|
||||||
|
(st/emit! (dwta/toggle-token {:token (first value)
|
||||||
|
:attrs #{:stroke-width}
|
||||||
|
:shape-ids ids}))))))
|
||||||
|
|
||||||
stroke-alignment (or (:stroke-alignment stroke) :center)
|
stroke-alignment (or (:stroke-alignment stroke) :center)
|
||||||
|
|
||||||
@@ -149,6 +190,12 @@
|
|||||||
(fn [token]
|
(fn [token]
|
||||||
(on-detach-token token #{:stroke-color})))
|
(on-detach-token token #{:stroke-color})))
|
||||||
|
|
||||||
|
on-detach-token-width
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps on-detach-token)
|
||||||
|
(fn [token]
|
||||||
|
(on-detach-token (first token) #{:stroke-width})))
|
||||||
|
|
||||||
stroke-caps-options
|
stroke-caps-options
|
||||||
[{:value nil :label (tr "workspace.options.stroke-cap.none")}
|
[{:value nil :label (tr "workspace.options.stroke-cap.none")}
|
||||||
:separator
|
:separator
|
||||||
@@ -195,17 +242,30 @@
|
|||||||
|
|
||||||
;; Stroke Width, Alignment & Style
|
;; Stroke Width, Alignment & Style
|
||||||
[:div {:class (stl/css :stroke-options)}
|
[:div {:class (stl/css :stroke-options)}
|
||||||
|
(if token-numeric-inputs
|
||||||
|
[:> numeric-input-wrapper* {:on-change on-width-change
|
||||||
|
:on-detach on-detach-token-width
|
||||||
|
:icon i/stroke-size
|
||||||
|
:min 0
|
||||||
|
:on-focus on-focus
|
||||||
|
:on-blur on-blur
|
||||||
|
:name :stroke-width
|
||||||
|
:class (stl/css :numeric-input-wrapper)
|
||||||
|
:property (tr "workspace.options.stroke-width")
|
||||||
|
:applied-tokens applied-tokens
|
||||||
|
:values stroke-width}]
|
||||||
|
|
||||||
[:div {:class (stl/css :stroke-width-input)
|
[:div {:class (stl/css :stroke-width-input)
|
||||||
:title (tr "workspace.options.stroke-width")}
|
:title (tr "workspace.options.stroke-width")}
|
||||||
[:> icon* {:icon-id i/stroke-size
|
[:> icon* {:icon-id i/stroke-size
|
||||||
:size "s"}]
|
:size "s"}]
|
||||||
[:> numeric-input* {:value stroke-width
|
[:> deprecated-input/numeric-input* {:value stroke-width
|
||||||
:min 0
|
:min 0
|
||||||
: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 :stroke-alignment-select)
|
[:div {:class (stl/css :stroke-alignment-select)
|
||||||
:data-testid "stroke.alignment"}
|
:data-testid "stroke.alignment"}
|
||||||
|
|||||||
@@ -45,6 +45,11 @@
|
|||||||
padding-inline-start: var(--sp-xs);
|
padding-inline-start: var(--sp-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.numeric-input-wrapper {
|
||||||
|
grid-column: span 2;
|
||||||
|
--dropdown-width: var(--7-columns-dropdown-width);
|
||||||
|
}
|
||||||
|
|
||||||
.stroke-alignment-select {
|
.stroke-alignment-select {
|
||||||
grid-column: span 3;
|
grid-column: span 3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,7 +223,7 @@
|
|||||||
gap-items (all-or-separate-actions {:attribute-labels {:column-gap "Column Gap"
|
gap-items (all-or-separate-actions {:attribute-labels {:column-gap "Column Gap"
|
||||||
:row-gap "Row Gap"}
|
:row-gap "Row Gap"}
|
||||||
:hint (tr "workspace.tokens.gaps")
|
:hint (tr "workspace.tokens.gaps")
|
||||||
:on-update-shape dwta/update-layout-spacing}
|
:on-update-shape dwta/update-layout-gap}
|
||||||
context-data)]
|
context-data)]
|
||||||
(->> (concat
|
(->> (concat
|
||||||
gap-items
|
gap-items
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
(all-or-separate-actions {:attribute-labels {:width "Width"
|
(all-or-separate-actions {:attribute-labels {:width "Width"
|
||||||
:height "Height"}
|
:height "Height"}
|
||||||
:hint (tr "workspace.tokens.size")
|
:hint (tr "workspace.tokens.size")
|
||||||
:on-update-shape dwta/update-shape-dimensions}
|
:on-update-shape dwta/use-dimensions-token}
|
||||||
context-data)
|
context-data)
|
||||||
[:separator]
|
[:separator]
|
||||||
(all-or-separate-actions {:attribute-labels {:layout-item-min-w "Min Width"
|
(all-or-separate-actions {:attribute-labels {:layout-item-min-w "Min Width"
|
||||||
|
|||||||
@@ -260,7 +260,7 @@
|
|||||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||||
:attributes #{:width :height}
|
:attributes #{:width :height}
|
||||||
:token (toht/get-token file "dimensions.sm")
|
:token (toht/get-token file "dimensions.sm")
|
||||||
:on-update-shape dwta/update-shape-dimensions})]]
|
:on-update-shape dwta/use-dimensions-token})]]
|
||||||
(tohs/run-store-async
|
(tohs/run-store-async
|
||||||
store done events
|
store done events
|
||||||
(fn [new-state]
|
(fn [new-state]
|
||||||
@@ -333,7 +333,7 @@
|
|||||||
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
events [(dwta/apply-token {:shape-ids [(:id rect-1)]
|
||||||
:attributes #{:width :height}
|
:attributes #{:width :height}
|
||||||
:token (toht/get-token file "sizing.sm")
|
:token (toht/get-token file "sizing.sm")
|
||||||
:on-update-shape dwta/update-shape-dimensions})]]
|
:on-update-shape dwta/use-dimensions-token})]]
|
||||||
(tohs/run-store-async
|
(tohs/run-store-async
|
||||||
store done events
|
store done events
|
||||||
(fn [new-state]
|
(fn [new-state]
|
||||||
|
|||||||
Reference in New Issue
Block a user