diff --git a/common/src/app/common/types/token.cljc b/common/src/app/common/types/token.cljc index ea3bed841c..f4792426b7 100644 --- a/common/src/app/common/types/token.cljc +++ b/common/src/app/common/types/token.cljc @@ -474,8 +474,8 @@ :height #{:sizing :dimensions} :max-width #{:sizing :dimensions} :max-height #{:sizing :dimensions} - :x #{:spacing :dimensions} - :y #{:spacing :dimensions} + :x #{:dimensions} + :y #{:dimensions} :rotation #{:number :rotation} :border-radius #{:border-radius :dimensions} :row-gap #{:spacing :dimensions} diff --git a/frontend/playwright/ui/specs/tokens/apply.spec.js b/frontend/playwright/ui/specs/tokens/apply.spec.js index 4e8130e4eb..376bc8122c 100644 --- a/frontend/playwright/ui/specs/tokens/apply.spec.js +++ b/frontend/playwright/ui/specs/tokens/apply.spec.js @@ -149,12 +149,14 @@ test.describe("Tokens: Apply token", () => { await detachButton.click(); // Open dropdown from input - const dropdownBtn = layerMenuSection.getByLabel('Open token list'); + const dropdownBtn = layerMenuSection.getByLabel("Open token list"); await expect(dropdownBtn).toBeVisible(); await dropdownBtn.click(); // 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 opacityLowOption.click(); @@ -482,4 +484,219 @@ test.describe("Tokens: Apply token", () => { 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(); + }); + }); diff --git a/frontend/src/app/main/data/workspace/tokens/application.cljs b/frontend/src/app/main/data/workspace/tokens/application.cljs index 2bebf8e4b8..531e4c3ce8 100644 --- a/frontend/src/app/main/data/workspace/tokens/application.cljs +++ b/frontend/src/app/main/data/workspace/tokens/application.cljs @@ -193,16 +193,6 @@ (when (:fill attributes) (update-fill 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] (let [layout-gap (-> (set/intersection attributes #{:column-gap :row-gap}) @@ -250,21 +240,6 @@ {:ignore-touched true :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 ([value shape-ids attributes] (update-shape-position value shape-ids attributes nil)) ([value shape-ids attributes page-id] @@ -278,6 +253,20 @@ {:ignore-touched true :page-id page-id}))))))))) +(defn update-layout-gap + [value shape-ids attributes page-id] + (ptk/reify ::update-layout-gap + 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 ([value shape-ids attributes] (update-layout-sizing-limits value shape-ids attributes nil)) ([value shape-ids attributes page-id] @@ -493,20 +482,126 @@ value [shape-ids attributes page-id]))))) -(defn update-typography-interactive - ([value shape-ids attributes] (update-typography value shape-ids attributes nil)) +(defn update-shape-dimensions + ([value shape-ids attributes] (update-shape-dimensions value shape-ids attributes nil)) ([value shape-ids attributes page-id] - (when (map? value) - (rx/merge - (apply-functions-map - {:font-size update-font-size - :font-family update-font-family-interactive - :font-weight update-font-weight-interactive - :letter-spacing update-letter-spacing - :text-case update-text-case - :text-decoration update-text-decoration-interactive} - 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->actions + [{:keys [value 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 apply-dimensions-token + ([value shape-ids attributes] (apply-dimensions-token value shape-ids attributes nil)) + ([value shape-ids attributes page-id] + (ptk/reify ::apply-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 apply-spacing-token + ([value shape-ids attributes] (apply-spacing-token value shape-ids attributes nil)) + ([value shape-ids attributes page-id] + (ptk/reify ::apply-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 apply-sizing-token + ([value shape-ids attributes] (apply-sizing-token value shape-ids attributes nil)) + ([value shape-ids attributes page-id] + (ptk/reify ::apply-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 ------------------------------------------------------------ @@ -572,13 +667,13 @@ (rx/of res)))) (rx/of (dwu/commit-undo-transaction undo-id))))))))))))) -(defn apply-spacing-token +(defn apply-spacing-token-separated "Handles edge-case for spacing token when applying token via toggle button. Splits out `shape-ids` into seperate default actions: - Layouts take the `default` update function - Shapes inside layout will only take margin" [{:keys [token shapes attr]}] - (ptk/reify ::apply-spacing-token + (ptk/reify ::apply-spacing-token-separated ptk/WatchEvent (watch [_ state _] (let [objects (dsh/lookup-page-objects state) @@ -646,54 +741,19 @@ :token token :shape-ids shape-ids})) (rx/of - (case (:type token) - :spacing - (apply-spacing-token {:token token - :attr attrs - :shapes shapes}) + (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 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 [color-operations token] (ptk/reify ::apply-token-on-selected @@ -823,7 +883,7 @@ {:title "Sizing" :attributes #{:width :height} :all-attributes ctt/sizing-keys - :on-update-shape update-shape-dimensions + :on-update-shape apply-sizing-token :modal {:key :tokens/sizing :fields [{:label "Sizing" :key :sizing}]}} @@ -836,7 +896,7 @@ ctt/border-radius-keys ctt/axis-keys ctt/stroke-width-keys) - :on-update-shape update-shape-dimensions + :on-update-shape apply-dimensions-token :modal {:key :tokens/dimensions :fields [{:label "Dimensions" :key :dimensions}]}} @@ -869,7 +929,7 @@ {:title "Spacing" :attributes #{:column-gap :row-gap} :all-attributes ctt/spacing-keys - :on-update-shape update-layout-spacing + :on-update-shape apply-spacing-token :modal {:key :tokens/spacing :fields [{:label "Spacing" :key :spacing}]}})) diff --git a/frontend/src/app/main/data/workspace/tokens/propagation.cljs b/frontend/src/app/main/data/workspace/tokens/propagation.cljs index fc5b76b79d..7ba5c3970c 100644 --- a/frontend/src/app/main/data/workspace/tokens/propagation.cljs +++ b/frontend/src/app/main/data/workspace/tokens/propagation.cljs @@ -54,7 +54,7 @@ {ctt/border-radius-keys dwta/update-shape-radius-for-corners ctt/color-keys dwta/update-fill-stroke ctt/stroke-width-keys dwta/update-stroke-width - ctt/sizing-keys dwta/update-shape-dimensions + ctt/sizing-keys dwta/apply-dimensions-token ctt/opacity-keys dwta/update-opacity ctt/rotation-keys dwta/update-rotation @@ -73,8 +73,8 @@ #{:x :y} dwta/update-shape-position #{:p1 :p2 :p3 :p4} dwta/update-layout-padding #{:m1 :m2 :m3 :m4} dwta/update-layout-item-margin - #{:column-gap :row-gap} dwta/update-layout-spacing - #{:width :height} dwta/update-shape-dimensions + #{:column-gap :row-gap} dwta/update-layout-gap + #{:width :height} dwta/apply-dimensions-token #{: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 diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs index 47b27f7f6e..809792af3d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs @@ -192,11 +192,10 @@ (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})))))) + (st/emit! + (dwta/toggle-token {:token (first value) + :attrs #{:r1 :r2 :r3 :r4} + :shape-ids ids}))))) on-single-radius-change @@ -205,9 +204,10 @@ (fn [value attr] (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}))))) + (st/emit! (st/emit! + (dwta/toggle-token {:token (first value) + :attrs #{attr} + :shape-ids ids})))))) on-radius-r1-change #(on-single-radius-change % :r1) on-radius-r2-change #(on-single-radius-change % :r2) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index 5fe4172d4f..0605999bd9 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -369,12 +369,12 @@ (if (or (string? value) (number? value)) (on-change :simple attr value event) (do - (let [resolved-value (:resolved-value (first value)) - updated-attr (if (= :p1 attr) #{:p1 :p3} #{:p2 :p4})] - (st/emit! (dwta/toggle-token {:token (first value) - :attrs updated-attr - :shape-ids ids})) - (on-change :simple attr resolved-value event)))))) + (st/emit! + (dwta/toggle-token {:token (first value) + :attrs (if (= :p1 attr) + #{:p1 :p3} + #{:p2 :p4}) + :shape-ids ids})))))) on-detach-token (mf/use-fn @@ -483,11 +483,9 @@ (if (or (string? value) (number? value)) (on-change :multiple attr value event) (do - (let [resolved-value (:resolved-value (first value))] - (st/emit! (dwta/toggle-token {:token (first value) - :attrs #{attr} - :shape-ids ids})) - (on-change :multiple attr resolved-value event)))))) + (st/emit! (dwta/toggle-token {:token (first value) + :attrs #{attr} + :shape-ids ids})))))) on-focus (mf/use-fn @@ -716,11 +714,12 @@ (if (or (string? value) (number? value)) (on-change (= "nowrap" wrap-type) attr value event) (do - (let [resolved-value (:resolved-value (first value))] - (st/emit! (dwta/toggle-token {:token (first value) - :attrs #{attr} - :shape-ids ids})) - (on-change (= "nowrap" wrap-type) attr resolved-value event)))))) + (st/emit! + (dwta/toggle-token {:token (first value) + :attrs (if (= "nowrap" wrap-type) + #{:row-gap :colum-gap} + #{attr}) + :shape-ids ids})))))) on-detach-token (mf/use-fn diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index 8c705b47e1..8d04d8187d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -284,28 +284,17 @@ (st/emit! (udw/change-orientation ids (keyword orientation))))) ;; 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 (mf/use-fn (mf/deps ids shapes) (fn [value attr] (if (or (string? value) (number? value)) - (do - (st/emit! (udw/trigger-bounding-box-cloaking ids)) - (run! #(do-size-change value attr) shapes)) - (do - (let [resolved-value (:resolved-value (first value))] - (st/emit! (udw/trigger-bounding-box-cloaking ids) - (dwta/toggle-token {:token (first value) - :attrs #{attr} - :shape-ids ids})) - (run! #(do-size-change resolved-value attr) shapes)))))) + (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}))))) on-proportion-lock-change (mf/use-fn @@ -315,11 +304,6 @@ (run! #(st/emit! (udw/set-shape-proportion-lock % new-lock)) ids)))) ;; POSITION - do-position-change - (mf/use-fn - (fn [shape' value attr] - (st/emit! (udw/update-position (:id shape') {attr value})))) - on-position-change (mf/use-fn (mf/deps ids) @@ -327,21 +311,11 @@ (if (or (string? value) (number? value)) (do (st/emit! (udw/trigger-bounding-box-cloaking ids)) - (run! #(do-position-change %1 value attr) shapes)) - (do - (let [resolved-value (:resolved-value (first value))] - (st/emit! (udw/trigger-bounding-box-cloaking ids) - (dwta/toggle-token {:token (first value) - :attrs #{attr} - :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)))) + (st/emit! (udw/update-position ids {attr value}))) + (st/emit! (udw/trigger-bounding-box-cloaking ids) + (dwta/toggle-token {:token (first value) + :attrs #{attr} + :shape-ids ids}))))) on-rotation-change (mf/use-fn @@ -350,14 +324,11 @@ (if (or (string? value) (number? value)) (do (st/emit! (udw/trigger-bounding-box-cloaking ids)) - (run! #(do-rotation-change value) shapes)) - (do - (let [resolved-value (:resolved-value (first value))] - (st/emit! (udw/trigger-bounding-box-cloaking ids) - (dwta/toggle-token {:token (first value) - :attrs #{:rotation} - :shape-ids ids})) - (run! #(do-rotation-change resolved-value) shapes)))))) + (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}))))) on-width-change (mf/use-fn (mf/deps on-size-change) #(on-size-change % :width)) @@ -410,7 +381,8 @@ (fn [] (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) (or (nil? all-types) (= (count all-types) 1))) [:div {:class (stl/css :presets)} diff --git a/frontend/src/app/main/ui/workspace/tokens/management/context_menu.cljs b/frontend/src/app/main/ui/workspace/tokens/management/context_menu.cljs index 1b26079247..1dcb40ea18 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/context_menu.cljs @@ -223,7 +223,7 @@ gap-items (all-or-separate-actions {:attribute-labels {:column-gap "Column Gap" :row-gap "Row Gap"} :hint (tr "workspace.tokens.gaps") - :on-update-shape dwta/update-layout-spacing} + :on-update-shape dwta/update-layout-gap} context-data)] (->> (concat gap-items @@ -239,7 +239,7 @@ (all-or-separate-actions {:attribute-labels {:width "Width" :height "Height"} :hint (tr "workspace.tokens.size") - :on-update-shape dwta/update-shape-dimensions} + :on-update-shape dwta/apply-dimensions-token} context-data) [:separator] (all-or-separate-actions {:attribute-labels {:layout-item-min-w "Min Width" diff --git a/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs b/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs index 0b8dd4247a..e215981948 100644 --- a/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs +++ b/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs @@ -260,7 +260,7 @@ events [(dwta/apply-token {:shape-ids [(:id rect-1)] :attributes #{:width :height} :token (toht/get-token file "dimensions.sm") - :on-update-shape dwta/update-shape-dimensions})]] + :on-update-shape dwta/apply-dimensions-token})]] (tohs/run-store-async store done events (fn [new-state] @@ -333,7 +333,7 @@ events [(dwta/apply-token {:shape-ids [(:id rect-1)] :attributes #{:width :height} :token (toht/get-token file "sizing.sm") - :on-update-shape dwta/update-shape-dimensions})]] + :on-update-shape dwta/apply-dimensions-token})]] (tohs/run-store-async store done events (fn [new-state]