mirror of
https://github.com/penpot/penpot.git
synced 2026-09-14 07:59:36 +00:00
🐛 Fix tooltip position on absolute positioned elements (#8509)
* 🐛 Fix tooltip position on absolute positioned elements * 🐛 Fix tests
This commit is contained in:
parent
0ceadada35
commit
c59cc4dff4
@ -94,7 +94,7 @@ test("Create a LINEAR gradient", async ({ page }) => {
|
|||||||
await expect(inputOpacityGlobal).toBeVisible();
|
await expect(inputOpacityGlobal).toBeVisible();
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
workspacePage.page.getByText("Linear gradient").nth(1),
|
workspacePage.page.getByText("Linear gradient")
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ test("Create a RADIAL gradient", async ({ page }) => {
|
|||||||
await expect(inputOpacityGlobal).toBeVisible();
|
await expect(inputOpacityGlobal).toBeVisible();
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
workspacePage.page.getByText("Radial gradient").nth(1),
|
workspacePage.page.getByText("Radial gradient")
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -83,7 +83,7 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
await brTokenPillSM.click();
|
await brTokenPillSM.click();
|
||||||
|
|
||||||
// Change token from dropdown
|
// Change token from dropdown
|
||||||
const brTokenOptionXl = borderRadiusSection.getByLabel("borderRadius.xl");
|
const brTokenOptionXl = borderRadiusSection.getByRole('option', { name: 'borderRadius.xl' })
|
||||||
await expect(brTokenOptionXl).toBeVisible();
|
await expect(brTokenOptionXl).toBeVisible();
|
||||||
await brTokenOptionXl.click();
|
await brTokenOptionXl.click();
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ 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.getByRole('button', { name: 'Open token list' })
|
||||||
await expect(dropdownBtn).toBeVisible();
|
await expect(dropdownBtn).toBeVisible();
|
||||||
await dropdownBtn.click();
|
await dropdownBtn.click();
|
||||||
|
|
||||||
@ -225,8 +225,8 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
await expect(firstShadowFields).toBeVisible();
|
await expect(firstShadowFields).toBeVisible();
|
||||||
|
|
||||||
// Fill in the shadow values
|
// Fill in the shadow values
|
||||||
const offsetXInput = firstShadowFields.getByLabel("X");
|
const offsetXInput = firstShadowFields.getByRole('textbox', { name: 'X' });
|
||||||
const offsetYInput = firstShadowFields.getByLabel("Y");
|
const offsetYInput = firstShadowFields.getByRole('textbox', { name: 'Y' });
|
||||||
const blurInput = firstShadowFields.getByRole("textbox", {
|
const blurInput = firstShadowFields.getByRole("textbox", {
|
||||||
name: "Blur",
|
name: "Blur",
|
||||||
});
|
});
|
||||||
@ -299,8 +299,8 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
await expect(thirdShadowFields).toBeVisible();
|
await expect(thirdShadowFields).toBeVisible();
|
||||||
|
|
||||||
// User adds values for the third shadow
|
// User adds values for the third shadow
|
||||||
const thirdOffsetXInput = thirdShadowFields.getByLabel("X");
|
const thirdOffsetXInput = thirdShadowFields.getByRole('textbox', { name: 'X' });
|
||||||
const thirdOffsetYInput = thirdShadowFields.getByLabel("Y");
|
const thirdOffsetYInput = thirdShadowFields.getByRole('textbox', { name: 'Y' });
|
||||||
const thirdBlurInput = thirdShadowFields.getByRole("textbox", {
|
const thirdBlurInput = thirdShadowFields.getByRole("textbox", {
|
||||||
name: "Blur",
|
name: "Blur",
|
||||||
});
|
});
|
||||||
@ -328,10 +328,10 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
|
|
||||||
// Verify that the first shadow kept its values
|
// Verify that the first shadow kept its values
|
||||||
const firstOffsetXValue = await firstShadowFields
|
const firstOffsetXValue = await firstShadowFields
|
||||||
.getByLabel("X")
|
.getByRole('textbox', { name: 'X' })
|
||||||
.inputValue();
|
.inputValue();
|
||||||
const firstOffsetYValue = await firstShadowFields
|
const firstOffsetYValue = await firstShadowFields
|
||||||
.getByLabel("Y")
|
.getByRole('textbox', { name: 'Y' })
|
||||||
.inputValue();
|
.inputValue();
|
||||||
const firstBlurValue = await firstShadowFields
|
const firstBlurValue = await firstShadowFields
|
||||||
.getByRole("textbox", { name: "Blur" })
|
.getByRole("textbox", { name: "Blur" })
|
||||||
@ -357,10 +357,10 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
await expect(newSecondShadowFields).toBeVisible();
|
await expect(newSecondShadowFields).toBeVisible();
|
||||||
|
|
||||||
const secondOffsetXValue = await newSecondShadowFields
|
const secondOffsetXValue = await newSecondShadowFields
|
||||||
.getByLabel("X")
|
.getByRole('textbox', { name: 'X' })
|
||||||
.inputValue();
|
.inputValue();
|
||||||
const secondOffsetYValue = await newSecondShadowFields
|
const secondOffsetYValue = await newSecondShadowFields
|
||||||
.getByLabel("Y")
|
.getByRole('textbox', { name: 'Y' })
|
||||||
.inputValue();
|
.inputValue();
|
||||||
const secondBlurValue = await newSecondShadowFields
|
const secondBlurValue = await newSecondShadowFields
|
||||||
.getByRole("textbox", { name: "Blur" })
|
.getByRole("textbox", { name: "Blur" })
|
||||||
@ -410,10 +410,10 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
|
|
||||||
// Verify first shadow values are still there
|
// Verify first shadow values are still there
|
||||||
const restoredFirstOffsetX = await firstShadowFields
|
const restoredFirstOffsetX = await firstShadowFields
|
||||||
.getByLabel("X")
|
.getByRole('textbox', { name: 'X' })
|
||||||
.inputValue();
|
.inputValue();
|
||||||
const restoredFirstOffsetY = await firstShadowFields
|
const restoredFirstOffsetY = await firstShadowFields
|
||||||
.getByLabel("Y")
|
.getByRole('textbox', { name: 'Y' })
|
||||||
.inputValue();
|
.inputValue();
|
||||||
const restoredFirstBlur = await firstShadowFields
|
const restoredFirstBlur = await firstShadowFields
|
||||||
.getByRole("textbox", { name: "Blur" })
|
.getByRole("textbox", { name: "Blur" })
|
||||||
@ -433,10 +433,10 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
|
|
||||||
// Verify second shadow values are still there
|
// Verify second shadow values are still there
|
||||||
const restoredSecondOffsetX = await newSecondShadowFields
|
const restoredSecondOffsetX = await newSecondShadowFields
|
||||||
.getByLabel("X")
|
.getByRole('textbox', { name: 'X' })
|
||||||
.inputValue();
|
.inputValue();
|
||||||
const restoredSecondOffsetY = await newSecondShadowFields
|
const restoredSecondOffsetY = await newSecondShadowFields
|
||||||
.getByLabel("Y")
|
.getByRole('textbox', { name: 'Y' })
|
||||||
.inputValue();
|
.inputValue();
|
||||||
const restoredSecondBlur = await newSecondShadowFields
|
const restoredSecondBlur = await newSecondShadowFields
|
||||||
.getByRole("textbox", { name: "Blur" })
|
.getByRole("textbox", { name: "Blur" })
|
||||||
@ -518,7 +518,7 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
await dimensionSMTokenPill.nth(1).click();
|
await dimensionSMTokenPill.nth(1).click();
|
||||||
|
|
||||||
// Change token from dropdown
|
// Change token from dropdown
|
||||||
const dimensionTokenOptionXl = measuresSection.getByLabel("dimension.xl");
|
const dimensionTokenOptionXl = measuresSection.getByRole('option', { name: 'dimension.xl' })
|
||||||
await expect(dimensionTokenOptionXl).toBeVisible();
|
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||||
await dimensionTokenOptionXl.click();
|
await dimensionTokenOptionXl.click();
|
||||||
|
|
||||||
@ -572,7 +572,7 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
await dimensionSMTokenPill.click();
|
await dimensionSMTokenPill.click();
|
||||||
|
|
||||||
// Change token from dropdown
|
// Change token from dropdown
|
||||||
const dimensionTokenOptionXl = measuresSection.getByLabel("dimension.xl");
|
const dimensionTokenOptionXl = measuresSection.getByRole('option', { name: 'dimension.xl' });
|
||||||
await expect(dimensionTokenOptionXl).toBeVisible();
|
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||||
await dimensionTokenOptionXl.click();
|
await dimensionTokenOptionXl.click();
|
||||||
|
|
||||||
@ -626,7 +626,7 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
await dimensionSMTokenPill.click();
|
await dimensionSMTokenPill.click();
|
||||||
|
|
||||||
// Change token from dropdown
|
// Change token from dropdown
|
||||||
const dimensionTokenOptionXl = measuresSection.getByLabel("dimension.xl");
|
const dimensionTokenOptionXl = measuresSection.getByRole('option', { name: 'dimension.xl' });
|
||||||
await expect(dimensionTokenOptionXl).toBeVisible();
|
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||||
await dimensionTokenOptionXl.click();
|
await dimensionTokenOptionXl.click();
|
||||||
|
|
||||||
@ -682,7 +682,7 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
|
|
||||||
// Change token from dropdown
|
// Change token from dropdown
|
||||||
const dimensionTokenOptionXl =
|
const dimensionTokenOptionXl =
|
||||||
borderRadiusSection.getByLabel("dimension.xl");
|
borderRadiusSection.getByRole('option', { name: 'dimension.xl' });
|
||||||
await expect(dimensionTokenOptionXl).toBeVisible();
|
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||||
await dimensionTokenOptionXl.click();
|
await dimensionTokenOptionXl.click();
|
||||||
|
|
||||||
@ -751,7 +751,7 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
});
|
});
|
||||||
await tokenDropdown.click();
|
await tokenDropdown.click();
|
||||||
|
|
||||||
const widthOptionSmall = firstStrokeRow.getByLabel("width-small");
|
const widthOptionSmall = firstStrokeRow.getByRole('option', { name: 'width-small' });
|
||||||
await expect(widthOptionSmall).toBeVisible();
|
await expect(widthOptionSmall).toBeVisible();
|
||||||
await widthOptionSmall.click();
|
await widthOptionSmall.click();
|
||||||
const StrokeWidthPillSmall = firstStrokeRow.getByRole("button", {
|
const StrokeWidthPillSmall = firstStrokeRow.getByRole("button", {
|
||||||
@ -831,15 +831,10 @@ test.describe("Tokens: Apply token", () => {
|
|||||||
});
|
});
|
||||||
await detachButton.click();
|
await detachButton.click();
|
||||||
await expect(marginPillXL).not.toBeVisible();
|
await expect(marginPillXL).not.toBeVisible();
|
||||||
const horizontalMarginInput = layoutItemSectionSidebar.getByText(
|
const horizontalMarginInput = layoutItemSectionSidebar.getByRole("button", {
|
||||||
"Horizontal marginOpen token",
|
|
||||||
);
|
|
||||||
await expect(horizontalMarginInput).toBeVisible();
|
|
||||||
|
|
||||||
const tokenDropdown = horizontalMarginInput.getByRole("button", {
|
|
||||||
name: "Open token list",
|
name: "Open token list",
|
||||||
});
|
});
|
||||||
await tokenDropdown.click();
|
await horizontalMarginInput.nth(1).click();
|
||||||
|
|
||||||
await expect(dimensionTokenOptionXl).toBeVisible();
|
await expect(dimensionTokenOptionXl).toBeVisible();
|
||||||
await dimensionTokenOptionXl.click();
|
await dimensionTokenOptionXl.click();
|
||||||
|
|||||||
@ -1024,7 +1024,7 @@ test.describe("Tokens - creation", () => {
|
|||||||
const nameField = tokensUpdateCreateModal.getByLabel("Name");
|
const nameField = tokensUpdateCreateModal.getByLabel("Name");
|
||||||
await nameField.fill("typography.empty");
|
await nameField.fill("typography.empty");
|
||||||
|
|
||||||
const valueField = tokensUpdateCreateModal.getByLabel("Font Size");
|
const valueField = tokensUpdateCreateModal.getByRole("textbox", {name: "Font Size"});
|
||||||
|
|
||||||
// Insert a value and then delete it
|
// Insert a value and then delete it
|
||||||
await valueField.fill("1");
|
await valueField.fill("1");
|
||||||
@ -1716,12 +1716,12 @@ test.describe("Tokens tab - edition", () => {
|
|||||||
|
|
||||||
// Fill font-family to verify to verify that input value doesn't get split into list of characters
|
// Fill font-family to verify to verify that input value doesn't get split into list of characters
|
||||||
const fontFamilyField = tokensUpdateCreateModal
|
const fontFamilyField = tokensUpdateCreateModal
|
||||||
.getByLabel("Font family")
|
.getByRole("textbox", { name: "Font family" })
|
||||||
.first();
|
.first();
|
||||||
await fontFamilyField.fill("OneWord");
|
await fontFamilyField.fill("OneWord");
|
||||||
|
|
||||||
// Invalidate incorrect values for font size
|
// Invalidate incorrect values for font size
|
||||||
const fontSizeField = tokensUpdateCreateModal.getByLabel(/Font Size/i);
|
const fontSizeField = tokensUpdateCreateModal.getByRole("textbox", { name: "Font Size" });
|
||||||
await fontSizeField.fill("invalid");
|
await fontSizeField.fill("invalid");
|
||||||
await expect(
|
await expect(
|
||||||
tokensUpdateCreateModal.getByText(/Invalid token value:/),
|
tokensUpdateCreateModal.getByText(/Invalid token value:/),
|
||||||
@ -1736,13 +1736,13 @@ test.describe("Tokens tab - edition", () => {
|
|||||||
await fontSizeField.fill("16");
|
await fontSizeField.fill("16");
|
||||||
await expect(saveButton).toBeEnabled();
|
await expect(saveButton).toBeEnabled();
|
||||||
|
|
||||||
const fontWeightField = tokensUpdateCreateModal.getByLabel(/Font Weight/i);
|
const fontWeightField = tokensUpdateCreateModal.getByRole("textbox", { name: "Font Weight" });
|
||||||
const letterSpacingField =
|
const letterSpacingField =
|
||||||
tokensUpdateCreateModal.getByLabel(/Letter Spacing/i);
|
tokensUpdateCreateModal.getByRole("textbox", { name: "Letter Spacing" });
|
||||||
const lineHeightField = tokensUpdateCreateModal.getByLabel(/Line Height/i);
|
const lineHeightField = tokensUpdateCreateModal.getByRole("textbox", { name: "Line Height" });
|
||||||
const textCaseField = tokensUpdateCreateModal.getByLabel(/Text Case/i);
|
const textCaseField = tokensUpdateCreateModal.getByRole("textbox", { name: "Text Case" });
|
||||||
const textDecorationField =
|
const textDecorationField =
|
||||||
tokensUpdateCreateModal.getByLabel(/Text Decoration/i);
|
tokensUpdateCreateModal.getByRole("textbox", { name: "Text Decoration" });
|
||||||
|
|
||||||
// Capture all values before switching tabs
|
// Capture all values before switching tabs
|
||||||
const originalValues = {
|
const originalValues = {
|
||||||
@ -1800,6 +1800,7 @@ test.describe("Tokens tab - edition", () => {
|
|||||||
const colorToken = tokensSidebar.getByRole("button", {
|
const colorToken = tokensSidebar.getByRole("button", {
|
||||||
name: "100",
|
name: "100",
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(colorToken).toBeVisible();
|
await expect(colorToken).toBeVisible();
|
||||||
await colorToken.click({ button: "right" });
|
await colorToken.click({ button: "right" });
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,8 @@
|
|||||||
(let [variant
|
(let [variant
|
||||||
(d/nilv variant "primary")
|
(d/nilv variant "primary")
|
||||||
|
|
||||||
|
button-ref (mf/use-ref nil)
|
||||||
|
|
||||||
tooltip-id
|
tooltip-id
|
||||||
(mf/use-id)
|
(mf/use-id)
|
||||||
|
|
||||||
@ -47,10 +49,12 @@
|
|||||||
props
|
props
|
||||||
(mf/spread-props props
|
(mf/spread-props props
|
||||||
{:class [class button-class]
|
{:class [class button-class]
|
||||||
|
:ref button-ref
|
||||||
:aria-labelledby tooltip-id})]
|
:aria-labelledby tooltip-id})]
|
||||||
|
|
||||||
[:> tooltip* {:content aria-label
|
[:> tooltip* {:content aria-label
|
||||||
:class tooltip-class
|
:class tooltip-class
|
||||||
|
:trigger-ref button-ref
|
||||||
:placement tooltip-placement
|
:placement tooltip-placement
|
||||||
:id tooltip-id}
|
:id tooltip-id}
|
||||||
[:> :button props
|
[:> :button props
|
||||||
|
|||||||
@ -28,7 +28,8 @@
|
|||||||
{::mf/schema schema:token-option}
|
{::mf/schema schema:token-option}
|
||||||
[{:keys [id name on-click selected ref focused resolved] :rest props}]
|
[{:keys [id name on-click selected ref focused resolved] :rest props}]
|
||||||
(let [internal-id (mf/use-id)
|
(let [internal-id (mf/use-id)
|
||||||
id (d/nilv id internal-id)]
|
id (d/nilv id internal-id)
|
||||||
|
element-ref (mf/use-ref nil)]
|
||||||
[:li {:value id
|
[:li {:value id
|
||||||
:class (stl/css-case :token-option true
|
:class (stl/css-case :token-option true
|
||||||
:option-with-pill true
|
:option-with-pill true
|
||||||
@ -50,10 +51,12 @@
|
|||||||
:aria-hidden (when name true)}]
|
:aria-hidden (when name true)}]
|
||||||
[:span {:class (stl/css :icon-placeholder)}])
|
[:span {:class (stl/css :icon-placeholder)}])
|
||||||
[:> tooltip* {:content name
|
[:> tooltip* {:content name
|
||||||
|
:trigger-ref element-ref
|
||||||
:id (dm/str id "-name")
|
:id (dm/str id "-name")
|
||||||
:class (stl/css :option-text)}
|
:class (stl/css :option-text)}
|
||||||
;; Add ellipsis
|
;; Add ellipsis
|
||||||
[:span {:aria-labelledby (dm/str id "-name")}
|
[:span {:aria-labelledby (dm/str id "-name")
|
||||||
|
:ref element-ref}
|
||||||
name]]
|
name]]
|
||||||
(when resolved
|
(when resolved
|
||||||
[:> :span {:class (stl/css :option-pill)}
|
[:> :span {:class (stl/css :option-pill)}
|
||||||
|
|||||||
@ -84,6 +84,7 @@
|
|||||||
:on-click on-icon-click}])
|
:on-click on-icon-click}])
|
||||||
(if aria-label
|
(if aria-label
|
||||||
[:> tooltip* {:content aria-label
|
[:> tooltip* {:content aria-label
|
||||||
|
:trigger-ref (or ref input-ref)
|
||||||
:class (stl/css :tooltip-wrapper)
|
:class (stl/css :tooltip-wrapper)
|
||||||
:id tooltip-id}
|
:id tooltip-id}
|
||||||
[:> "input" props]]
|
[:> "input" props]]
|
||||||
|
|||||||
@ -43,6 +43,7 @@
|
|||||||
(tr "ds.inputs.token-field.no-active-token-option"))
|
(tr "ds.inputs.token-field.no-active-token-option"))
|
||||||
default-id (mf/use-id)
|
default-id (mf/use-id)
|
||||||
id (d/nilv id default-id)
|
id (d/nilv id default-id)
|
||||||
|
pill-ref (mf/use-ref nil)
|
||||||
|
|
||||||
focus-wrapper
|
focus-wrapper
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@ -53,6 +54,7 @@
|
|||||||
(dom/focus! (mf/ref-val token-wrapper-ref)))))]
|
(dom/focus! (mf/ref-val token-wrapper-ref)))))]
|
||||||
[:> tooltip* {:content property
|
[:> tooltip* {:content property
|
||||||
:class (stl/css :token-field-wrapper)
|
:class (stl/css :token-field-wrapper)
|
||||||
|
:trigger-ref token-wrapper-ref
|
||||||
:id (dm/str default-id "-input")}
|
:id (dm/str default-id "-input")}
|
||||||
[:div {:class [class (stl/css-case :token-field true
|
[:div {:class [class (stl/css-case :token-field true
|
||||||
:with-icon (some? slot-start)
|
:with-icon (some? slot-start)
|
||||||
@ -70,8 +72,10 @@
|
|||||||
|
|
||||||
[:div {:class (stl/css :content-wrapper)}
|
[:div {:class (stl/css :content-wrapper)}
|
||||||
[:> tooltip* {:content content
|
[:> tooltip* {:content content
|
||||||
|
:trigger-ref pill-ref
|
||||||
:id (dm/str id "-pill")}
|
:id (dm/str id "-pill")}
|
||||||
[:button {:on-click on-click
|
[:button {:on-click on-click
|
||||||
|
:ref pill-ref
|
||||||
:class (stl/css-case :pill true
|
:class (stl/css-case :pill true
|
||||||
:no-set-pill (not set-active?)
|
:no-set-pill (not set-active?)
|
||||||
:pill-disabled disabled)
|
:pill-disabled disabled)
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
(ns app.main.ui.ds.tooltip.tooltip
|
(ns app.main.ui.ds.tooltip.tooltip
|
||||||
(:require-macros
|
(:require-macros
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.main.style :as stl])
|
[app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
@ -15,10 +14,10 @@
|
|||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def ^:private ^:const arrow-height 12)
|
|
||||||
(def ^:private ^:const half-arrow-height (/ arrow-height 2))
|
|
||||||
(def ^:private ^:const overlay-offset 32)
|
(def ^:private ^:const overlay-offset 32)
|
||||||
|
|
||||||
|
(defonce active-tooltip (atom nil))
|
||||||
|
|
||||||
(defn- clear-schedule
|
(defn- clear-schedule
|
||||||
[ref]
|
[ref]
|
||||||
(when-let [schedule (mf/ref-val ref)]
|
(when-let [schedule (mf/ref-val ref)]
|
||||||
@ -29,20 +28,6 @@
|
|||||||
[ref delay f]
|
[ref delay f]
|
||||||
(mf/set-ref-val! ref (ts/schedule delay f)))
|
(mf/set-ref-val! ref (ts/schedule delay f)))
|
||||||
|
|
||||||
(defn- show-popover
|
|
||||||
[node]
|
|
||||||
(when (.-isConnected ^js node)
|
|
||||||
(.showPopover ^js node)))
|
|
||||||
|
|
||||||
(defn- hide-popover
|
|
||||||
[node]
|
|
||||||
(when (and (some? node)
|
|
||||||
(fn? (.-hidePopover node)))
|
|
||||||
(dom/unset-css-property! node "block-size")
|
|
||||||
(dom/unset-css-property! node "inset-block-start")
|
|
||||||
(dom/unset-css-property! node "inset-inline-start")
|
|
||||||
(.hidePopover ^js node)))
|
|
||||||
|
|
||||||
(defn- calculate-placement-bounding-rect
|
(defn- calculate-placement-bounding-rect
|
||||||
"Given a placement, calcultates the bounding rect for it taking in
|
"Given a placement, calcultates the bounding rect for it taking in
|
||||||
account provided tooltip bounding rect and the origin bounding
|
account provided tooltip bounding rect and the origin bounding
|
||||||
@ -72,18 +57,18 @@
|
|||||||
:height tooltip-height}
|
:height tooltip-height}
|
||||||
|
|
||||||
"left"
|
"left"
|
||||||
{:top (- (+ trigger-top (/ trigger-height 2) half-arrow-height) (/ tooltip-height 2))
|
{:top (- (+ trigger-top (/ trigger-height 2)) (/ tooltip-height 2))
|
||||||
:left (- trigger-left tooltip-width arrow-height)
|
:left (- trigger-left tooltip-width)
|
||||||
:right (+ (- trigger-left tooltip-width) tooltip-width)
|
:right (+ (- trigger-left tooltip-width) tooltip-width)
|
||||||
:bottom (+ (- (+ trigger-top (/ trigger-height 2) half-arrow-height) (/ tooltip-height 2)) tooltip-height)
|
:bottom (+ (- (+ trigger-top (/ trigger-height 2)) (/ tooltip-height 2)) tooltip-height)
|
||||||
:width tooltip-width
|
:width tooltip-width
|
||||||
:height tooltip-height}
|
:height tooltip-height}
|
||||||
|
|
||||||
"right"
|
"right"
|
||||||
{:top (- (+ trigger-top (/ trigger-height 2) half-arrow-height) (/ tooltip-height 2))
|
{:top (- (+ trigger-top (/ trigger-height 2)) (/ tooltip-height 2))
|
||||||
:left (+ trigger-right offset)
|
:left (+ trigger-right offset)
|
||||||
:right (+ trigger-right offset tooltip-width)
|
:right (+ trigger-right offset tooltip-width)
|
||||||
:bottom (+ (- (+ trigger-top (/ trigger-height 2) half-arrow-height) (/ tooltip-height 2)) tooltip-height)
|
:bottom (+ (- (+ trigger-top (/ trigger-height 2)) (/ tooltip-height 2)) tooltip-height)
|
||||||
:width tooltip-width
|
:width tooltip-width
|
||||||
:height tooltip-height}
|
:height tooltip-height}
|
||||||
|
|
||||||
@ -153,22 +138,6 @@
|
|||||||
(recur (rest placements))
|
(recur (rest placements))
|
||||||
#js [placement placement-brect])))))
|
#js [placement placement-brect])))))
|
||||||
|
|
||||||
(defn- update-tooltip-position
|
|
||||||
"Update the tooltip position having in account the current window
|
|
||||||
size, placement. It calculates the appropriate placement and updates
|
|
||||||
the dom with the result."
|
|
||||||
[tooltip placement origin-brect offset]
|
|
||||||
(show-popover tooltip)
|
|
||||||
(let [tooltip-brect (dom/get-bounding-rect tooltip)
|
|
||||||
tooltip-brect (assoc tooltip-brect :height (:height tooltip-brect) :width (:width tooltip-brect))
|
|
||||||
window-size (dom/get-window-size)]
|
|
||||||
(when-let [[placement placement-rect] (find-matching-placement placement tooltip-brect origin-brect window-size offset)]
|
|
||||||
(let [height (:height placement-rect)]
|
|
||||||
(dom/set-css-property! tooltip "block-size" (dm/str height "px"))
|
|
||||||
(dom/set-css-property! tooltip "inset-block-start" (dm/str (:top placement-rect) "px"))
|
|
||||||
(dom/set-css-property! tooltip "inset-inline-start" (dm/str (:left placement-rect) "px")))
|
|
||||||
placement)))
|
|
||||||
|
|
||||||
(def ^:private schema:tooltip
|
(def ^:private schema:tooltip
|
||||||
[:map
|
[:map
|
||||||
[:class {:optional true} [:maybe :string]]
|
[:class {:optional true} [:maybe :string]]
|
||||||
@ -176,19 +145,26 @@
|
|||||||
[:offset {:optional true} :int]
|
[:offset {:optional true} :int]
|
||||||
[:delay {:optional true} :int]
|
[:delay {:optional true} :int]
|
||||||
[:content [:or fn? :string map?]]
|
[:content [:or fn? :string map?]]
|
||||||
|
[:trigger-ref {:optional true} [:maybe :any]]
|
||||||
[:placement {:optional true}
|
[:placement {:optional true}
|
||||||
[:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]]])
|
[:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]]])
|
||||||
|
|
||||||
(mf/defc tooltip*
|
(mf/defc tooltip*
|
||||||
{::mf/schema schema:tooltip}
|
{::mf/schema schema:tooltip}
|
||||||
[{:keys [class id children content placement offset delay] :rest props}]
|
[{:keys [class id children content placement offset delay trigger-ref aria-label] :rest props}]
|
||||||
(let [internal-id
|
(let [internal-id
|
||||||
(mf/use-id)
|
(mf/use-id)
|
||||||
trigger-ref (mf/use-ref nil)
|
internal-trigger-ref (mf/use-ref nil)
|
||||||
|
trigger-ref (or trigger-ref internal-trigger-ref)
|
||||||
|
|
||||||
|
tooltip-ref (mf/use-ref nil)
|
||||||
|
|
||||||
id
|
id
|
||||||
(d/nilv id internal-id)
|
(d/nilv id internal-id)
|
||||||
|
|
||||||
|
tooltip-id
|
||||||
|
(mf/use-id)
|
||||||
|
|
||||||
placement*
|
placement*
|
||||||
(mf/use-state #(d/nilv placement "top"))
|
(mf/use-state #(d/nilv placement "top"))
|
||||||
|
|
||||||
@ -201,35 +177,35 @@
|
|||||||
schedule-ref
|
schedule-ref
|
||||||
(mf/use-ref nil)
|
(mf/use-ref nil)
|
||||||
|
|
||||||
|
visible*
|
||||||
|
(mf/use-state false)
|
||||||
|
visible (deref visible*)
|
||||||
|
|
||||||
on-show
|
on-show
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps id placement offset)
|
(mf/deps tooltip-id delay)
|
||||||
(fn [event]
|
(fn [_]
|
||||||
|
(let [trigger-el (mf/ref-val trigger-ref)]
|
||||||
(let [current (dom/get-current-target event)
|
(clear-schedule schedule-ref)
|
||||||
related (dom/get-related-target event)
|
(add-schedule schedule-ref (d/nilv delay 300)
|
||||||
is-node? (fn [node] (and node (.-nodeType node)))]
|
(fn []
|
||||||
(when-not (and related (is-node? related) (.contains current related))
|
(prn tooltip-id)
|
||||||
(clear-schedule schedule-ref)
|
(when-let [active @active-tooltip]
|
||||||
(when-let [tooltip (dom/get-element id)]
|
(when (not= (:id active) tooltip-id)
|
||||||
(let [origin-brect
|
(when-let [tooltip-el (dom/get-element (:id active))]
|
||||||
(dom/get-bounding-rect (mf/ref-val trigger-ref))
|
(dom/set-css-property! tooltip-el "display" "none"))
|
||||||
|
(reset! active-tooltip nil)))
|
||||||
update-position
|
(reset! active-tooltip {:id tooltip-id :trigger trigger-el})
|
||||||
(fn []
|
(reset! visible* true))))))
|
||||||
(let [new-placement (update-tooltip-position tooltip placement origin-brect offset)]
|
|
||||||
(when (not= new-placement placement)
|
|
||||||
(reset! placement* new-placement))))]
|
|
||||||
|
|
||||||
(add-schedule schedule-ref delay update-position)))))))
|
|
||||||
|
|
||||||
on-hide
|
on-hide
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps id)
|
(mf/deps tooltip-id)
|
||||||
(fn []
|
(fn []
|
||||||
(when-let [tooltip (dom/get-element id)]
|
(clear-schedule schedule-ref)
|
||||||
(clear-schedule schedule-ref)
|
(reset! visible* false)
|
||||||
(hide-popover tooltip))))
|
(when (= (:id @active-tooltip) tooltip-id)
|
||||||
|
(reset! active-tooltip nil))))
|
||||||
|
|
||||||
handle-key-down
|
handle-key-down
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@ -250,28 +226,62 @@
|
|||||||
:tooltip-bottom-left (identical? placement "bottom-left")
|
:tooltip-bottom-left (identical? placement "bottom-left")
|
||||||
:tooltip-top-left (identical? placement "top-left"))
|
:tooltip-top-left (identical? placement "top-left"))
|
||||||
|
|
||||||
|
content
|
||||||
|
(if (fn? content)
|
||||||
|
(content)
|
||||||
|
content)
|
||||||
props
|
props
|
||||||
(mf/spread-props props
|
(mf/spread-props props
|
||||||
{:on-mouse-enter on-show
|
{:on-mouse-enter on-show
|
||||||
:on-mouse-leave on-hide
|
:on-mouse-leave on-hide
|
||||||
:on-focus on-show
|
:on-focus on-show
|
||||||
:on-blur on-hide
|
:on-blur on-hide
|
||||||
|
:ref internal-trigger-ref
|
||||||
:on-key-down handle-key-down
|
:on-key-down handle-key-down
|
||||||
:ref trigger-ref
|
:id id
|
||||||
:class [class (stl/css :tooltip-trigger)]
|
:class [class (stl/css :tooltip-trigger)]
|
||||||
:aria-describedby id})
|
:aria-label (if (string? content)
|
||||||
content
|
content
|
||||||
(if (fn? content)
|
aria-label)})]
|
||||||
(content)
|
|
||||||
content)]
|
(mf/use-effect
|
||||||
|
(mf/deps visible placement offset)
|
||||||
|
(fn []
|
||||||
|
(when visible
|
||||||
|
(let [trigger-el (mf/ref-val trigger-ref)
|
||||||
|
tooltip-el (mf/ref-val tooltip-ref)]
|
||||||
|
(when (and trigger-el tooltip-el)
|
||||||
|
(js/requestAnimationFrame
|
||||||
|
(fn []
|
||||||
|
(let [origin-brect (dom/get-bounding-rect trigger-el)
|
||||||
|
tooltip-brect (dom/get-bounding-rect tooltip-el)
|
||||||
|
window-size (dom/get-window-size)]
|
||||||
|
(when-let [[new-placement placement-rect]
|
||||||
|
(find-matching-placement
|
||||||
|
placement
|
||||||
|
tooltip-brect
|
||||||
|
origin-brect
|
||||||
|
window-size
|
||||||
|
offset)]
|
||||||
|
(dom/set-css-property! tooltip-el "inset-block-start"
|
||||||
|
(str (:top placement-rect) "px"))
|
||||||
|
(dom/set-css-property! tooltip-el "inset-inline-start"
|
||||||
|
(str (:left placement-rect) "px"))
|
||||||
|
|
||||||
|
(when (not= new-placement placement)
|
||||||
|
(reset! placement* new-placement)))))))))))
|
||||||
|
|
||||||
[:> :div props
|
[:> :div props
|
||||||
children
|
children
|
||||||
[:div {:class (stl/css :tooltip)
|
(when visible
|
||||||
:id id
|
(mf/portal
|
||||||
:popover "auto"
|
(mf/html
|
||||||
:role "tooltip"}
|
[:div {:class (stl/css :tooltip)
|
||||||
[:div {:class tooltip-class}
|
:role "tooltip"
|
||||||
[:div {:class (stl/css :tooltip-content)} content]
|
:id tooltip-id
|
||||||
[:div {:class (stl/css :tooltip-arrow)
|
:ref tooltip-ref}
|
||||||
:id "tooltip-arrow"}]]]]))
|
[:div {:class tooltip-class}
|
||||||
|
[:div {:class (stl/css :tooltip-content)} content]
|
||||||
|
[:div {:class (stl/css :tooltip-arrow)
|
||||||
|
:id "tooltip-arrow"}]]])
|
||||||
|
(.-body js/document)))]))
|
||||||
|
|||||||
@ -6,17 +6,19 @@
|
|||||||
|
|
||||||
@use "ds/_sizes.scss" as *;
|
@use "ds/_sizes.scss" as *;
|
||||||
@use "ds/_borders.scss" as *;
|
@use "ds/_borders.scss" as *;
|
||||||
|
@use "ds/z-index.scss" as *;
|
||||||
@use "ds/typography.scss" as t;
|
@use "ds/typography.scss" as t;
|
||||||
|
|
||||||
$arrow-side: 12px;
|
$arrow-side: 12px;
|
||||||
|
|
||||||
.tooltip {
|
.tooltip {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
max-inline-size: $sz-352;
|
max-inline-size: $sz-352;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
inline-size: fit-content;
|
inline-size: fit-content;
|
||||||
block-size: fit-content;
|
block-size: fit-content;
|
||||||
|
z-index: var(--z-index-notifications);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-content-wrapper {
|
.tooltip-content-wrapper {
|
||||||
|
|||||||
@ -96,8 +96,9 @@
|
|||||||
image (:image background)
|
image (:image background)
|
||||||
format (if id? "rounded" "square")
|
format (if id? "rounded" "square")
|
||||||
element-id (mf/use-id)
|
element-id (mf/use-id)
|
||||||
has-opacity? (and (some? (:color background))
|
has-opacity? (and (some? (:color background))
|
||||||
(< (:opacity background) 1))
|
(< (:opacity background) 1))
|
||||||
|
element-ref (mf/use-ref nil)
|
||||||
on-click
|
on-click
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps background on-click)
|
(mf/deps background on-click)
|
||||||
@ -120,7 +121,8 @@
|
|||||||
(mf/spread-props props {:class class
|
(mf/spread-props props {:class class
|
||||||
:on-click on-click
|
:on-click on-click
|
||||||
:type button-type
|
:type button-type
|
||||||
:aria-labelledby element-id})
|
:aria-labelledby element-id
|
||||||
|
:ref element-ref})
|
||||||
children (mf/html
|
children (mf/html
|
||||||
[:> element-type props
|
[:> element-type props
|
||||||
(cond
|
(cond
|
||||||
@ -147,6 +149,7 @@
|
|||||||
[:> tooltip* {:content (if tooltip-content
|
[:> tooltip* {:content (if tooltip-content
|
||||||
tooltip-content
|
tooltip-content
|
||||||
(color-title background))
|
(color-title background))
|
||||||
|
:trigger-ref element-ref
|
||||||
:id element-id}
|
:id element-id}
|
||||||
children]
|
children]
|
||||||
|
|
||||||
|
|||||||
@ -23,11 +23,12 @@
|
|||||||
|
|
||||||
(mf/defc property-detail-copiable*
|
(mf/defc property-detail-copiable*
|
||||||
{::mf/schema schema:property-detail-copiable}
|
{::mf/schema schema:property-detail-copiable}
|
||||||
[{:keys [color token copied on-click children]}]
|
[{:keys [color token copied on-click children ref]}]
|
||||||
[:button {:class (stl/css-case :property-detail-copiable true
|
[:button {:class (stl/css-case :property-detail-copiable true
|
||||||
:property-detail-copied copied
|
:property-detail-copied copied
|
||||||
:property-detail-copiable-color (some? color))
|
:property-detail-copiable-color (some? color))
|
||||||
:on-click on-click}
|
:on-click on-click
|
||||||
|
:ref ref}
|
||||||
(when color
|
(when color
|
||||||
[:> swatch* {:background color
|
[:> swatch* {:background color
|
||||||
:size "small"}])
|
:size "small"}])
|
||||||
|
|||||||
@ -41,6 +41,7 @@
|
|||||||
color-image-name (:name color-image)
|
color-image-name (:name color-image)
|
||||||
color-image-url (when (some? color-image)
|
color-image-url (when (some? color-image)
|
||||||
(cfg/resolve-file-media color-image))
|
(cfg/resolve-file-media color-image))
|
||||||
|
row-ref (mf/use-ref nil)
|
||||||
color-opacity (mf/use-memo
|
color-opacity (mf/use-memo
|
||||||
(mf/deps color)
|
(mf/deps color)
|
||||||
#(dm/str (-> color
|
#(dm/str (-> color
|
||||||
@ -96,6 +97,7 @@
|
|||||||
(if token
|
(if token
|
||||||
[:> tooltip* {:id (:name token)
|
[:> tooltip* {:id (:name token)
|
||||||
:class (stl/css :tooltip-token-wrapper)
|
:class (stl/css :tooltip-token-wrapper)
|
||||||
|
:trigger-ref row-ref
|
||||||
:content #(mf/html
|
:content #(mf/html
|
||||||
[:div {:class (stl/css :tooltip-token)}
|
[:div {:class (stl/css :tooltip-token)}
|
||||||
[:div {:class (stl/css :tooltip-token-title)}
|
[:div {:class (stl/css :tooltip-token-title)}
|
||||||
@ -104,6 +106,7 @@
|
|||||||
(:resolved-value token)]])}
|
(:resolved-value token)]])}
|
||||||
[:> property-detail-copiable* {:color color
|
[:> property-detail-copiable* {:color color
|
||||||
:token token
|
:token token
|
||||||
|
:ref row-ref
|
||||||
:copied copied
|
:copied copied
|
||||||
:on-click copy-attr} formatted-color-value]]
|
:on-click copy-attr} formatted-color-value]]
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
copiable-value (if (some? token)
|
copiable-value (if (some? token)
|
||||||
(:name token)
|
(:name token)
|
||||||
property)
|
property)
|
||||||
|
row-ref (mf/use-ref nil)
|
||||||
|
|
||||||
copy-attr
|
copy-attr
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@ -54,6 +55,7 @@
|
|||||||
(let [token-type (:type token)]
|
(let [token-type (:type token)]
|
||||||
[:> tooltip* {:id (:name token)
|
[:> tooltip* {:id (:name token)
|
||||||
:class (stl/css :tooltip-token-wrapper)
|
:class (stl/css :tooltip-token-wrapper)
|
||||||
|
:trigger-ref row-ref
|
||||||
:content #(mf/html
|
:content #(mf/html
|
||||||
[:div {:class (stl/css :tooltip-token)}
|
[:div {:class (stl/css :tooltip-token)}
|
||||||
[:div {:class (stl/css :tooltip-token-title)}
|
[:div {:class (stl/css :tooltip-token-title)}
|
||||||
@ -75,6 +77,7 @@
|
|||||||
(:resolved-value token))]])}
|
(:resolved-value token))]])}
|
||||||
[:> property-detail-copiable* {:token token
|
[:> property-detail-copiable* {:token token
|
||||||
:copied copied
|
:copied copied
|
||||||
|
:ref row-ref
|
||||||
:on-click copy-attr} detail]])
|
:on-click copy-attr} detail]])
|
||||||
[:> property-detail-copiable* {:copied copied
|
[:> property-detail-copiable* {:copied copied
|
||||||
:on-click copy-attr} detail])
|
:on-click copy-attr} detail])
|
||||||
|
|||||||
@ -44,12 +44,15 @@
|
|||||||
(on-token-pill-click event token)))
|
(on-token-pill-click event token)))
|
||||||
id-tooltip (mf/use-id)
|
id-tooltip (mf/use-id)
|
||||||
resolved (:resolved-value token)
|
resolved (:resolved-value token)
|
||||||
color-value (dwta/value->color resolved)]
|
color-value (dwta/value->color resolved)
|
||||||
|
item-ref (mf/use-ref nil)]
|
||||||
[:> tooltip* {:id id-tooltip
|
[:> tooltip* {:id id-tooltip
|
||||||
:style {:width "100%"}
|
:style {:width "100%"}
|
||||||
|
:trigger-ref item-ref
|
||||||
:content (:name token)}
|
:content (:name token)}
|
||||||
[:button {:class (stl/css-case :color-token-item true
|
[:button {:class (stl/css-case :color-token-item true
|
||||||
:color-token-selected selected)
|
:color-token-selected selected)
|
||||||
|
:ref item-ref
|
||||||
:aria-labelledby id-tooltip
|
:aria-labelledby id-tooltip
|
||||||
:on-click on-click}
|
:on-click on-click}
|
||||||
[:> swatch* {:background color-value
|
[:> swatch* {:background color-value
|
||||||
|
|||||||
@ -94,6 +94,7 @@
|
|||||||
not-active (or (empty? active-tokens)
|
not-active (or (empty? active-tokens)
|
||||||
(nil? token))
|
(nil? token))
|
||||||
id (dm/str (:id token) "-name")
|
id (dm/str (:id token) "-name")
|
||||||
|
token-name-ref (mf/use-ref nil)
|
||||||
swatch-tooltip-content (cond
|
swatch-tooltip-content (cond
|
||||||
not-active
|
not-active
|
||||||
(tr "ds.inputs.token-field.no-active-token-option")
|
(tr "ds.inputs.token-field.no-active-token-option")
|
||||||
@ -126,8 +127,11 @@
|
|||||||
:size "small"}]]
|
:size "small"}]]
|
||||||
[:> tooltip* {:content name-tooltip-content
|
[:> tooltip* {:content name-tooltip-content
|
||||||
:id id
|
:id id
|
||||||
|
:aria-label (str (tr "workspace.tokens.token-name") ": " applied-token-name)
|
||||||
|
:trigger-ref token-name-ref
|
||||||
:class (stl/css :token-tooltip)}
|
:class (stl/css :token-tooltip)}
|
||||||
[:div {:class (stl/css :token-name)
|
[:div {:class (stl/css :token-name)
|
||||||
|
:ref token-name-ref
|
||||||
:aria-labelledby id}
|
:aria-labelledby id}
|
||||||
(or token-name applied-token-name)]]
|
(or token-name applied-token-name)]]
|
||||||
[:div {:class (stl/css :token-actions)}
|
[:div {:class (stl/css :token-actions)}
|
||||||
|
|||||||
@ -4,17 +4,27 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) KALEIDOS INC
|
// Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
@use "refactor/common-refactor.scss" as deprecated;
|
@use "ds/_sizes.scss" as *;
|
||||||
|
@use "ds/_borders.scss" as *;
|
||||||
|
@use "ds/_utils.scss" as *;
|
||||||
|
@use "ds/z-index.scss" as *;
|
||||||
|
|
||||||
.token-modal-wrapper {
|
.token-modal-wrapper {
|
||||||
@extend .modal-container-base;
|
border-radius: $br-4;
|
||||||
@include deprecated.menuShadow;
|
background-color: var(--color-background-primary);
|
||||||
|
border: $b-2 solid var(--color-background-quaternary);
|
||||||
|
min-width: $sz-364;
|
||||||
|
min-height: $sz-192;
|
||||||
|
max-width: $sz-512;
|
||||||
|
max-height: $sz-512;
|
||||||
|
box-shadow: 0px 0px $sz-12 0px var(--color-shadow-dark);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
z-index: 11;
|
z-index: var(--z-index-set);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
padding: var(--sp-xxxl);
|
||||||
&.token-modal-large {
|
&.token-modal-large {
|
||||||
max-block-size: 95vh;
|
max-block-size: 95vh;
|
||||||
}
|
}
|
||||||
@ -22,6 +32,6 @@
|
|||||||
|
|
||||||
.close-btn {
|
.close-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: deprecated.$s-6;
|
top: px2rem(6);
|
||||||
right: deprecated.$s-6;
|
right: px2rem(6);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user