diff --git a/CHANGELOG.md b/CHANGELOG.md
index 225fb9de03..1b411f9a05 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,28 @@
# Changelog
+## [6.21.0](https://github.com/gravity-ui/uikit/compare/v6.20.1...v6.21.0) (2024-07-16)
+
+
+### Features
+
+* **PinInput:** form support ([#1686](https://github.com/gravity-ui/uikit/issues/1686)) ([b82262e](https://github.com/gravity-ui/uikit/commit/b82262e6ac3ac656f0d87a6275a081f9990aeb6a))
+* **Select:** new label and value resize behaviour ([#1694](https://github.com/gravity-ui/uikit/issues/1694)) ([891fa88](https://github.com/gravity-ui/uikit/commit/891fa886ce5b2d9c8753abbfe49f833ff35619a6))
+* **TreeList:** add ListTreeItemType interface export and id argument to renderItem prop ([#1707](https://github.com/gravity-ui/uikit/issues/1707)) ([de544b8](https://github.com/gravity-ui/uikit/commit/de544b871f722fe63f677e17f4272767bebf973e))
+* **TreeSelect:** add placeholder prop ([#1705](https://github.com/gravity-ui/uikit/issues/1705)) ([88696a3](https://github.com/gravity-ui/uikit/commit/88696a3f529c44dc9bd17024c926a77fea67acaa))
+* **useControlledState:** support update callback with additional params ([#1688](https://github.com/gravity-ui/uikit/issues/1688)) ([8bff882](https://github.com/gravity-ui/uikit/commit/8bff8821b4e8bb20e1bedb01c07a3ba8f22dfe16))
+* **useResizeObserver:** support box option ([#1687](https://github.com/gravity-ui/uikit/issues/1687)) ([a178dff](https://github.com/gravity-ui/uikit/commit/a178dffefb2d1cfa481417a2dea6297034ae22a0))
+
+
+### Bug Fixes
+
+* **Avatar:** update text font weight ([#1684](https://github.com/gravity-ui/uikit/issues/1684)) ([0ae513a](https://github.com/gravity-ui/uikit/commit/0ae513a2e2a595f2cc7f5d0b2fe532a6f7f46b03))
+* **ListItemView:** div -> li default list item html tag ([#1698](https://github.com/gravity-ui/uikit/issues/1698)) ([07a16c9](https://github.com/gravity-ui/uikit/commit/07a16c959198bedfa45dbb14b5ad804bd11a6d82))
+* **Sheet:** fix incorrect content height calculation ([#1700](https://github.com/gravity-ui/uikit/issues/1700)) ([7e4dd23](https://github.com/gravity-ui/uikit/commit/7e4dd2374cb83f72168e0b2fc416fa76dd6fbe6e))
+* **TextArea:** fix content width & height styles ([#1690](https://github.com/gravity-ui/uikit/issues/1690)) ([94979cf](https://github.com/gravity-ui/uikit/commit/94979cf8c43194dd347481929dc1e217ac2bd84b))
+* **TreeSelect:** add disabled prop ([#1697](https://github.com/gravity-ui/uikit/issues/1697)) ([f9650da](https://github.com/gravity-ui/uikit/commit/f9650dab0b999e5efa03e2e8f513e62074083f67))
+* **TreeSelect:** fix page gap on component focus in some cases ([#1708](https://github.com/gravity-ui/uikit/issues/1708)) ([cd4eb93](https://github.com/gravity-ui/uikit/commit/cd4eb93375ad7a6cfc6e4c87a92e3a20679b3047))
+* **useList:** fix disabled elements activate logic ([#1706](https://github.com/gravity-ui/uikit/issues/1706)) ([f12d49f](https://github.com/gravity-ui/uikit/commit/f12d49f125c189ff6ceaba86b5000920a811586d))
+
## [6.20.1](https://github.com/gravity-ui/uikit/compare/v6.20.0...v6.20.1) (2024-07-01)
diff --git a/CODEOWNERS b/CODEOWNERS
index 3a004158c2..fa0631e2e0 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -3,6 +3,7 @@
/src/components/Alert @IsaevAlexandr
/src/components/ArrowToggle @Marginy605
/src/components/Avatar @DakEnviy
+/src/components/AvatarStack @ogonkov
#/src/components/Breadcrumbs
/src/components/Button @amje
/src/components/Card @Lunory
diff --git a/package-lock.json b/package-lock.json
index b31f868100..a28de9d6a1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@gravity-ui/uikit",
- "version": "6.20.1",
+ "version": "6.21.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@gravity-ui/uikit",
- "version": "6.20.1",
+ "version": "6.21.0",
"license": "MIT",
"dependencies": {
"@bem-react/classname": "^1.6.0",
diff --git a/package.json b/package.json
index 90859c437f..096cfcc0a7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@gravity-ui/uikit",
- "version": "6.20.1",
+ "version": "6.21.0",
"description": "Gravity UI base styling and components",
"keywords": [
"component",
@@ -108,7 +108,7 @@
"lint": "run-p lint:*",
"typecheck": "tsc --noEmit",
"prepublishOnly": "npm run build && npm pkg delete engines",
- "playwright:install": "playwright install --with-deps",
+ "playwright:install": "playwright install chromium webkit --with-deps",
"playwright": "playwright test --config=playwright/playwright.config.ts",
"playwright:update": "npm run playwright -- -u",
"playwright:docker": "./scripts/playwright-docker.sh 'npm run playwright'",
diff --git a/src/components/Avatar/Avatar.scss b/src/components/Avatar/Avatar.scss
index c7081cf759..cf51bd03e3 100644
--- a/src/components/Avatar/Avatar.scss
+++ b/src/components/Avatar/Avatar.scss
@@ -10,6 +10,7 @@ $block: '.#{variables.$ns}avatar';
--_--color: var(--g-color-text-misc);
--_--font-size: var(--g-text-body-1-font-size);
--_--line-height: var(--g-text-body-1-line-height);
+ --_--font-weight: var(--g-text-body-font-weight);
overflow: hidden;
display: inline-flex;
@@ -39,7 +40,7 @@ $block: '.#{variables.$ns}avatar';
color: var(--g-avatar-color, var(--_--color));
font-size: var(--g-avatar-font-size, var(--_--font-size));
line-height: var(--g-avatar-line-height, var(--_--line-height));
- font-weight: 500;
+ font-weight: var(--_--font-weight);
}
&_with-border,
@@ -75,17 +76,20 @@ $block: '.#{variables.$ns}avatar';
&_s {
--_--font-size: var(--g-text-caption-1-font-size);
--_--line-height: var(--g-text-caption-1-line-height);
+ --_--font-weight: var(--g-text-caption-font-weight);
}
&_m,
&_l {
- --_--font-size: var(--g-text-body-1-font-size);
- --_--line-height: var(--g-text-body-1-line-height);
+ --_--font-size: var(--g-text-subheader-1-font-size);
+ --_--line-height: var(--g-text-subheader-1-line-height);
+ --_--font-weight: var(--g-text-subheader-font-weight);
}
&_xl {
- --_--font-size: var(--g-text-body-2-font-size);
- --_--line-height: var(--g-text-body-2-line-height);
+ --_--font-size: var(--g-text-subheader-2-font-size);
+ --_--line-height: var(--g-text-subheader-2-line-height);
+ --_--font-weight: var(--g-text-subheader-font-weight);
}
}
diff --git a/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Showcase-1-chromium-linux.png b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Showcase-1-chromium-linux.png
index eef174dd24..b4a9685df5 100644
Binary files a/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Showcase-1-chromium-linux.png and b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-Showcase-1-chromium-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 969abb6b18..3aad9739f9 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-TextInitials-1-chromium-linux.png b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-TextInitials-1-chromium-linux.png
index 85aaad554b..e8015e0799 100644
Binary files a/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-TextInitials-1-chromium-linux.png and b/src/components/Avatar/__snapshots__/Avatar.visual.test.tsx-snapshots/Avatar-render-story-TextInitials-1-chromium-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 00e4d243d7..c36ea7324d 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/AvatarStack.scss b/src/components/AvatarStack/AvatarStack.scss
new file mode 100644
index 0000000000..b0663c6a2e
--- /dev/null
+++ b/src/components/AvatarStack/AvatarStack.scss
@@ -0,0 +1,61 @@
+@use '../../../styles/mixins';
+@use '../Avatar/variables' as avatar-variables;
+@use '../variables';
+
+$block: '.#{variables.$ns}avatar-stack';
+
+#{$block} {
+ --_--more-button-size: #{avatar-variables.$default-size};
+ --_--more-button-border-width: 1px;
+
+ display: inline-flex;
+ justify-content: flex-end;
+ flex-direction: row-reverse;
+
+ margin: 0;
+ padding: 0;
+
+ &_overlap-size_s {
+ --_--overlap: var(--g-spacing-1);
+ }
+
+ &_overlap-size_m {
+ --_--overlap: var(--g-spacing-2);
+ }
+
+ &_overlap-size_l {
+ --_--overlap: var(--g-spacing-3);
+ }
+
+ &__item {
+ display: flex;
+ z-index: 0;
+ border-radius: 100%;
+
+ &:not(:first-child) {
+ margin-inline-end: calc(-1 * var(--_--overlap));
+ }
+ }
+
+ &__more-button {
+ @include mixins.button-reset;
+
+ border-radius: 100%;
+
+ width: var(--_--more-button-size);
+ height: var(--_--more-button-size);
+
+ &:focus-visible {
+ outline: var(--g-color-line-focus) solid 2px;
+ outline-offset: 0;
+ }
+
+ &_size {
+ @each $size-name, $size-value in avatar-variables.$sizes {
+ &_#{$size-name} {
+ --_--more-button-size: #{$size-value};
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/AvatarStack/AvatarStack.tsx b/src/components/AvatarStack/AvatarStack.tsx
new file mode 100644
index 0000000000..3e03fb63c5
--- /dev/null
+++ b/src/components/AvatarStack/AvatarStack.tsx
@@ -0,0 +1,69 @@
+import React from 'react';
+
+import {Avatar} from '../Avatar';
+import {block} from '../utils/cn';
+
+import {AvatarStackItem} from './AvatarStackItem';
+import {AvatarStackMoreButton} from './AvatarStackMoreButton';
+import i18n from './i18n';
+import type {AvatarStackProps} from './types';
+
+import './AvatarStack.scss';
+
+const b = block('avatar-stack');
+
+const AvatarStackComponent = ({
+ max = 3,
+ overlapSize = 's',
+ size,
+ children,
+ className,
+ renderMore,
+}: AvatarStackProps) => {
+ const visibleItems: React.ReactElement[] = [];
+ let moreItems = 0;
+
+ React.Children.forEach(children, (child) => {
+ if (!React.isValidElement(child)) {
+ return;
+ }
+
+ const item =