-`;
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Actions-dark-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Actions-dark-webkit-linux.png
index 22662c78ce..bcff46683a 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Actions-dark-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Actions-dark-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Actions-light-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Actions-light-webkit-linux.png
index ddb715266e..1546209bb4 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Actions-light-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Actions-light-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Align-dark-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Align-dark-webkit-linux.png
index cd2f7a967e..a870201613 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Align-dark-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Align-dark-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Align-light-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Align-light-webkit-linux.png
index 3165c09058..3b7844421d 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Align-light-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Align-light-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Corners-dark-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Corners-dark-webkit-linux.png
index 6bfecc9f2a..818bd9fc88 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Corners-dark-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Corners-dark-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Corners-light-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Corners-light-webkit-linux.png
index 014d6d9c96..5555a0ac9f 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Corners-light-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Corners-light-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-CustomIcon-dark-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-CustomIcon-dark-webkit-linux.png
index a60404d8d7..7721606c12 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-CustomIcon-dark-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-CustomIcon-dark-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-CustomIcon-light-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-CustomIcon-light-webkit-linux.png
index 500fe9c0f7..ba596f9e85 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-CustomIcon-light-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-CustomIcon-light-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Default-dark-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Default-dark-webkit-linux.png
index 323bc6ec98..2197572f2a 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Default-dark-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Default-dark-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Default-light-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Default-light-webkit-linux.png
index df6c3d6261..be6700968d 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Default-light-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Default-light-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Layout-dark-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Layout-dark-webkit-linux.png
index 80ae0401b6..062b888cb2 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Layout-dark-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Layout-dark-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Layout-light-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Layout-light-webkit-linux.png
index 670093f2ce..a1974b8dd8 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Layout-light-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Layout-light-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Theme-dark-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Theme-dark-webkit-linux.png
index 88f097a29f..f569f0533c 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Theme-dark-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Theme-dark-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Theme-light-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Theme-light-webkit-linux.png
index 53dffcb9cf..eeeea5772d 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Theme-light-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-Theme-light-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-View-dark-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-View-dark-webkit-linux.png
index 728fb379b8..1d2284cfaf 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-View-dark-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-View-dark-webkit-linux.png differ
diff --git a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-View-light-webkit-linux.png b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-View-light-webkit-linux.png
index 2cddb8d6d2..34fe810dd4 100644
Binary files a/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-View-light-webkit-linux.png and b/src/components/Alert/__snapshots__/Alert.visual.test.tsx-snapshots/Alert-render-story-View-light-webkit-linux.png differ
diff --git a/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Showcase-1-webkit-linux.png b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Showcase-1-webkit-linux.png
index fa62a36eea..32c6a4708c 100644
Binary files a/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Showcase-1-webkit-linux.png and b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Showcase-1-webkit-linux.png differ
diff --git a/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Text-1-webkit-linux.png b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Text-1-webkit-linux.png
index 15f6aba578..ecef4ac4b8 100644
Binary files a/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Text-1-webkit-linux.png and b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Text-1-webkit-linux.png differ
diff --git a/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-TextInitials-1-webkit-linux.png b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-TextInitials-1-webkit-linux.png
index c36ea7324d..e9619e35bd 100644
Binary files a/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-TextInitials-1-webkit-linux.png and b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-TextInitials-1-webkit-linux.png differ
diff --git a/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-MoreButton-dark-webkit-linux.png b/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-MoreButton-dark-webkit-linux.png
index 2ab381bc7e..73170626c8 100644
Binary files a/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-MoreButton-dark-webkit-linux.png and b/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-MoreButton-dark-webkit-linux.png differ
diff --git a/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-MoreButton-light-webkit-linux.png b/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-MoreButton-light-webkit-linux.png
index 1226f21dc4..641a746118 100644
Binary files a/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-MoreButton-light-webkit-linux.png and b/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-MoreButton-light-webkit-linux.png differ
diff --git a/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-Total-dark-webkit-linux.png b/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-Total-dark-webkit-linux.png
index 952ac4cc4f..ad35bb7e64 100644
Binary files a/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-Total-dark-webkit-linux.png and b/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-Total-dark-webkit-linux.png differ
diff --git a/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-Total-light-webkit-linux.png b/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-Total-light-webkit-linux.png
index 13f4f18ffb..6e2002b93e 100644
Binary files a/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-Total-light-webkit-linux.png and b/src/components/AvatarStack/__snapshots__/AvatarStack.visual.test.tsx-snapshots/AvatarStack-render-story-Total-light-webkit-linux.png differ
diff --git a/src/components/Button/Button.scss b/src/components/Button/Button.scss
index 85572d5d93..2e43ad80c9 100644
--- a/src/components/Button/Button.scss
+++ b/src/components/Button/Button.scss
@@ -89,7 +89,7 @@ $block: '.#{variables.$ns}button';
--_--height: 20px;
--_--border-radius: var(--g-border-radius-xs);
--_--padding: 6px;
- --_--icon-size: 12px;
+ --_--icon-space: 12px;
--_--icon-offset: 4px;
}
@@ -97,7 +97,7 @@ $block: '.#{variables.$ns}button';
--_--height: 24px;
--_--border-radius: var(--g-border-radius-s);
--_--padding: 8px;
- --_--icon-size: 16px;
+ --_--icon-space: 16px;
--_--icon-offset: 4px;
}
@@ -105,7 +105,7 @@ $block: '.#{variables.$ns}button';
--_--height: 28px;
--_--border-radius: var(--g-border-radius-m);
--_--padding: 12px;
- --_--icon-size: 16px;
+ --_--icon-space: 16px;
--_--icon-offset: 8px;
}
@@ -113,7 +113,7 @@ $block: '.#{variables.$ns}button';
--_--height: 36px;
--_--border-radius: var(--g-border-radius-l);
--_--padding: 16px;
- --_--icon-size: 16px;
+ --_--icon-space: 16px;
--_--icon-offset: 8px;
}
@@ -121,7 +121,7 @@ $block: '.#{variables.$ns}button';
--_--height: 44px;
--_--border-radius: var(--g-border-radius-xl);
--_--padding: 24px;
- --_--icon-size: 20px;
+ --_--icon-space: 20px;
--_--icon-offset: 12px;
--_--font-size: var(--g-text-body-2-font-size);
}
@@ -269,10 +269,11 @@ $block: '.#{variables.$ns}button';
calc(
(
var(--g-button-height, var(--_--height)) - var(
- --g-button-icon-size,
- var(--_--icon-size)
+ --g-button-icon-space,
+ var(--_--icon-space)
)
- ) / 2 * -1
+ ) /
+ 2 * -1
);
width: var(--g-button-height, var(--_--height));
height: var(--g-button-height, var(--_--height));
diff --git a/src/components/Button/README.md b/src/components/Button/README.md
index 7b854c711a..d29b539469 100644
--- a/src/components/Button/README.md
+++ b/src/components/Button/README.md
@@ -495,5 +495,5 @@ LANDING_BLOCK-->
| `--g-button-padding` | Side paddings |
| `--g-button-border-radius` | Border radius |
| `--g-button-font-size` | Text font size |
-| `--g-button-icon-size` | Icon size |
+| `--g-button-icon-space` | Icon available space |
| `--g-button-icon-offset` | Icon offset |
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-ActionType-dark-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-ActionType-dark-webkit-linux.png
index f7d837b806..78e685634f 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-ActionType-dark-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-ActionType-dark-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-ActionType-light-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-ActionType-light-webkit-linux.png
index 6b8d7155e9..f6470850af 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-ActionType-light-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-ActionType-light-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Custom-dark-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Custom-dark-webkit-linux.png
index 5c70b65912..6f15536bdb 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Custom-dark-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Custom-dark-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Custom-light-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Custom-light-webkit-linux.png
index 865f36521a..f7c97d9a3b 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Custom-light-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Custom-light-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Default-dark-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Default-dark-webkit-linux.png
index 647fc5c936..1cecd702a5 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Default-dark-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Default-dark-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Default-light-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Default-light-webkit-linux.png
index 43aad18596..a092803f56 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Default-light-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Default-light-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-SelectionType-dark-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-SelectionType-dark-webkit-linux.png
index 0540b20c95..530824cf0b 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-SelectionType-dark-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-SelectionType-dark-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-SelectionType-light-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-SelectionType-light-webkit-linux.png
index 4fbf7d63ac..669bbadfa1 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-SelectionType-light-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-SelectionType-light-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Size-dark-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Size-dark-webkit-linux.png
index a3f46a04bd..1a54221ff7 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Size-dark-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Size-dark-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Size-light-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Size-light-webkit-linux.png
index 0a5e4b2fe4..230bce0794 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Size-light-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Size-light-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Theme-dark-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Theme-dark-webkit-linux.png
index 238c2bc1d4..45f1d87c03 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Theme-dark-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Theme-dark-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Theme-light-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Theme-light-webkit-linux.png
index a15b349cc5..bd57f434f6 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Theme-light-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-Theme-light-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-View-dark-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-View-dark-webkit-linux.png
index f8a05b3f9f..3a2577defc 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-View-dark-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-View-dark-webkit-linux.png differ
diff --git a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-View-light-webkit-linux.png b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-View-light-webkit-linux.png
index 29f624ebfe..2e80dcaa21 100644
Binary files a/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-View-light-webkit-linux.png and b/src/components/Card/__snapshots__/Card.visual.test.tsx-snapshots/Card-render-story-View-light-webkit-linux.png differ
diff --git a/src/components/Checkbox/Checkbox.scss b/src/components/Checkbox/Checkbox.scss
index 53162ad495..12bc194345 100644
--- a/src/components/Checkbox/Checkbox.scss
+++ b/src/components/Checkbox/Checkbox.scss
@@ -141,11 +141,8 @@ $block: '.#{variables.$ns}checkbox';
{$block}_checked,
{$block}_indeterminate {
- #{$block}__indicator {
- &::before {
- background-color: var(--g-color-base-brand);
- opacity: 0.5;
- }
+ #{$block}__icon {
+ color: var(--g-color-text-hint);
}
}
}
diff --git a/src/components/Checkbox/__snapshots__/Checkbox.visual.test.tsx-snapshots/Checkbox-smoke-dark-chromium-linux.png b/src/components/Checkbox/__snapshots__/Checkbox.visual.test.tsx-snapshots/Checkbox-smoke-dark-chromium-linux.png
index 0f5173b22a..e84e7ccb4b 100644
Binary files a/src/components/Checkbox/__snapshots__/Checkbox.visual.test.tsx-snapshots/Checkbox-smoke-dark-chromium-linux.png and b/src/components/Checkbox/__snapshots__/Checkbox.visual.test.tsx-snapshots/Checkbox-smoke-dark-chromium-linux.png differ
diff --git a/src/components/Checkbox/__snapshots__/Checkbox.visual.test.tsx-snapshots/Checkbox-smoke-light-chromium-linux.png b/src/components/Checkbox/__snapshots__/Checkbox.visual.test.tsx-snapshots/Checkbox-smoke-light-chromium-linux.png
index c1723672cb..e6af9c672a 100644
Binary files a/src/components/Checkbox/__snapshots__/Checkbox.visual.test.tsx-snapshots/Checkbox-smoke-light-chromium-linux.png and b/src/components/Checkbox/__snapshots__/Checkbox.visual.test.tsx-snapshots/Checkbox-smoke-light-chromium-linux.png differ
diff --git a/src/components/ClipboardButton/ClipboardButton.tsx b/src/components/ClipboardButton/ClipboardButton.tsx
index c30d42065e..92a0c346f3 100644
--- a/src/components/ClipboardButton/ClipboardButton.tsx
+++ b/src/components/ClipboardButton/ClipboardButton.tsx
@@ -102,7 +102,6 @@ export function ClipboardButton(props: ClipboardButtonProps) {
text,
timeout = DEFAULT_TIMEOUT,
onCopy,
- options,
hasTooltip = true,
onMouseEnter,
onFocus,
@@ -154,7 +153,7 @@ export function ClipboardButton(props: ClipboardButtonProps) {
);
return (
-
+
{(status) => (
`ClipboardButton` properties are inherited from `Button` [properties](../Button/README.md#properties) except `href`, `component`, `target`, `rel`, `loading`, `children`.
-| Name | Description | Type | Default |
-| :----------------- | :----------------------------------------------------------------------- | :-----------------------------------------------: | :---------: |
-| hasTooltip | Disable tooltip. Tooltip won't be shown | `boolean` | `true` |
-| onCopy | Callback after copy `(text: string, result: boolean) => void` | `Function` | |
-| options | Copy to clipboard options | [CopyToClipboardOptions](#copytoclipboardoptions) | |
-| text | Text to copy | `string` | |
-| timeout | Time before state bounces back to its normal after the button is clicked | `number` | `1000` |
-| tooltipInitialText | Text shown before copy | `string` | `"Copy"` |
-| tooltipSuccessText | Text shown after copy | `string` | `"Copied!"` |
+| Name | Description | Type | Default |
+| :----------------- | :----------------------------------------------------------------------- | :--------: | :---------: |
+| hasTooltip | Disable tooltip. Tooltip won't be shown | `boolean` | `true` |
+| onCopy | Callback after copy `(text: string, result: boolean) => void` | `Function` | |
+| text | Text to copy | `string` | |
+| timeout | Time before state bounces back to its normal after the button is clicked | `number` | `1000` |
+| tooltipInitialText | Text shown before copy | `string` | `"Copy"` |
+| tooltipSuccessText | Text shown after copy | `string` | `"Copied!"` |
### CopyToClipboardOptions
diff --git a/src/components/ClipboardButton/__stories__/ClipboardButton.stories.tsx b/src/components/ClipboardButton/__stories__/ClipboardButton.stories.tsx
index ad6d56996d..35304c8756 100644
--- a/src/components/ClipboardButton/__stories__/ClipboardButton.stories.tsx
+++ b/src/components/ClipboardButton/__stories__/ClipboardButton.stories.tsx
@@ -9,6 +9,9 @@ import {ClipboardButton} from '../ClipboardButton';
export default {
title: 'Components/Utils/ClipboardButton',
component: ClipboardButton,
+ args: {
+ text: 'Clipboard text from ``',
+ },
} as Meta;
type Story = StoryObj;
diff --git a/src/components/ControlLabel/ControlLabel.scss b/src/components/ControlLabel/ControlLabel.scss
index fc70210e75..5c580aee71 100644
--- a/src/components/ControlLabel/ControlLabel.scss
+++ b/src/components/ControlLabel/ControlLabel.scss
@@ -33,18 +33,11 @@ $block: '.#{variables.$ns}control-label';
&__text {
flex-grow: 1;
+ margin-inline-start: var(--g-spacing-2);
white-space: normal;
#{$block}_disabled & {
opacity: 0.6;
}
-
- #{$block}_size_m & {
- margin-inline-start: 5px;
- }
-
- #{$block}_size_l & {
- margin-inline-start: 7px;
- }
}
}
diff --git a/src/components/CopyToClipboard/CopyToClipboard.tsx b/src/components/CopyToClipboard/CopyToClipboard.tsx
index 6265056c99..9aa6bcda88 100644
--- a/src/components/CopyToClipboard/CopyToClipboard.tsx
+++ b/src/components/CopyToClipboard/CopyToClipboard.tsx
@@ -2,23 +2,27 @@
import React from 'react';
-import ReactCopyToClipboard from 'react-copy-to-clipboard';
+import {copyText} from '../../utils/copyText';
import type {CopyToClipboardProps, CopyToClipboardStatus} from './types';
const INITIAL_STATUS: CopyToClipboardStatus = 'pending';
export function CopyToClipboard(props: CopyToClipboardProps) {
- const {children, text, options, timeout, onCopy} = props;
+ const {children, text, timeout, onCopy} = props;
+ const textRef = React.useRef(text);
const [status, setStatus] = React.useState(INITIAL_STATUS);
const timerIdRef = React.useRef();
- const content = React.useMemo(() => children(status), [children, status]);
+ const content = React.useMemo>>(
+ () => children(status),
+ [children, status],
+ );
- const handleCopy = React.useCallback['onCopy']>(
- (copyText, result) => {
+ const handleCopy = React.useCallback(
+ (copyText: string, result: boolean) => {
setStatus(result ? 'success' : 'error');
window.clearTimeout(timerIdRef.current);
timerIdRef.current = window.setTimeout(() => setStatus(INITIAL_STATUS), timeout);
@@ -27,15 +31,37 @@ export function CopyToClipboard(props: CopyToClipboardProps) {
[onCopy, timeout],
);
+ const onClickWithCopy: React.MouseEventHandler = React.useCallback(
+ (event) => {
+ textRef.current = text;
+
+ function copy(result: boolean) {
+ if (text === textRef.current) {
+ handleCopy(text, result);
+
+ content.props?.onClick?.(event);
+ }
+ }
+
+ copyText(text).then(
+ () => {
+ copy(true);
+ },
+ () => {
+ copy(false);
+ },
+ );
+ },
+ [content.props, handleCopy, text],
+ );
+
React.useEffect(() => () => window.clearTimeout(timerIdRef.current), []);
if (!React.isValidElement(content)) {
throw new Error('Content must be a valid react element');
}
- return (
-
- {content}
-
- );
+ return React.cloneElement(content, {
+ onClick: onClickWithCopy,
+ });
}
diff --git a/src/components/CopyToClipboard/types.ts b/src/components/CopyToClipboard/types.ts
index b70a733b7f..51c0d835b3 100644
--- a/src/components/CopyToClipboard/types.ts
+++ b/src/components/CopyToClipboard/types.ts
@@ -1,7 +1,5 @@
import type React from 'react';
-import type ReactCopyToClipboard from 'react-copy-to-clipboard';
-
export type CopyToClipboardStatus = 'pending' | 'success' | 'error';
export type OnCopyHandler = (text: string, result: boolean) => void;
@@ -11,7 +9,7 @@ export type CopyToClipboardContent = (status: CopyToClipboardStatus) => React.Re
export interface CopyToClipboardProps {
text: string;
timeout?: number;
+ /** Child element should have `onClick` handler to work properly */
children: CopyToClipboardContent;
onCopy?: OnCopyHandler;
- options?: ReactCopyToClipboard.Options;
}
diff --git a/src/components/DropdownMenu/DropdownMenuPopup.tsx b/src/components/DropdownMenu/DropdownMenuPopup.tsx
index 6d356ce9dc..df1e3a639a 100644
--- a/src/components/DropdownMenu/DropdownMenuPopup.tsx
+++ b/src/components/DropdownMenu/DropdownMenuPopup.tsx
@@ -142,6 +142,7 @@ export const DropdownMenuPopup = ({
open={open}
anchorRef={anchorRef}
onClose={onClose}
+ placement="bottom-start"
{...popupProps}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
diff --git a/src/components/FilePreview/__stories__/FilePreview.stories.tsx b/src/components/FilePreview/__stories__/FilePreview.stories.tsx
index bd2caf7c19..aea550e359 100644
--- a/src/components/FilePreview/__stories__/FilePreview.stories.tsx
+++ b/src/components/FilePreview/__stories__/FilePreview.stories.tsx
@@ -102,6 +102,14 @@ const CollageTemplate: StoryFn = () => {
export const Collage = CollageTemplate.bind({});
+const noClickableTemplateActions = [
+ {
+ icon: ,
+ onClick: () => action('Are you sure you want to delete the file?'),
+ title: 'Close',
+ },
+];
+
const NoClickableTemplate: StoryFn> = (args) => {
return (
@@ -109,25 +117,13 @@ const NoClickableTemplate: StoryFn> = (args) =
,
- onClick: () => action('Are you sure you want to delete the file?'),
- title: 'Close',
- },
- ]}
+ actions={noClickableTemplateActions}
/>
action('onClick')}
- actions={[
- {
- icon: ,
- onClick: () => action('Are you sure you want to delete the file?'),
- title: 'Close',
- },
- ]}
+ actions={noClickableTemplateActions}
/>
);
@@ -135,6 +131,17 @@ const NoClickableTemplate: StoryFn> = (args) =
export const NoClickable = NoClickableTemplate.bind({});
+const withoutActionTooltipTemplateActions = [
+ {
+ icon: ,
+ onClick: () => action('onClose'),
+ title: 'Close',
+ tooltipExtraProps: {
+ disabled: true,
+ },
+ },
+];
+
const WithoutActionTooltipTemplate: StoryFn> = (args) => {
return (
@@ -142,16 +149,7 @@ const WithoutActionTooltipTemplate: StoryFn> =
{...args}
file={{name: 'Clicable without tooltip', type: 'text/docs'} as File}
onClick={() => action('onClick')}
- actions={[
- {
- icon: ,
- onClick: () => action('onClose'),
- title: 'Close',
- tooltipExtraProps: {
- disabled: true,
- },
- },
- ]}
+ actions={withoutActionTooltipTemplateActions}
/>
);
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Close-dark-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Close-dark-webkit-linux.png
index e57d07c66e..190b6876bd 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Close-dark-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Close-dark-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Close-light-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Close-light-webkit-linux.png
index b448abdf91..3d93786e87 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Close-light-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Close-light-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Copy-dark-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Copy-dark-webkit-linux.png
index 58e94245fb..6c7159ff4c 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Copy-dark-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Copy-dark-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Copy-light-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Copy-light-webkit-linux.png
index 3131443521..3f990823fb 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Copy-light-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Copy-light-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Default-dark-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Default-dark-webkit-linux.png
index 57b77c4b96..666414da4f 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Default-dark-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Default-dark-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Default-light-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Default-light-webkit-linux.png
index 43b3ce446f..4f26125fd4 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Default-light-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Default-light-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Icon-dark-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Icon-dark-webkit-linux.png
index ea7273b4ff..d7010d9fe7 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Icon-dark-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Icon-dark-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Icon-light-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Icon-light-webkit-linux.png
index 8548741bd5..c3607f0b22 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Icon-light-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Icon-light-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Interactive-dark-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Interactive-dark-webkit-linux.png
index c96d996526..04f40b9761 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Interactive-dark-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Interactive-dark-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Interactive-light-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Interactive-light-webkit-linux.png
index 765fcd0a95..de5d49115a 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Interactive-light-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Interactive-light-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-LinkWrapper-dark-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-LinkWrapper-dark-webkit-linux.png
index 57b77c4b96..666414da4f 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-LinkWrapper-dark-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-LinkWrapper-dark-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-LinkWrapper-light-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-LinkWrapper-light-webkit-linux.png
index 43b3ce446f..4f26125fd4 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-LinkWrapper-light-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-LinkWrapper-light-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Size-dark-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Size-dark-webkit-linux.png
index 86327fc52a..c807ee38c7 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Size-dark-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Size-dark-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Size-light-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Size-light-webkit-linux.png
index 929c8aa4b0..4dfa0359db 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Size-light-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Size-light-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Theme-dark-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Theme-dark-webkit-linux.png
index 1047d43b24..32146b7bca 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Theme-dark-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Theme-dark-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Theme-light-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Theme-light-webkit-linux.png
index 79337072b5..156640b7b1 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Theme-light-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Theme-light-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Value-dark-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Value-dark-webkit-linux.png
index 19cd9f7874..24c0d41842 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Value-dark-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Value-dark-webkit-linux.png differ
diff --git a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Value-light-webkit-linux.png b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Value-light-webkit-linux.png
index f8ea80e941..3e1f6e01d1 100644
Binary files a/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Value-light-webkit-linux.png and b/src/components/Label/__snapshots__/Label.visual.test.tsx-snapshots/Label-render-story-Value-light-webkit-linux.png differ
diff --git a/src/components/Link/Link.tsx b/src/components/Link/Link.tsx
index 3b693cae3c..3b92b32a92 100644
--- a/src/components/Link/Link.tsx
+++ b/src/components/Link/Link.tsx
@@ -2,7 +2,7 @@
import React from 'react';
-import type {DOMProps, QAProps} from '../types';
+import type {QAProps} from '../types';
import {block} from '../utils/cn';
import {eventBroker} from '../utils/event-broker';
@@ -10,19 +10,15 @@ import './Link.scss';
export type LinkView = 'normal' | 'primary' | 'secondary';
-export interface LinkProps extends DOMProps, QAProps {
+export interface LinkProps extends React.AnchorHTMLAttributes, QAProps {
view?: LinkView;
visitable?: boolean;
underline?: boolean;
- title?: string;
href: string;
- target?: string;
- rel?: string;
- id?: string;
children?: React.ReactNode;
- onClick?: React.MouseEventHandler;
- onFocus?: React.FocusEventHandler;
- onBlur?: React.FocusEventHandler;
+ /**
+ * @deprecated Use additional props at the root
+ */
extraProps?: React.AnchorHTMLAttributes;
}
@@ -31,48 +27,42 @@ const b = block('link');
export const Link = React.forwardRef(function Link(
{
view = 'normal',
- visitable,
- underline,
+ visitable = false,
+ underline = false,
href,
- target,
- rel,
- title,
children,
extraProps,
- onClick,
- onFocus,
- onBlur,
- id,
- style,
- className,
qa,
+ ...props
},
ref,
) {
- const handleClickCapture = React.useCallback((event: React.SyntheticEvent) => {
- eventBroker.publish({
- componentId: 'Link',
- eventId: 'click',
- domEvent: event,
- });
- }, []);
+ const handleClickCapture = React.useCallback(
+ (event: React.MouseEvent) => {
+ eventBroker.publish({
+ componentId: 'Link',
+ eventId: 'click',
+ domEvent: event,
+ });
- const commonProps = {
- title,
- onClick,
- onClickCapture: handleClickCapture,
- onFocus,
- onBlur,
- id,
- style,
- className: b({view, visitable, underline}, className),
- 'data-qa': qa,
- };
-
- const relProp = target === '_blank' && !rel ? 'noopener noreferrer' : rel;
+ if (props.onClickCapture) {
+ props.onClickCapture(event);
+ }
+ },
+ [props.onClickCapture],
+ );
return (
-
+
{children}
);
diff --git a/src/components/Link/README.md b/src/components/Link/README.md
index ea9f8017d2..b2cfaba4f5 100644
--- a/src/components/Link/README.md
+++ b/src/components/Link/README.md
@@ -167,21 +167,13 @@ LANDING_BLOCK-->
## Properties
-| Name | Description | Type | Default |
-| :--------- | :----------------------------------------- | :-------------------------------------------------------: | :--------: |
-| view | Link appearance | `"normal" \| "primary" \| "secondary"` | `"normal"` |
-| visitable | Display `:visitable` CSS state | `boolean \| undefined` |
-| href | HTML `href` attribute | `string` |
-| target | HTML `target` attribute | `string \| undefined` |
-| rel | HTML `rel` attribute | `string \| undefined` |
-| title | HTML `title` attribute | `string \| undefined` |
-| children | Link content | `React.ReactNode` |
-| extraProps | Any additional props | `Record \| undefined` |
-| onClick | `click` event handler | `React.MouseEventHandler \| undefined` |
-| onFocus | `focus` event handler | `React.FocusEventHandler \| undefined` |
-| onBlur | `blur` event handler | `React.FocusEventHandler \| undefined` |
-| id | HTML `id` attribute | `string \| undefined` |
-| style | HTML `style` attribute | `React.CSSProperties \| undefined` |
-| className | HTML `class` attribute | `string \| undefined` |
-| qa | HTML `data-qa` attribute, used for testing | `string \| undefined` |
-| ref | React ref to Link DOM node | `React.ForwardedRef \| undefined` |
+`Link` accepts any valid `a` element props in addition to these:
+
+| Name | Description | Type | Default |
+| :-------- | :----------------------------------------- | :----------------------------------: | :--------: |
+| children | `Link` content | `React.ReactNode` | |
+| href | HTML `href` attribute | `string` | |
+| qa | HTML `data-qa` attribute, used for testing | `string` | |
+| underline | Show underline underneath the `Link` | `boolean` | `false` |
+| view | `Link` appearance | `"normal"` `"primary"` `"secondary"` | `"normal"` |
+| visitable | Display `:visitable` CSS state | `boolean` | `false` |
diff --git a/src/components/PlaceholderContainer/PlaceholderContainer.scss b/src/components/PlaceholderContainer/PlaceholderContainer.scss
index 3e14317664..00eb26a1b9 100644
--- a/src/components/PlaceholderContainer/PlaceholderContainer.scss
+++ b/src/components/PlaceholderContainer/PlaceholderContainer.scss
@@ -1,5 +1,5 @@
-@import '../variables';
-@import '../../../styles/mixins';
+@use '../variables';
+@use '../../../styles/mixins';
$imageSmallSize: 100px;
$imageMediumSize: 150px;
@@ -21,7 +21,7 @@ $normalOffset: var(--g-spacing-5);
$mediumOffset: var(--g-spacing-7);
$bigOffset: var(--g-spacing-10);
-$block: '.#{$ns}placeholder-container';
+$block: '.#{variables.$ns}placeholder-container';
@mixin container-row-sizes($bodyWidth, $imageSize, $contentHeight, $contentOffset) {
#{$block}__body {
@@ -120,19 +120,19 @@ $block: '.#{$ns}placeholder-container';
&__title {
#{$block}_size_s & {
- @include text-subheader-1();
+ @include mixins.text-subheader-1();
}
#{$block}_size_m & {
- @include text-subheader-2();
+ @include mixins.text-subheader-2();
}
#{$block}_size_l & {
- @include text-subheader-3();
+ @include mixins.text-subheader-3();
}
#{$block}_size_promo & {
- @include text-header-1();
+ @include mixins.text-header-1();
}
}
diff --git a/src/components/PlaceholderContainer/__stories__/PlaceholderContainerShowcase.scss b/src/components/PlaceholderContainer/__stories__/PlaceholderContainerShowcase.scss
index 00eb2d1078..8951eec489 100644
--- a/src/components/PlaceholderContainer/__stories__/PlaceholderContainerShowcase.scss
+++ b/src/components/PlaceholderContainer/__stories__/PlaceholderContainerShowcase.scss
@@ -1,7 +1,7 @@
-@import '../../variables';
+@use '../../variables';
-$block: '.#{$ns}placeholder-container-showcase';
-$body: '.#{$ns}placeholder-container__body';
+$block: '.#{variables.$ns}placeholder-container-showcase';
+$body: '.#{variables.$ns}placeholder-container__body';
#{$block} {
&__custom-action {
diff --git a/src/components/Popover/Popover.tsx b/src/components/Popover/Popover.tsx
index d6d7087be9..d3d46950e8 100644
--- a/src/components/Popover/Popover.tsx
+++ b/src/components/Popover/Popover.tsx
@@ -56,6 +56,7 @@ export const Popover = React.forwardRef
@@ -185,7 +189,7 @@ export const Popover = React.forwardRef
);
- if (anchorRef) {
+ if (hasAnchor) {
return tooltip;
}
diff --git a/src/components/Popover/README.md b/src/components/Popover/README.md
index 774303d967..1e97b29373 100644
--- a/src/components/Popover/README.md
+++ b/src/components/Popover/README.md
@@ -231,45 +231,45 @@ const close = () => {
## Properties
-| Name | Description | Type | Default |
-| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------: | :-------------------: |
-| anchorRef | `Popper.js` anchor element. Can also be `popper.VirtualElement`. | [`PopupAnchorRef`](../Popup/README.md#anchor) | |
-| autoclosable | Whether the tooltip automatically closes when cursor moves outside it | `boolean` | `true` |
-| autoFocus | If true, focus will be transferred to the first element when the popover opens | `boolean` | |
-| behavior | Tooltip open/close behaviour when `openOnHover`. `"immediate"` - without any delay. `"delayed"` - with 300ms delay for opening and closing. `"delayedClosing"` - with 300ms delay only for closing. Won't be applied if `delayOpening` or `delayClosing` are passed. | `"immediate"` `"delayed"` `"delayedClosing"` | `"delayed"` |
-| children | Tooltip's trigger content over which the tooltip is shown. Can be function `(triggerProps: `[`TriggerProps`](#triggerprops))` => React.ReactNode` or `ReactNode` | `React.ReactNode` `Function` | |
-| className | css class for the control | `string` | |
-| content | Tooltip's content | `React.ReactNode` | |
-| contentClassName | css class for `content` | `string` | |
-| delayClosing | Custom delay for closing if autoclosable | `number` | |
-| delayOpening | Custom delay for opening if openOnHover | `number` | |
-| disabled | Disables open state changes | `boolean` | `false` |
-| disablePortal | Disable rendering of the popover in a portal | `boolean` | `false` |
-| focusTrap | Prevent focus from leaving the popover while open | `boolean` | |
-| forceLinksAppearance | Force styles for links | `boolean` | `false` |
-| hasArrow | Whether the tooltip has a tail | `boolean` | `true` |
-| hasClose | Whether the tooltip has a close button | `boolean` | `false` |
-| htmlContent | Tooltip's html content to be rendered via `dangerouslySetInnerHTML` | `string` | |
-| initialOpen | Whether the tooltip initially opened | `boolean` | `false` |
-| links | Links under the content | `[`[`LinkProps`](#linksprops)`]` | |
-| offset | Control's offset | `{top: number, left: number}` | |
-| onClick | Anchor click callback `(event: React.MouseEvent) => boolean \| Promise`. If the function returns `true', the tooltip will be open, otherwise it won't be opened. | `Function` | |
-| onCloseClick | Close button click handler `(event: React.MouseEvent) => void` | `Function` | |
-| onOpenChange | Open state change handler `(open: boolean) => void`. Might be useful for the delayed rendering of the tooltip's content. | `Function` | |
-| openOnHover | Whether the tooltip opens when hovered | `boolean` | `true` |
-| placement | `Popper.js` placement | [`PopupPlacement`](../Popup/README.md#placement) | `["right", "bottom"]` |
-| qa | HTML `data-qa` attribute, used in tests | `string` | |
-| restoreFocusRef | Focused element when the popover closes | `React.RefObject` | |
-| size | Tooltip's size | `"s"` `"l"` | `"s"` |
-| strategy | `Popper.js` positioning [strategy](https://popper.js.org/docs/v2/constructors/#strategy) | `"absolute"` `"fixed"` | `"absolute"` |
-| title | Tooltip's title | `string` | |
-| theme | Tooltip's theme | `"info"` `"special"` `"announcement"` | `"info"` |
-| tooltipActionButton | Action button properties. The button won't be rendered without it. | [`PopoverButtonProps`](#popoverbuttonprops) | |
-| tooltipCancelButton | Cancel button properties. The button won't be rendered without it. | [`PopoverButtonProps`](#popoverbuttonprops) | |
-| tooltipClassName | Tooltip's css class | `string` | |
-| tooltipContentClassName | Tooltip's content css class | `string` | |
-| tooltipOffset | Tooltip's offset relative to the control | `[number, number]` | |
-| tooltipId | The html id attribute of the popover | `string` | |
+| Name | Description | Type | Default |
+| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----------------------------------------------: | :-------------------: |
+| anchorElement | `Popup` anchor element. Can also be `VirtualElement`. | [`PopupAnchorElement`](../Popup/README.md#anchor) | |
+| autoclosable | Whether the tooltip automatically closes when cursor moves outside it | `boolean` | `true` |
+| autoFocus | If true, focus will be transferred to the first element when the popover opens | `boolean` | |
+| behavior | Tooltip open/close behaviour when `openOnHover`. `"immediate"` - without any delay. `"delayed"` - with 300ms delay for opening and closing. `"delayedClosing"` - with 300ms delay only for closing. Won't be applied if `delayOpening` or `delayClosing` are passed. | `"immediate"` `"delayed"` `"delayedClosing"` | `"delayed"` |
+| children | Tooltip's trigger content over which the tooltip is shown. Can be function `(triggerProps: `[`TriggerProps`](#triggerprops))` => React.ReactNode` or `ReactNode` | `React.ReactNode` `Function` | |
+| className | css class for the control | `string` | |
+| content | Tooltip's content | `React.ReactNode` | |
+| contentClassName | css class for `content` | `string` | |
+| delayClosing | Custom delay for closing if autoclosable | `number` | |
+| delayOpening | Custom delay for opening if openOnHover | `number` | |
+| disabled | Disables open state changes | `boolean` | `false` |
+| disablePortal | Disable rendering of the popover in a portal | `boolean` | `false` |
+| focusTrap | Prevent focus from leaving the popover while open | `boolean` | |
+| forceLinksAppearance | Force styles for links | `boolean` | `false` |
+| hasArrow | Whether the tooltip has a tail | `boolean` | `true` |
+| hasClose | Whether the tooltip has a close button | `boolean` | `false` |
+| htmlContent | Tooltip's html content to be rendered via `dangerouslySetInnerHTML` | `string` | |
+| initialOpen | Whether the tooltip initially opened | `boolean` | `false` |
+| links | Links under the content | `[`[`LinkProps`](#linksprops)`]` | |
+| offset | Control's offset | `{top: number, left: number}` | |
+| onClick | Anchor click callback `(event: React.MouseEvent) => boolean \| Promise`. If the function returns `true', the tooltip will be open, otherwise it won't be opened. | `Function` | |
+| onCloseClick | Close button click handler `(event: React.MouseEvent) => void` | `Function` | |
+| onOpenChange | Open state change handler `(open: boolean) => void`. Might be useful for the delayed rendering of the tooltip's content. | `Function` | |
+| openOnHover | Whether the tooltip opens when hovered | `boolean` | `true` |
+| placement | `Popup` placement | [`PopupPlacement`](../Popup/README.md#placement) | `["right", "bottom"]` |
+| qa | HTML `data-qa` attribute, used in tests | `string` | |
+| restoreFocusRef | Focused element when the popover closes | `React.RefObject` | |
+| size | Tooltip's size | `"s"` `"l"` | `"s"` |
+| strategy | `Floating UI` positioning [strategy](https://floating-ui.com/docs/computePosition#strategy) | `"absolute"` `"fixed"` | `"absolute"` |
+| title | Tooltip's title | `string` | |
+| theme | Tooltip's theme | `"info"` `"special"` `"announcement"` | `"info"` |
+| tooltipActionButton | Action button properties. The button won't be rendered without it. | [`PopoverButtonProps`](#popoverbuttonprops) | |
+| tooltipCancelButton | Cancel button properties. The button won't be rendered without it. | [`PopoverButtonProps`](#popoverbuttonprops) | |
+| tooltipClassName | Tooltip's css class | `string` | |
+| tooltipContentClassName | Tooltip's content css class | `string` | |
+| tooltipOffset | Tooltip's offset relative to the control | `[number, number]` | |
+| tooltipId | The html id attribute of the popover | `string` | |
### TriggerProps
diff --git a/src/components/Popover/__stories__/PopoverDemo.scss b/src/components/Popover/__stories__/PopoverDemo.scss
index e554f696bf..eaaec0c85b 100644
--- a/src/components/Popover/__stories__/PopoverDemo.scss
+++ b/src/components/Popover/__stories__/PopoverDemo.scss
@@ -1,6 +1,6 @@
-@import '../../variables';
+@use '../../variables';
-$block: '.#{$ns}popover-demo';
+$block: '.#{variables.$ns}popover-demo';
#{$block} {
display: flex;
diff --git a/src/components/Popover/index.ts b/src/components/Popover/index.ts
index 11e52e1806..18c9d69577 100644
--- a/src/components/Popover/index.ts
+++ b/src/components/Popover/index.ts
@@ -4,5 +4,6 @@ export type {
PopoverProps,
PopoverInstanceProps,
PopoverAnchorRef,
+ PopoverAnchorElement,
} from './types';
export {PopoverBehavior} from './config';
diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts
index 1331e8d7af..cc936a6b05 100644
--- a/src/components/Popover/types.ts
+++ b/src/components/Popover/types.ts
@@ -1,4 +1,4 @@
-import type {PopupAnchorRef, PopupProps} from '../Popup';
+import type {PopupAnchorElement, PopupAnchorRef, PopupOffset, PopupProps} from '../Popup';
import type {ButtonsProps} from './components/Buttons/Buttons';
import type {ContentProps} from './components/Content/Content';
@@ -41,7 +41,7 @@ export interface PopoverExternalProps {
*/
tooltipCancelButton?: ButtonsProps['tooltipCancelButton'];
/** Tooltip's offset relative to the control */
- tooltipOffset?: [number, number];
+ tooltipOffset?: PopupOffset;
/** Tooltip's css class */
tooltipClassName?: string;
/** Tooltip's content css class */
@@ -92,6 +92,7 @@ export type PopoverBehaviorProps = {
export type PopoverTheme = 'info' | 'special' | 'announcement';
export type PopoverAnchorRef = PopupAnchorRef;
+export type PopoverAnchorElement = PopupAnchorElement;
export type PopoverDefaultProps = {
/** Whether the tooltip initially opened */
@@ -121,7 +122,10 @@ export type PopoverDefaultProps = {
size: 's' | 'l';
};
-export type PopoverProps = Pick &
+export type PopoverProps = Pick<
+ PopupProps,
+ 'anchorElement' | 'anchorRef' | 'strategy' | 'placement' | 'middlewares'
+> &
PopoverExternalProps &
PopoverBehaviorProps &
Partial;
diff --git a/src/components/Popup/Popup.scss b/src/components/Popup/Popup.scss
index acd49b2140..a975e415b3 100644
--- a/src/components/Popup/Popup.scss
+++ b/src/components/Popup/Popup.scss
@@ -17,25 +17,32 @@ $transition-distance: 10px;
z-index: 1000;
visibility: hidden;
+ width: max-content;
+ position: absolute;
+ // stylelint-disable-next-line csstools/use-logical
+ top: 0;
+ // stylelint-disable-next-line csstools/use-logical
+ left: 0;
+
&_open,
&_exit_active {
visibility: visible;
}
&_exit_active {
- &[data-popper-placement*='bottom'] #{$block}__content {
+ &[data-floating-placement*='bottom'] #{$block}__content {
animation-name: #{variables.$ns}popup-bottom;
}
- &[data-popper-placement*='top'] #{$block}__content {
+ &[data-floating-placement*='top'] #{$block}__content {
animation-name: #{variables.$ns}popup-top;
}
- &[data-popper-placement*='left'] #{$block}__content {
+ &[data-floating-placement*='left'] #{$block}__content {
animation-name: #{variables.$ns}popup-left;
}
- &[data-popper-placement*='right'] #{$block}__content {
+ &[data-floating-placement*='right'] #{$block}__content {
animation-name: #{variables.$ns}popup-right;
}
}
@@ -43,29 +50,29 @@ $transition-distance: 10px;
// open state
&_enter_active,
&_appear_active {
- &[data-popper-placement*='bottom'] #{$block}__content {
+ &[data-floating-placement*='bottom'] #{$block}__content {
animation-name: #{variables.$ns}popup-bottom-open;
}
- &[data-popper-placement*='top'] #{$block}__content {
+ &[data-floating-placement*='top'] #{$block}__content {
animation-name: #{variables.$ns}popup-top-open;
}
- &[data-popper-placement*='left'] #{$block}__content {
+ &[data-floating-placement*='left'] #{$block}__content {
animation-name: #{variables.$ns}popup-left-open;
}
- &[data-popper-placement*='right'] #{$block}__content {
+ &[data-floating-placement*='right'] #{$block}__content {
animation-name: #{variables.$ns}popup-right-open;
}
}
// arrow
- &[data-popper-placement*='bottom'] #{$block}__arrow {
+ &[data-floating-placement*='bottom'] #{$block}__arrow {
inset-block-start: -$arrow-offset;
}
- &[data-popper-placement*='top'] #{$block}__arrow {
+ &[data-floating-placement*='top'] #{$block}__arrow {
inset-block-end: -$arrow-offset;
&-content {
@@ -73,7 +80,7 @@ $transition-distance: 10px;
}
}
- &[data-popper-placement*='left'] #{$block}__arrow {
+ &[data-floating-placement*='left'] #{$block}__arrow {
// stylelint-disable-next-line csstools/use-logical
right: -$arrow-offset;
@@ -82,7 +89,7 @@ $transition-distance: 10px;
}
}
- &[data-popper-placement*='right'] #{$block}__arrow {
+ &[data-floating-placement*='right'] #{$block}__arrow {
// stylelint-disable-next-line csstools/use-logical
left: -$arrow-offset;
@@ -116,6 +123,10 @@ $transition-distance: 10px;
}
}
+ &__arrow {
+ position: absolute;
+ }
+
&__arrow-content {
width: $arrow-size;
height: $arrow-size;
diff --git a/src/components/Popup/Popup.tsx b/src/components/Popup/Popup.tsx
index 15768bf02b..f26b850c31 100644
--- a/src/components/Popup/Popup.tsx
+++ b/src/components/Popup/Popup.tsx
@@ -2,11 +2,28 @@
import React from 'react';
+import {
+ arrow,
+ autoPlacement,
+ autoUpdate,
+ flip,
+ offset as floatingOffset,
+ limitShift,
+ shift,
+ useFloating,
+} from '@floating-ui/react';
+import type {
+ Alignment,
+ FloatingRootContext,
+ Middleware,
+ Placement,
+ ReferenceType,
+ Strategy,
+} from '@floating-ui/react';
import {CSSTransition} from 'react-transition-group';
import {useForkRef} from '../../hooks';
-import {usePopper, useRestoreFocus} from '../../hooks/private';
-import type {PopperAnchorRef, PopperPlacement, PopperProps} from '../../hooks/private';
+import {useRestoreFocus} from '../../hooks/private';
import {Portal} from '../Portal';
import type {DOMProps, QAProps} from '../types';
import {FocusTrap, useParentFocusTrap} from '../utils/FocusTrap';
@@ -16,13 +33,13 @@ import type {LayerExtendableProps} from '../utils/layer-manager/LayerManager';
import {getCSSTransitionClassNames} from '../utils/transition';
import {PopupArrow} from './PopupArrow';
+import {useAnchor} from './hooks';
+import type {PopupAnchorElement, PopupAnchorRef, PopupOffset, PopupPlacement} from './types';
+import {getOffsetValue, isAutoPlacement} from './utils';
import './Popup.scss';
-export type PopupPlacement = PopperPlacement;
-export type PopupAnchorRef = PopperAnchorRef;
-
-export interface PopupProps extends DOMProps, LayerExtendableProps, PopperProps, QAProps {
+export interface PopupProps extends DOMProps, LayerExtendableProps, QAProps {
children?: React.ReactNode;
/** Manages `Popup` visibility */
open?: boolean;
@@ -30,6 +47,24 @@ export interface PopupProps extends DOMProps, LayerExtendableProps, PopperProps,
keepMounted?: boolean;
/** Render an arrow pointing to the anchor */
hasArrow?: boolean;
+ /** Floating UI strategy */
+ strategy?: Strategy;
+ /** floating element placement */
+ placement?: PopupPlacement;
+ /** floating element offset relative to anchor */
+ offset?: PopupOffset;
+ /** floating element anchor */
+ anchorElement?: PopupAnchorElement | null;
+ /** floating element anchor ref object */
+ anchorRef?: PopupAnchorRef;
+ /** Floating UI middlewares. If set, they will completely overwrite the default middlewares. */
+ middlewares?: Middleware[];
+ /** Floating UI context to provide interactions */
+ floatingContext?: FloatingRootContext;
+ /** Additional floating element props to provide interactions */
+ floatingProps?: Record;
+ /** React ref floating element is attached to */
+ floatingRef?: React.Ref;
/** Do not use `LayerManager` on stacking popups */
disableLayer?: boolean;
/** @deprecated Add onClick handler to children */
@@ -77,21 +112,26 @@ export interface PopupProps extends DOMProps, LayerExtendableProps, PopperProps,
}
const b = block('popup');
-const ARROW_SIZE = 8;
+
export function Popup({
+ floatingRef,
keepMounted = false,
hasArrow = false,
- offset = [0, 4],
open,
- placement,
+ strategy,
+ placement = 'top',
+ offset = 4,
+ anchorElement,
anchorRef,
+ floatingContext,
+ floatingProps,
disableEscapeKeyDown,
disableOutsideClick,
disableLayer,
style,
className,
contentClassName,
- modifiers = [],
+ middlewares,
children,
onEscapeKeyDown,
onOutsideClick,
@@ -107,7 +147,6 @@ export function Popup({
onTransitionExited,
disablePortal,
container,
- strategy,
qa,
restoreFocus,
restoreFocusRef,
@@ -120,6 +159,39 @@ export function Popup({
'aria-modal': ariaModal = focusTrap,
}: PopupProps) {
const containerRef = React.useRef(null);
+ const [arrowElement, setArrowElement] = React.useState(null);
+
+ const anchor = useAnchor(anchorElement, anchorRef);
+ const offsetValue = getOffsetValue(offset, hasArrow);
+
+ let placementValue: Placement | undefined;
+ let preventOverflowMiddleware: Middleware;
+
+ if (Array.isArray(placement)) {
+ placementValue = placement[0];
+ preventOverflowMiddleware = flip({
+ altBoundary: disablePortal,
+ fallbackPlacements: placement.slice(1),
+ });
+ } else if (isAutoPlacement(placement)) {
+ let alignment: Alignment | undefined;
+ if (placement === 'auto-start') {
+ alignment = 'start';
+ } else if (placement === 'auto-end') {
+ alignment = 'end';
+ }
+
+ placementValue = undefined;
+ preventOverflowMiddleware = autoPlacement({
+ altBoundary: disablePortal,
+ alignment,
+ });
+ } else {
+ placementValue = placement;
+ preventOverflowMiddleware = flip({
+ altBoundary: disablePortal,
+ });
+ }
useLayer({
open,
@@ -128,27 +200,48 @@ export function Popup({
onEscapeKeyDown,
onOutsideClick,
onClose,
- contentRefs: [anchorRef, containerRef],
+ contentRefs: [anchor.ref, containerRef],
enabled: !disableLayer,
type: 'popup',
});
- const {attributes, styles, setPopperRef, setArrowRef} = usePopper({
- anchorRef,
- placement,
- // Take arrow size into offset account
- offset: hasArrow ? [offset[0], offset[1] + ARROW_SIZE] : offset,
+ const {
+ refs,
+ floatingStyles,
+ placement: actualPlacement,
+ middlewareData,
+ } = useFloating({
+ rootContext: floatingContext,
strategy,
- altBoundary: disablePortal,
- modifiers: [
- // Properly display arrow within rounded container
- {name: 'arrow', options: {enabled: hasArrow, padding: 4}},
- // Prevent border hiding
- {name: 'preventOverflow', options: {padding: 1, altBoundary: disablePortal}},
- ...modifiers,
+ placement: placementValue,
+ open,
+ whileElementsMounted: open ? autoUpdate : undefined,
+ elements: {
+ // @ts-expect-error: Type 'Element | VirtualElement | undefined' is not assignable to type 'Element | null | undefined'.
+ reference: anchor.element,
+ },
+ middleware: middlewares ?? [
+ floatingOffset(offsetValue),
+ preventOverflowMiddleware,
+ shift({limiter: limitShift(), altBoundary: disablePortal}),
+ arrow({element: arrowElement, padding: 4}),
],
});
- const handleRef = useForkRef(setPopperRef, containerRef, useParentFocusTrap());
+
+ const arrowStyles: React.CSSProperties = {};
+
+ if (hasArrow && middlewareData.arrow) {
+ const {x, y} = middlewareData.arrow;
+ arrowStyles.left = x;
+ arrowStyles.top = y;
+ }
+
+ const handleRef = useForkRef(
+ floatingRef,
+ refs.setFloating,
+ containerRef,
+ useParentFocusTrap(),
+ );
const containerProps = useRestoreFocus({
enabled: Boolean(restoreFocus && open),
@@ -185,8 +278,8 @@ export function Popup({
{/* FIXME The onClick event handler is deprecated and should be removed */}
@@ -210,11 +304,7 @@ export function Popup({
tabIndex={-1}
>
{hasArrow && (
-
+
)}
{children}
diff --git a/src/components/Popup/README.md b/src/components/Popup/README.md
index aa0208e512..ad1dedec88 100644
--- a/src/components/Popup/README.md
+++ b/src/components/Popup/README.md
@@ -8,13 +8,13 @@
import {Popup} from '@gravity-ui/uikit';
```
-`Popup` can be used to display floating content above the page. It is a wrapper around [Popper.js](https://popper.js.org)
+`Popup` can be used to display floating content above the page. It is a wrapper around [Floating UI](https://floating-ui.com)
with some defaults. To manage `Popup` visibility, use the `open` property.
The `Popup` child components are rendered inside the [`Portal`](../Portal) component. To disable this behavior, use the `disablePortal` property.
## Anchor
-Ref object of the DOM element is passed to the `anchorRef` property to create a `Popper.js` instance.
+To specify the anchor of a floating element, you can use either the `anchorElement` property.
## Properties
-| Name | Description | Type | Default |
-| :------------------- | :--------------------------------------------------------------------------------- | :--------------------------------------: | :------------------------------: |
-| altBoundary | `altBoundary` parameter for `Popper.js` `offset` modifier | `boolean` | `false` |
-| anchorRef | `Popper.js` anchor element. Can also be `popper.VirtualElement` | `PopupAnchorRef` | |
-| autoFocus | While open, the focus will be set to the first interactive element in the content | `boolean` | `false` |
-| children | Any React content | `React.ReactNode` | |
-| className | HTML `class` attribute for root node | `string` | |
-| container | DOM element children to be mounted to | `HTMLElement` | `document.body` |
-| contentClassName | HTML `class` attribute for content node | `string` | |
-| disableEscapeKeyDown | Do not trigger close on `Esc` | `boolean` | `false` |
-| disableLayer | Do not use `LayerManager` on stacking popups | `boolean` | `false` |
-| disableOutsideClick | Do not trigger close on outside clicks | `boolean` | `false` |
-| disablePortal | Do not use `Portal` for children | `boolean` | `false` |
-| focusTrap | Enable focus trapping behavior | `boolean` | `false` |
-| hasArrow | Render an arrow pointing to the anchor | `boolean` | `false` |
-| id | HTML `id` attribute | `string` | |
-| keepMounted | `Popup` will not be removed from the DOM upon hiding | `boolean` | `false` |
-| modifiers | `Popper.js` modifiers in addition to default: `arrow`, `offset`, `flip` | `Array` | `[0, 4]` |
-| offset | `Popper.js` offset | `[number, number]` | `[0, 4]` |
-| onBlur | `blur` event handler | `Function` | |
-| onClose | Handle `Popup` close event | `Function` | |
-| onEnterKeyDown | `Enter` press event handler | `Function` | |
-| onEscapeKeyDown | `Esc` press event handler | `Function` | |
-| onFocus | `focus` event handler | `Function` | |
-| onMouseEnter | `mouseenter` event handler | `Function` | |
-| onMouseLeave | `mouseleave` event handler | `Function` | |
-| onOutsideClick | Outside click event handler | `Function` | |
-| onTransitionEnter | On start open popup animation | `Function` | |
-| onTransitionEntered | On finish open popup animation | `Function` | |
-| onTransitionExit | On start close popup animation | `Function` | |
-| onTransitionExited | On finish close popup animation | `Function` | |
-| open | Manages `Popup` visibility | `boolean` | `false` |
-| placement | `Popper.js` placement | `PopupPlacement` `Array` | |
-| qa | Test attribute (`data-qa`) | `string` | |
-| restoreFocus | If true, the focus will return to the anchor element | `boolean` | `false` |
-| restoreFocusRef | Element the focus will be restored to | `React.RefObject` | |
-| aria-labelledby | `aria-labelledby` attribute, prefer this attribute if you have visible caption | `string` | |
-| aria-label | `aria-label` attribute, use this attribute only if you didn't have visible caption | `string` | |
-| aria-modal | The `aria-modal` attribute indicates whether an element is modal when displayed. | `Booleanish` | value of `focusTrap` |
-| role | The accessibility role for popup | `string` | `dialog` if `aria-modal` is true |
-| strategy | `Popper.js` positioning strategy | `popper.PositioningStrategy` | `[0, 4]` |
-| style | HTML `style` attribute for root node | `string` | |
+| Name | Description | Type | Default |
+| :------------------- | :----------------------------------------------------------------------------------------- | :-----------------------------------------------------------: | :------------------------------: |
+| anchorElement | Anchor element. Can also be `VirtualElement` | `PopupAnchorElement` | |
+| autoFocus | While open, the focus will be set to the first interactive element in the content | `boolean` | `false` |
+| children | Any React content | `React.ReactNode` | |
+| className | HTML `class` attribute for root node | `string` | |
+| container | DOM element children to be mounted to | `HTMLElement` | `document.body` |
+| contentClassName | HTML `class` attribute for content node | `string` | |
+| disableEscapeKeyDown | Do not trigger close on `Esc` | `boolean` | `false` |
+| disableLayer | Do not use `LayerManager` on stacking popups | `boolean` | `false` |
+| disableOutsideClick | Do not trigger close on outside clicks | `boolean` | `false` |
+| disablePortal | Do not use `Portal` for children | `boolean` | `false` |
+| focusTrap | Enable focus trapping behavior | `boolean` | `false` |
+| hasArrow | Render an arrow pointing to the anchor | `boolean` | `false` |
+| id | HTML `id` attribute | `string` | |
+| keepMounted | `Popup` will not be removed from the DOM upon hiding | `boolean` | `false` |
+| middlewares | `Floating UI` middlewares. If set, they will completely overwrite the default middlewares. | `Array` | |
+| offset | `Floating UI` offset value | `PopupOffset` | `4` |
+| floatingContext | `Floating UI` context to provide interactions | `FloatingRootContext` | |
+| floatingProps | Additional floating element props to provide interactions | `Record` | |
+| onBlur | `blur` event handler | `Function` | |
+| onClose | Handle `Popup` close event | `Function` | |
+| onEnterKeyDown | `Enter` press event handler | `Function` | |
+| onEscapeKeyDown | `Esc` press event handler | `Function` | |
+| onFocus | `focus` event handler | `Function` | |
+| onMouseEnter | `mouseenter` event handler | `Function` | |
+| onMouseLeave | `mouseleave` event handler | `Function` | |
+| onOutsideClick | Outside click event handler | `Function` | |
+| onTransitionEnter | On start open popup animation | `Function` | |
+| onTransitionEntered | On finish open popup animation | `Function` | |
+| onTransitionExit | On start close popup animation | `Function` | |
+| onTransitionExited | On finish close popup animation | `Function` | |
+| open | Manages `Popup` visibility | `boolean` | `false` |
+| placement | `Floating UI` placement | `Placement` `Array` `auto` `auto-start` `auto-end` | `top` |
+| qa | Test attribute (`data-qa`) | `string` | |
+| restoreFocus | If true, the focus will return to the anchor element | `boolean` | `false` |
+| restoreFocusRef | Element the focus will be restored to | `React.RefObject` | |
+| aria-labelledby | `aria-labelledby` attribute, prefer this attribute if you have visible caption | `string` | |
+| aria-label | `aria-label` attribute, use this attribute only if you didn't have visible caption | `string` | |
+| aria-modal | The `aria-modal` attribute indicates whether an element is modal when displayed. | `Booleanish` | value of `focusTrap` |
+| role | The accessibility role for popup | `string` | `dialog` if `aria-modal` is true |
+| strategy | `Floating UI` positioning strategy | `absolute` `fixed` | `absolute` |
+| style | HTML `style` attribute for root node | `string` | |
## CSS API
diff --git a/src/components/Popup/__stories__/Popup.stories.tsx b/src/components/Popup/__stories__/Popup.stories.tsx
index 2824695128..1237f47313 100644
--- a/src/components/Popup/__stories__/Popup.stories.tsx
+++ b/src/components/Popup/__stories__/Popup.stories.tsx
@@ -6,7 +6,7 @@ import {useVirtualElementRef} from '../../../hooks';
import {Button} from '../../Button';
import {Text} from '../../Text';
import {Popup} from '../Popup';
-import type {PopupPlacement} from '../Popup';
+import type {PopupPlacement} from '../types';
const meta: Meta = {
title: 'Components/Overlays/Popup',
@@ -24,7 +24,12 @@ export const Default: Story = {
return (
- setOpen(false)}>
+ setOpen(false)}
+ >
Popup content
{
+ anchorElementRef.current = anchorElement ?? null;
+ }, [anchorElement]);
+
+ if (anchorElement !== undefined) {
+ return {element: anchorElement, ref: anchorElementRef};
+ } else if (anchorRef) {
+ return {element: anchorRef.current, ref: anchorRef};
+ }
+
+ return {element: undefined, ref: undefined};
+}
diff --git a/src/components/Popup/index.ts b/src/components/Popup/index.ts
index 95a491cb9d..d3e33e4b65 100644
--- a/src/components/Popup/index.ts
+++ b/src/components/Popup/index.ts
@@ -1 +1,2 @@
export * from './Popup';
+export * from './types';
diff --git a/src/components/Popup/types.ts b/src/components/Popup/types.ts
new file mode 100644
index 0000000000..0e5c3337a4
--- /dev/null
+++ b/src/components/Popup/types.ts
@@ -0,0 +1,16 @@
+import type {OffsetOptions, Placement, VirtualElement} from '@floating-ui/react';
+
+import type {AUTO_PLACEMENTS} from './constants';
+
+export type AutoPlacement = (typeof AUTO_PLACEMENTS)[number];
+
+export type PopupPlacement = AutoPlacement | Placement | Placement[];
+
+export type PopupAnchorElement = Element | VirtualElement;
+
+export type PopupAnchorRef = React.RefObject;
+
+type RemoveFunction = T extends Function ? never : T;
+
+// floating-ui not exports `OffsetValue` type, so use this workarround
+export type PopupOffset = RemoveFunction;
diff --git a/src/components/Popup/utils.ts b/src/components/Popup/utils.ts
new file mode 100644
index 0000000000..02e4d5ed9b
--- /dev/null
+++ b/src/components/Popup/utils.ts
@@ -0,0 +1,19 @@
+import {ARROW_SIZE, AUTO_PLACEMENTS} from './constants';
+import type {AutoPlacement, PopupOffset} from './types';
+
+export function getOffsetValue(offset: PopupOffset, hasArrow: boolean | undefined) {
+ let offsetValue = offset;
+ if (hasArrow) {
+ if (typeof offsetValue === 'number') {
+ offsetValue += ARROW_SIZE;
+ } else {
+ offsetValue = {...offsetValue, mainAxis: (offsetValue.mainAxis ?? 0) + ARROW_SIZE};
+ }
+ }
+
+ return offsetValue;
+}
+
+export function isAutoPlacement(placement: string): placement is AutoPlacement {
+ return AUTO_PLACEMENTS.includes(placement as AutoPlacement);
+}
diff --git a/src/components/Radio/Radio.scss b/src/components/Radio/Radio.scss
index cee5bf799d..4c34cd5de7 100644
--- a/src/components/Radio/Radio.scss
+++ b/src/components/Radio/Radio.scss
@@ -126,11 +126,8 @@ $discMarginLSize: 6px;
}
{$block}_checked {
- #{$block}__indicator {
- &::before {
- background-color: var(--g-color-base-brand);
- opacity: 0.5;
- }
+ #{$block}__disc::before {
+ background-color: var(--g-color-text-hint);
}
}
}
diff --git a/src/components/RadioButton/README.md b/src/components/RadioButton/README.md
deleted file mode 100644
index 547a8a61e0..0000000000
--- a/src/components/RadioButton/README.md
+++ /dev/null
@@ -1,279 +0,0 @@
-
-
-# RadioButton
-
-
-
-```tsx
-import {RadioButton} from '@gravity-ui/uikit';
-```
-
-The `RadioButton` component is used to create a group of radio buttons where users can select a single option from multiple choices.
-
-### Disabled state
-
-
-
-
-
-```tsx
-const options: RadioButtonOption[] = [
- {value: 'Value 1', content: 'Value 1'},
- {value: 'Value 2', content: 'Value 2'},
- {value: 'Value 3', content: 'Value 3'},
-];
-;
-```
-
-
-
-### Size
-
-To control the size of the `RadioButton`, use the `size` property. The default size is `m`.
-
-
-
-
-
-```tsx
- const options: RadioButtonOption[] = [
- {value: 'Value 1', content: 's'},
- {value: 'Value 2', content: 'm'},
- {value: 'Value 3', content: 'l'},
- {value: 'Value 4', content: 'xl'},
- ];
-
-
-
-
-```
-
-
-
-### Width
-
-To control the width of the `RadioButton`, use the `width` property.
-
-
-
-
-
-```tsx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-
-
-### Properties
-
-| Name | Description | Type | Default |
-| :----------- | :--------------------------------------------------------------------------------------------------- | :-----------------------: | :-----: |
-| children | The content of the radio button. | `ReactNode` | |
-| disabled | Toggles the `disabled` state of the radio button. | `boolean` | `false` |
-| options | Options for radio button. | `RadioButtonOption[]` | |
-| defaultValue | Sets the initial value state when the component is mounted. | `string` | |
-| onUpdate | Fires when the user changes the radio button state. Provides the new value as a callback's argument. | `(value: string) => void` | |
-| onChange | Fires when the user changes the radio button state. Provides change event as a callback's argument. | `Function` | |
-| onFocus | Event handler for when the radio input element receives focus. | `Function` | |
-| onBlur | Event handler for when the radio input element loses focus. | `Function` | |
-| width | Sets the width of the radio button. | `auto - max` | |
-| size | Sets the size of the radio button. | `s` `m` `l` `xl` | `m` |
-| name | HTML `name` attribute for the input element. | `string` | |
-| qa | HTML `data-qa` attribute, used in tests. | `string` | |
-| style | HTML `style` attribute | `React.CSSProperties` | |
-| className | HTML `class` attribute | `string` | |
-
-## RadioButton.Option
-
-The `RadioButton` component also exports a nested `Option` component. You can use it to create radio button options within the `RadioButton`.
-
-
-
-
-
-```tsx
-const options: RadioButtonOption[] = [
- {value: 'Value 1', content: 'Value 1'},
- {value: 'Value 2', content: 'Value 2'},
- {value: 'Value 3', content: 'Value 3'},
-];
-
-
-
-
-;
-```
-
-
-
-### Properties
-
-| Name | Description | Type | Default |
-| :------- | :-------------------------------------------------- | :---------: | :-----: |
-| children | The content of the radio (usually a label). | `ReactNode` | |
-| content | The content of the radio (alternative to children). | `ReactNode` | |
-| disabled | Toggles the `disabled` state of the radio. | `boolean` | `false` |
-| value | Control value | `string` | |
diff --git a/src/components/RadioButton/RadioButton.tsx b/src/components/RadioButton/RadioButton.tsx
deleted file mode 100644
index c236c8b5d9..0000000000
--- a/src/components/RadioButton/RadioButton.tsx
+++ /dev/null
@@ -1,120 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import {useRadioGroup} from '../../hooks/private';
-import type {ControlGroupOption, ControlGroupProps, DOMProps, QAProps} from '../types';
-import {block} from '../utils/cn';
-
-import {RadioButtonOption as Option} from './RadioButtonOption';
-
-import './RadioButton.scss';
-
-const b = block('radio-button');
-
-export type RadioButtonOption = ControlGroupOption;
-export type RadioButtonSize = 's' | 'm' | 'l' | 'xl';
-export type RadioButtonWidth = 'auto' | 'max';
-
-export interface RadioButtonProps
- extends ControlGroupProps,
- DOMProps,
- QAProps {
- size?: RadioButtonSize;
- width?: RadioButtonWidth;
- children?:
- | React.ReactElement>
- | React.ReactElement>[];
-}
-
-type RadioButtonComponentType = ((
- props: RadioButtonProps & {ref?: React.ForwardedRef},
-) => React.JSX.Element) & {
- Option: typeof Option;
-};
-
-export const RadioButton = React.forwardRef(function RadioButton(
- props: RadioButtonProps,
- ref: React.ForwardedRef,
-) {
- const {size = 'm', width, style, className, qa, children} = props;
- let options = props.options;
-
- if (!options) {
- options = (
- React.Children.toArray(children) as React.ReactElement>[]
- ).map(({props}) => ({
- value: props.value,
- content: props.content || props.children,
- disabled: props.disabled,
- title: props.title,
- }));
- }
-
- const plateRef = React.useRef(null);
- const optionRef = React.useRef();
-
- const handleCheckedOptionMount: React.Ref = React.useCallback(
- (checkedOptionNode: HTMLLabelElement | null) => {
- if (!checkedOptionNode) {
- return;
- }
-
- const plateNode = plateRef.current;
-
- if (!plateNode) {
- return;
- }
-
- const uncheckedOptionNode = optionRef.current;
-
- if (uncheckedOptionNode && uncheckedOptionNode !== checkedOptionNode) {
- const setPlateStyle = (node: HTMLElement) => {
- plateNode.style.left = `${node.offsetLeft}px`;
- plateNode.style.width = `${node.offsetWidth}px`;
- };
-
- setPlateStyle(uncheckedOptionNode);
-
- plateNode.hidden = false;
-
- setPlateStyle(checkedOptionNode);
- }
-
- optionRef.current = checkedOptionNode;
- },
- [],
- );
-
- const handlePlateTransitionEnd: React.TransitionEventHandler = (event) => {
- event.currentTarget.hidden = true;
- };
-
- const {containerProps, optionsProps} = useRadioGroup({...props, options});
-
- return (
-