mirror of
https://github.com/penpot/penpot.git
synced 2026-01-30 09:11:43 -05:00
Compare commits
2 Commits
develop
...
eva-fix-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff79374648 | ||
|
|
db7ab5105d |
@@ -48,6 +48,11 @@
|
||||
applied-tokens)
|
||||
(into {}))))
|
||||
|
||||
(defn remove-attribute-for-detached-token
|
||||
"Removes applied tokens when token-id is nil for the given `attributes` set from `applied-tokens`."
|
||||
[attributes applied-tokens]
|
||||
(apply dissoc applied-tokens attributes))
|
||||
|
||||
(defn token-attribute-applied?
|
||||
"Test if `token` is applied to a `shape` on single `token-attribute`."
|
||||
[token shape token-attribute]
|
||||
|
||||
@@ -831,15 +831,102 @@ test.describe("Tokens: Apply token", () => {
|
||||
});
|
||||
await detachButton.click();
|
||||
await expect(marginPillXL).not.toBeVisible();
|
||||
const horizontalMarginInput = layoutItemSectionSidebar.getByText('Horizontal marginOpen token');
|
||||
const horizontalMarginInput = layoutItemSectionSidebar.getByText(
|
||||
"Horizontal marginOpen token",
|
||||
);
|
||||
await expect(horizontalMarginInput).toBeVisible();
|
||||
|
||||
const tokenDropdown = horizontalMarginInput.getByRole('button', { name: 'Open token list' });
|
||||
const tokenDropdown = horizontalMarginInput.getByRole("button", {
|
||||
name: "Open token list",
|
||||
});
|
||||
await tokenDropdown.click();
|
||||
|
||||
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||
await dimensionTokenOptionXl.click();
|
||||
|
||||
|
||||
await expect(marginPillXL).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Tokens: Detach token", () => {
|
||||
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();
|
||||
|
||||
// Rename token
|
||||
await tokensSidebar
|
||||
.getByRole("button", { name: "borderRadius.sm" })
|
||||
.click({ button: "right" });
|
||||
await expect(page.getByText("Edit token")).toBeVisible();
|
||||
await page.getByText("Edit token").click();
|
||||
const editModal = page.getByTestId("token-update-create-modal");
|
||||
await expect(editModal).toBeVisible();
|
||||
await expect(
|
||||
editModal.getByRole("textbox", { name: "Name" }),
|
||||
).toBeVisible();
|
||||
await editModal
|
||||
.getByRole("textbox", { name: "Name" })
|
||||
.fill("BorderRadius.smBis");
|
||||
const submitButton = editModal.getByRole("button", { name: "Save" });
|
||||
await expect(submitButton).toBeEnabled();
|
||||
await submitButton.click();
|
||||
await expect(page.getByText("Don't remap")).toBeVisible();
|
||||
await page.getByText("Don't remap").click();
|
||||
const brokenPill = borderRadiusSection.getByRole("button", {
|
||||
name: "This token is not in any",
|
||||
});
|
||||
await expect(brokenPill).toBeVisible();
|
||||
|
||||
// Detach broken token
|
||||
const detachButton = borderRadiusSection.getByRole("button", {
|
||||
name: "Detach token",
|
||||
});
|
||||
await detachButton.click();
|
||||
await expect(brokenPill).not.toBeVisible();
|
||||
|
||||
//De-select and select shape again to double check token is detached
|
||||
await page.getByRole("tab", { name: "Layers" }).click();
|
||||
|
||||
await workspacePage.layers.getByTestId("layer-row").nth(0).click();
|
||||
await workspacePage.layers.getByTestId("layer-row").nth(1).click();
|
||||
await expect(brokenPill).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -710,6 +710,21 @@
|
||||
(fn [shape]
|
||||
(update shape :applied-tokens remove-token))))))))
|
||||
|
||||
(defn detach-token
|
||||
"Removes `attributes` when token-id is nil.
|
||||
|
||||
Doesn't update shape attributes."
|
||||
[{:keys [attributes shape-ids] :as _props}]
|
||||
(ptk/reify ::detach-token
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of
|
||||
(let [remove-token #(when % (cft/remove-attribute-for-detached-token attributes %))]
|
||||
(dwsh/update-shapes
|
||||
shape-ids
|
||||
(fn [shape]
|
||||
(update shape :applied-tokens remove-token))))))))
|
||||
|
||||
(defn toggle-token
|
||||
[{:keys [token attrs shape-ids expand-with-children]}]
|
||||
(ptk/reify ::on-toggle-token
|
||||
|
||||
@@ -61,9 +61,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attr]
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))))
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-detach-all
|
||||
(mf/use-fn
|
||||
|
||||
@@ -166,9 +166,16 @@
|
||||
(d/without-nils))]
|
||||
(mf/set-ref-val! prev-colors-ref
|
||||
(conj prev-colors color))
|
||||
(st/emit! (dwta/unapply-token {:attributes attr
|
||||
:token token
|
||||
:shape-ids [(:shape-id op)]})))))))
|
||||
(prn token)
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes attr
|
||||
:shape-ids [(:shape-id op)]}))
|
||||
(st/emit! (dwta/detach-token {:attributes attr
|
||||
:shape-ids [(:shape-id op)]})))
|
||||
#_(st/emit! (dwta/unapply-token {:attributes attr
|
||||
:token token
|
||||
:shape-ids [(:shape-id op)]})))))))
|
||||
|
||||
select-only
|
||||
(mf/use-fn
|
||||
|
||||
@@ -74,7 +74,6 @@
|
||||
|
||||
render-wasm? (feat/use-feature "render-wasm/v1")
|
||||
|
||||
|
||||
^boolean
|
||||
multiple? (= :multiple fills)
|
||||
|
||||
@@ -184,9 +183,13 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token]
|
||||
(st/emit! (dwta/unapply-token {:attributes #{:fill}
|
||||
:token token
|
||||
:shape-ids ids}))))]
|
||||
(prn "on-detach-token" token)
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{:fill}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{:fill}
|
||||
:shape-ids ids})))))]
|
||||
|
||||
(mf/with-layout-effect [hide-on-export]
|
||||
(when-let [checkbox (mf/ref-val checkbox-ref)]
|
||||
@@ -215,7 +218,8 @@
|
||||
(when open?
|
||||
[:div {:class (stl/css :fill-content)}
|
||||
(cond
|
||||
(= :multiple fills)
|
||||
(or (= :multiple fills)
|
||||
(= :multiple fill-token-applied))
|
||||
[:div {:class (stl/css :fill-multiple)}
|
||||
[:div {:class (stl/css :fill-multiple-label)}
|
||||
(tr "settings.multiple")]
|
||||
|
||||
@@ -73,9 +73,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attr]
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))))
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
current-blend-mode (or (get values :blend-mode) :normal)
|
||||
current-opacity (opacity->string (:opacity values))
|
||||
|
||||
@@ -340,9 +340,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attr]
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))))
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-focus
|
||||
(mf/use-fn
|
||||
@@ -475,9 +478,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attr]
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))))
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-p1-change
|
||||
(mf/use-fn (mf/deps on-change') #(on-change' % :p1))
|
||||
@@ -722,9 +728,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attr]
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))))
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-row-gap-change
|
||||
(mf/use-fn (mf/deps on-change') #(on-change' %1 %2 :row-gap))
|
||||
|
||||
@@ -98,9 +98,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attr]
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))))
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-detach-horizontal
|
||||
(mf/use-fn
|
||||
@@ -221,9 +224,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attr]
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))))
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-focus
|
||||
(mf/use-fn
|
||||
@@ -551,9 +557,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attr]
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))))
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
on-size-change
|
||||
(mf/use-fn
|
||||
|
||||
@@ -320,9 +320,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attr]
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))))
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes #{attr}
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes #{attr}
|
||||
:shape-ids ids})))))
|
||||
|
||||
;; CLIP CONTENT AND SHOW IN VIEWER
|
||||
on-change-clip-content
|
||||
|
||||
@@ -172,9 +172,12 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [token attrs]
|
||||
(st/emit! (dwta/unapply-token {:attributes attrs
|
||||
:token token
|
||||
:shape-ids ids}))))]
|
||||
(if (seq token)
|
||||
(st/emit! (dwta/unapply-token {:token (first token)
|
||||
:attributes attrs
|
||||
:shape-ids ids}))
|
||||
(st/emit! (dwta/detach-token {:attributes attrs
|
||||
:shape-ids ids})))))]
|
||||
|
||||
[:section {:class (stl/css :stroke-section)
|
||||
:aria-label "stroke-section"}
|
||||
|
||||
@@ -85,14 +85,13 @@
|
||||
(mf/use-fn
|
||||
(mf/deps detach-token token applied-token-name)
|
||||
(fn []
|
||||
(let [token (or token applied-token-name)]
|
||||
(detach-token token))))
|
||||
(detach-token token)))
|
||||
|
||||
has-errors (some? (:errors token))
|
||||
token-name (:name token)
|
||||
resolved (:resolved-value token)
|
||||
not-active (and (empty? active-tokens)
|
||||
(nil? token))
|
||||
not-active (or (empty? active-tokens)
|
||||
(nil? token))
|
||||
id (dm/str (:id token) "-name")
|
||||
swatch-tooltip-content (cond
|
||||
not-active
|
||||
@@ -344,7 +343,6 @@
|
||||
(mf/with-effect [color prev-color disable-picker]
|
||||
(when (and (not disable-picker) (not= prev-color color))
|
||||
(modal/update-props! :colorpicker {:data (parse-color color)})))
|
||||
|
||||
[:div {:class [class row-class]}
|
||||
;; Drag handler
|
||||
(when (some? on-reorder)
|
||||
|
||||
Reference in New Issue
Block a user