From 572afdf9d8d8369c16be315bf1e3a11586756964 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 20 Apr 2023 14:34:07 +0200 Subject: [PATCH 01/13] chore(UserAvatar): deprecate `onClick` (#642) --- src/components/UserAvatar/UserAvatar.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/UserAvatar/UserAvatar.tsx b/src/components/UserAvatar/UserAvatar.tsx index 3b101e53b2..28da8c28ff 100644 --- a/src/components/UserAvatar/UserAvatar.tsx +++ b/src/components/UserAvatar/UserAvatar.tsx @@ -9,6 +9,7 @@ export interface UserAvatarProps { size?: UserAvatarSize; title?: string; className?: string; + /** @deprecated Use appropriate component, like ` + ); +}; diff --git a/src/components/TextInput/TextInput.scss b/src/components/TextInput/TextInput.scss index 39fe4885ef..f31d23dc5d 100644 --- a/src/components/TextInput/TextInput.scss +++ b/src/components/TextInput/TextInput.scss @@ -1,24 +1,30 @@ @use '../variables'; @use '../../../styles/mixins'; +$sHeight: 24px; +$mHeight: 28px; +$lHeight: 36px; +$xlHeight: 44px; +$borderWidth: 1px; + @mixin block_style($size: s, $type: control) { @if $size == 's' { - height: 24px; + height: #{$sHeight - $borderWidth * 2}; padding: 4px 8px; @include mixins.text-body-short; } @if $size == 'm' { - height: 28px; + height: #{$mHeight - $borderWidth * 2}; padding: 6px 8px; @include mixins.text-body-short; } @if $size == 'l' { - height: 36px; + height: #{$lHeight - $borderWidth * 2}; padding: 10px 12px; @include mixins.text-body-short; } @if $size == 'xl' { - height: 44px; + height: #{$xlHeight - $borderWidth * 2}; padding: 12px; @include mixins.text-body-2; } @@ -32,14 +38,20 @@ $block: '.#{variables.$ns}text-input'; #{$block} { - box-sizing: border-box; display: inline-block; width: 100%; position: relative; + &__content { + box-sizing: border-box; + display: flex; + width: 100%; + } + &__control { box-sizing: border-box; display: inline-block; + flex-grow: 1; vertical-align: top; position: relative; margin: 0; @@ -49,6 +61,7 @@ $block: '.#{variables.$ns}text-input'; font-family: var(--yc-text-body-font-family); color: var(--yc-color-text-primary); background-color: transparent; + border: none; &::placeholder { color: var(--yc-color-text-hint); @@ -91,22 +104,27 @@ $block: '.#{variables.$ns}text-input'; margin-top: 2px; } - /* increase css specificity to rewrite Button styles */ - &__clear[class] { - --yc-button-background-color: transparent; - --yc-button-background-color-hover: transparent; + &__clear { + /* increase css specificity to rewrite Button styles */ + &[class] { + --yc-button-background-color: transparent; + --yc-button-background-color-hover: transparent; - position: absolute; - top: 0; - right: 0; - color: var(--yc-color-text-hint); + color: var(--yc-color-text-hint); + + &:hover { + color: var(--yc-color-text-primary); + } + } - &:hover { - color: var(--yc-color-text-primary); + &_textarea { + position: absolute; + top: 0; + right: 0; } - &:not(#{$block}__clear_visible) { - display: none; + &:not(#{&}_textarea) { + margin: -1px; } } @@ -120,10 +138,8 @@ $block: '.#{variables.$ns}text-input'; @include block_style(s, label); } - &#{$block}_has-clear { - #{$block}__control { - padding-right: 26px; - } + #{$block}__additional-content { + height: #{$sHeight}; } --yc-text-input-border-radius: var(--yc-border-radius-s); @@ -138,10 +154,8 @@ $block: '.#{variables.$ns}text-input'; @include block_style(m, label); } - &#{$block}_has-clear { - #{$block}__control { - padding-right: 26px; - } + #{$block}__additional-content { + height: #{$mHeight}; } --yc-text-input-border-radius: var(--yc-border-radius-m); @@ -156,10 +170,8 @@ $block: '.#{variables.$ns}text-input'; @include block_style(l, label); } - &#{$block}_has-clear { - #{$block}__control { - padding-right: 36px; - } + #{$block}__additional-content { + height: #{$lHeight}; } --yc-text-input-border-radius: var(--yc-border-radius-l); @@ -174,10 +186,8 @@ $block: '.#{variables.$ns}text-input'; @include block_style(xl, label); } - &#{$block}_has-clear { - #{$block}__control { - padding-right: 36px; - } + #{$block}__additional-content { + height: #{$xlHeight}; } --yc-text-input-border-radius: var(--yc-border-radius-xl); @@ -186,26 +196,28 @@ $block: '.#{variables.$ns}text-input'; &_view { &_normal { - #{$block}__control { + #{$block}__content { border: 1px solid var(--yc-color-line-generic); &:hover { - border: 1px solid var(--yc-color-line-generic-hover); + border-color: var(--yc-color-line-generic-hover); } - &:focus { - border: 1px solid var(--yc-color-line-generic-active); + &:focus-within { + border-color: var(--yc-color-line-generic-active); } } } &_clear { - #{$block}__control { + & #{$block}__content { border: 1px solid transparent; border-left: 0; border-right: 0; border-radius: 0; + } + & #{$block}__control { padding-left: 0; padding-right: 0; } @@ -214,13 +226,13 @@ $block: '.#{variables.$ns}text-input'; @include mixins.pin( $block, - #{$block}__control, + #{$block}__content, var(--yc-text-input-border-radius), $append: false ); &_disabled { - #{$block}__control { + #{$block}__content { background-color: var(--yc-color-base-generic-accent-disabled); color: var(--yc-color-text-hint); border-color: transparent; @@ -230,6 +242,10 @@ $block: '.#{variables.$ns}text-input'; } } + #{$block}__control { + color: var(--yc-color-text-hint); + } + #{$block}__label { color: var(--yc-color-text-hint); } @@ -241,25 +257,37 @@ $block: '.#{variables.$ns}text-input'; } } + &_has-left-content { + #{$block}__control { + padding-left: 2px; + } + } + + &_has-right-content { + #{$block}__control { + padding-right: 2px; + } + } + &_state { &_error { &#{$block}_view_normal { - #{$block}__control { + #{$block}__content { border-color: var(--yc-color-line-danger); &:hover, - &:focus { + &:focus-within { border-color: var(--yc-color-line-danger); } } } &#{$block}_view_clear { - #{$block}__control { + #{$block}__content { border-bottom: 1px solid var(--yc-color-line-danger); &:hover, - &:focus { + &:focus-within { border-bottom: 1px solid var(--yc-color-line-danger); } } diff --git a/src/components/TextInput/TextInput.tsx b/src/components/TextInput/TextInput.tsx index 49c0d1ddfb..c28104ae99 100644 --- a/src/components/TextInput/TextInput.tsx +++ b/src/components/TextInput/TextInput.tsx @@ -1,15 +1,12 @@ import React from 'react'; -import {block} from '../utils/cn'; +import {block, modsClassName} from '../utils/cn'; import {useForkRef} from '../utils/useForkRef'; import {useElementSize} from '../utils/useElementSize'; import {useUniqId} from '../utils/useUniqId'; -import {TextAreaControl} from './TextAreaControl/TextAreaControl'; import {InputControl} from './InputControl/InputControl'; -import {Button} from '../Button'; -import {Icon} from '../Icon'; -import {CrossIcon} from '../icons/CrossIcon'; +import {TextAreaControl} from './TextAreaControl/TextAreaControl'; +import {ClearAction} from './ClearAction/ClearAction'; import {TextInputProps, TextInputView, TextInputSize, TextInputPin, TextInputState} from './types'; -import i18n from './i18n'; import './TextInput.scss'; @@ -33,6 +30,7 @@ const prepareAutoComplete = (autoComplete: TextInputProps['autoComplete']): stri } }; +// eslint-disable-next-line complexity export const TextInput = React.forwardRef(function TextInput( props, ref, @@ -157,38 +155,37 @@ export const TextInput = React.forwardRef(funct { view, size, - pin: view === 'clear' ? undefined : pin, disabled, state, - 'has-clear': hasClear, + pin: view === 'clear' ? undefined : pin, + 'has-left-content': isLabelVisible, + 'has-right-content': isClearControlVisible && !multiline, 'has-scrollbar': hasVerticalScrollbar, }, className, )} data-qa={qa} > - {isLabelVisible && ( - - )} - {multiline ? ( - - ) : ( - - )} - + + {isLabelVisible && ( + + )} + {multiline ? ( + + ) : ( + + )} + {isClearControlVisible && ( + + )} + {isErrorMsgVisible &&
{error}
} - {hasClear && ( - - )} ); }); diff --git a/src/components/TextInput/__tests__/TextInput.input.test.tsx b/src/components/TextInput/__tests__/TextInput.input.test.tsx index 1ab297e59d..f23f917c3e 100644 --- a/src/components/TextInput/__tests__/TextInput.input.test.tsx +++ b/src/components/TextInput/__tests__/TextInput.input.test.tsx @@ -29,10 +29,15 @@ describe('TextInput input', () => { expect(container.querySelector('.yc-text-input__error')).not.toBeInTheDocument(); }); - test('render clear button with hasClear prop', () => { + test('check clear button visibility with hasClear prop', async () => { render(); - - expect(screen.getByRole('button', {name: 'Clear input value'})).toBeInTheDocument(); + const user = userEvent.setup(); + const input = screen.getByRole('textbox'); + let clearButton = screen.queryByRole('button', {name: 'Clear input value'}); + expect(clearButton).not.toBeInTheDocument(); + await user.type(input, 'abc'); + clearButton = screen.queryByRole('button', {name: 'Clear input value'}); + expect(clearButton).toBeInTheDocument(); }); test('do not render clear button without hasClear prop', () => { @@ -66,6 +71,8 @@ describe('TextInput input', () => { const onChangeFn = jest.fn(); const user = userEvent.setup(); render(); + const input = screen.getByRole('textbox'); + await user.type(input, 'abc'); const clear = screen.getByRole('button', {name: 'Clear input value'}); if (clear) { @@ -74,19 +81,6 @@ describe('TextInput input', () => { expect(onChangeFn).toBeCalled(); }); - - test('call onUpdate with emply value when click to clean button', async () => { - const onUpdateFn = jest.fn(); - const user = userEvent.setup(); - render(); - const clear = screen.getByRole('button', {name: 'Clear input value'}); - - if (clear) { - await user.click(clear); - } - - expect(onUpdateFn).toBeCalledWith(''); - }); }); describe('autocomplete', () => { From ca3e624373b8135c40add4151cbd65ea4f83515d Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 26 Apr 2023 13:29:47 +0200 Subject: [PATCH 05/13] chore: dedupe `tabbable` (#647) --- package-lock.json | 13 +++---------- package.json | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 105c7175b4..9ae49d7657 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15030,13 +15030,6 @@ "integrity": "sha512-yI7FwUqU4TVb+7t6PaQ3spT/42r/KLEi8mtdGoQo2li/kFzmu9URmalTvw7xCCJtSOyhBxscvEAmvjeN9iHARg==", "requires": { "tabbable": "^6.1.1" - }, - "dependencies": { - "tabbable": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz", - "integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==" - } } }, "for-each": { @@ -26175,9 +26168,9 @@ "dev": true }, "tabbable": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.0.1.tgz", - "integrity": "sha512-SYJSIgeyXW7EuX1ytdneO5e8jip42oHWg9xl/o3oTYhmXusZVgiA+VlPvjIN+kHii9v90AmzTZEBcsEvuAY+TA==" + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz", + "integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==" }, "table": { "version": "6.8.0", diff --git a/package.json b/package.json index 6e69d0fd90..6965a4d851 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "react-virtualized-auto-sizer": "1.0.7", "react-window": "1.8.8", "resize-observer-polyfill": "1.5.1", - "tabbable": "6.0.1", + "tabbable": "6.1.1", "tslib": "2.3.1", "utility-types": "3.10.0" }, From 11ff86a98c7176c1624976b94fe03c6b13769d36 Mon Sep 17 00:00:00 2001 From: Gravity UI Bot <111915794+gravity-ui-bot@users.noreply.github.com> Date: Wed, 26 Apr 2023 15:09:40 +0300 Subject: [PATCH 06/13] chore(main): release 4.10.0 (#644) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6841e20a92..0557bddeb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [4.10.0](https://github.com/gravity-ui/uikit/compare/v4.9.0...v4.10.0) (2023-04-26) + + +### Features + +* **Popover:** let action and cancel buttons to wrap on long text ([#631](https://github.com/gravity-ui/uikit/issues/631)) ([f22f9b5](https://github.com/gravity-ui/uikit/commit/f22f9b5ed2b864fbccb19118b142b6e03285296a)) + ## [4.9.0](https://github.com/gravity-ui/uikit/compare/v4.8.1...v4.9.0) (2023-04-20) diff --git a/package-lock.json b/package-lock.json index 9ae49d7657..cd89a38c8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@gravity-ui/uikit", - "version": "4.9.0", + "version": "4.10.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6965a4d851..b9a2819aba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gravity-ui/uikit", - "version": "4.9.0", + "version": "4.10.0", "description": "Gravity UI base styling and components", "license": "MIT", "repository": { From fd29127d30df8659da3785fc1417cae778846842 Mon Sep 17 00:00:00 2001 From: "Mr.Dr.Professor Patrick" Date: Thu, 27 Apr 2023 17:37:06 +0200 Subject: [PATCH 07/13] feat(TextInput): add rightContent props (#649) --- src/components/TextInput/README.md | 4 + src/components/TextInput/TextInput.scss | 23 ++--- src/components/TextInput/TextInput.tsx | 8 +- .../__stories__/TextInputShowcase.scss | 6 -- .../__stories__/TextInputShowcase.tsx | 90 +++++++++++++++++++ src/components/TextInput/types.ts | 4 + 6 files changed, 117 insertions(+), 18 deletions(-) diff --git a/src/components/TextInput/README.md b/src/components/TextInput/README.md index 5e37bd59a4..60bd809fb9 100644 --- a/src/components/TextInput/README.md +++ b/src/components/TextInput/README.md @@ -91,6 +91,10 @@ export interface TextInputProps extends DOMProps, QAProps { * Maximum number of rows in textarea when the hight is autogenerated. */ maxRows?: number; + /** + * User`s node rendered after input and clear button + */ + rightContent?: React.ReactNode; onUpdate?: (value: string) => void; onChange?: React.ChangeEventHandler; onFocus?: React.FocusEventHandler; diff --git a/src/components/TextInput/TextInput.scss b/src/components/TextInput/TextInput.scss index f31d23dc5d..9a0936a29e 100644 --- a/src/components/TextInput/TextInput.scss +++ b/src/components/TextInput/TextInput.scss @@ -128,6 +128,11 @@ $block: '.#{variables.$ns}text-input'; } } + &__additional-content { + display: flex; + align-items: center; + } + &_size { &_s { #{$block}__control { @@ -139,7 +144,8 @@ $block: '.#{variables.$ns}text-input'; } #{$block}__additional-content { - height: #{$sHeight}; + height: #{$sHeight - $borderWidth * 2}; + padding-right: 1px; } --yc-text-input-border-radius: var(--yc-border-radius-s); @@ -155,7 +161,8 @@ $block: '.#{variables.$ns}text-input'; } #{$block}__additional-content { - height: #{$mHeight}; + height: #{$mHeight - $borderWidth * 2}; + padding-right: 1px; } --yc-text-input-border-radius: var(--yc-border-radius-m); @@ -171,7 +178,8 @@ $block: '.#{variables.$ns}text-input'; } #{$block}__additional-content { - height: #{$lHeight}; + height: #{$lHeight - $borderWidth * 2}; + padding-right: 3px; } --yc-text-input-border-radius: var(--yc-border-radius-l); @@ -187,7 +195,8 @@ $block: '.#{variables.$ns}text-input'; } #{$block}__additional-content { - height: #{$xlHeight}; + height: #{$xlHeight - $borderWidth * 2}; + padding-right: 3px; } --yc-text-input-border-radius: var(--yc-border-radius-xl); @@ -257,12 +266,6 @@ $block: '.#{variables.$ns}text-input'; } } - &_has-left-content { - #{$block}__control { - padding-left: 2px; - } - } - &_has-right-content { #{$block}__control { padding-right: 2px; diff --git a/src/components/TextInput/TextInput.tsx b/src/components/TextInput/TextInput.tsx index c28104ae99..77f76885fc 100644 --- a/src/components/TextInput/TextInput.tsx +++ b/src/components/TextInput/TextInput.tsx @@ -6,6 +6,7 @@ import {useUniqId} from '../utils/useUniqId'; import {InputControl} from './InputControl/InputControl'; import {TextAreaControl} from './TextAreaControl/TextAreaControl'; import {ClearAction} from './ClearAction/ClearAction'; +import {AdditionalContent} from './AdditionalContent/AdditionalContent'; import {TextInputProps, TextInputView, TextInputSize, TextInputPin, TextInputState} from './types'; import './TextInput.scss'; @@ -56,6 +57,7 @@ export const TextInput = React.forwardRef(funct className, qa, controlProps: originalControlProps, + rightContent, } = props; const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue ?? ''); const innerControlRef = React.useRef(null); @@ -118,6 +120,7 @@ export const TextInput = React.forwardRef(funct const isErrorMsgVisible = typeof error === 'string'; const isClearControlVisible = Boolean(hasClear && !disabled && inputValue); + const isRightContentVisible = Boolean(rightContent && !multiline); const controlProps: TextInputProps['controlProps'] = { ...originalControlProps, @@ -158,8 +161,8 @@ export const TextInput = React.forwardRef(funct disabled, state, pin: view === 'clear' ? undefined : pin, - 'has-left-content': isLabelVisible, - 'has-right-content': isClearControlVisible && !multiline, + 'has-right-content': + (isClearControlVisible || isRightContentVisible) && !multiline, 'has-scrollbar': hasVerticalScrollbar, }, className, @@ -184,6 +187,7 @@ export const TextInput = React.forwardRef(funct onClick={handleClear} /> )} + {isRightContentVisible && {rightContent}} {isErrorMsgVisible &&
{error}
} diff --git a/src/components/TextInput/__stories__/TextInputShowcase.scss b/src/components/TextInput/__stories__/TextInputShowcase.scss index 3b56bfc34a..f3acc7c642 100644 --- a/src/components/TextInput/__stories__/TextInputShowcase.scss +++ b/src/components/TextInput/__stories__/TextInputShowcase.scss @@ -1,10 +1,4 @@ .text-input-showcase { - display: grid; - grid-template: - 'text-input' auto - 'text-input-label' auto - 'text-area' auto / auto; - &__text-input-examples { grid-area: text-input; display: grid; diff --git a/src/components/TextInput/__stories__/TextInputShowcase.tsx b/src/components/TextInput/__stories__/TextInputShowcase.tsx index eee8f63c5a..0f8f1d45f9 100644 --- a/src/components/TextInput/__stories__/TextInputShowcase.tsx +++ b/src/components/TextInput/__stories__/TextInputShowcase.tsx @@ -1,6 +1,9 @@ import React from 'react'; import block from 'bem-cn-lite'; import {Checkbox} from '../../Checkbox'; +import {Button} from '../../Button'; +import {Icon} from '../../Icon'; +import {GearIcon} from '../../icons'; import {TextInput} from '../TextInput'; import {TextInputProps} from '../types'; import './TextInputShowcase.scss'; @@ -10,6 +13,25 @@ const b = block('text-input-showcase'); const LABEL = 'Label:'; const LONG_LABEL = 'Very very long label is limited by 50% width of the input control size'; +const RightContent = (props: {size: TextInputProps['size']; disabled?: boolean}) => { + const {size, disabled} = props; + const [selected, setSelected] = React.useState(false); + + const handleClick = () => setSelected(!selected); + + return ( + + ); +}; + export const TextInputShowcase: React.FC = () => { const [value, setValue] = React.useState(''); const [isErrorMessageVisible, setErrorMessageVisibility] = React.useState(false); @@ -112,6 +134,74 @@ export const TextInputShowcase: React.FC = () => { +
+

TextInput (with right content)

+ +
+

Sizes:

+ + } + /> + } + /> + } + /> + } + /> +
+ +
+

States:

+ +
+ } + /> + +
+ } + disabled + /> + } + hasClear + /> + } + /> +
+
+

TextInput (multiline)

diff --git a/src/components/TextInput/types.ts b/src/components/TextInput/types.ts index d32b252449..a0f5583daf 100644 --- a/src/components/TextInput/types.ts +++ b/src/components/TextInput/types.ts @@ -75,6 +75,10 @@ export interface TextInputProps extends DOMProps, QAProps { * Maximum number of rows in textarea when the hight is autogenerated. */ maxRows?: number; + /** + * User`s node rendered after input and clear button + */ + rightContent?: React.ReactNode; onUpdate?: (value: string) => void; onChange?: React.ChangeEventHandler; onFocus?: React.FocusEventHandler; From fe05925d6b47ff9cc0d4786c5cb435089e3a7987 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 28 Apr 2023 17:30:41 +0200 Subject: [PATCH 08/13] feat(UserAvatar): add `srcset` support (#641) --- src/components/UserAvatar/README.md | 2 ++ src/components/UserAvatar/UserAvatar.scss | 11 ++++-- src/components/UserAvatar/UserAvatar.tsx | 35 +++++++++++++------ .../__stories__/UserAvatar.stories.tsx | 32 +++++++++++++++-- .../UserAvatar/__stories__/getAvatarSrcSet.ts | 24 +++++++++++++ .../__stories__/getClosestNumber.ts | 26 ++++++++++++++ .../UserAvatar/__stories__/getSrcSet.ts | 19 ++++++++++ .../UserAvatar/__stories__/types.ts | 11 ++++++ src/components/UserAvatar/constants.ts | 9 +++++ src/components/UserAvatar/index.ts | 2 ++ src/components/UserAvatar/types.ts | 1 + 11 files changed, 157 insertions(+), 15 deletions(-) create mode 100644 src/components/UserAvatar/__stories__/getAvatarSrcSet.ts create mode 100644 src/components/UserAvatar/__stories__/getClosestNumber.ts create mode 100644 src/components/UserAvatar/__stories__/getSrcSet.ts create mode 100644 src/components/UserAvatar/__stories__/types.ts create mode 100644 src/components/UserAvatar/constants.ts create mode 100644 src/components/UserAvatar/types.ts diff --git a/src/components/UserAvatar/README.md b/src/components/UserAvatar/README.md index 8f19f308b1..086f2e550d 100644 --- a/src/components/UserAvatar/README.md +++ b/src/components/UserAvatar/README.md @@ -8,5 +8,7 @@ Component for displaying user avatar. | :-------- | :--------------- | :------- | :------ | :--------------------------------------------------------- | | imgUrl | `string` | | | Link to image | | size | `UserAvatarSize` | | 'm' | Component size. Possible values: `xs`, `s`, `m`, `l`, `xl` | +| srcSet | `string` | | | `srcSet` attribute of the image | +| sizes | `string` | | | `sizes` attribute of the image | | title | `string` | | | Tooltip text on hover | | className | `string` | | | Class name | diff --git a/src/components/UserAvatar/UserAvatar.scss b/src/components/UserAvatar/UserAvatar.scss index 639118e167..7e18f9be27 100644 --- a/src/components/UserAvatar/UserAvatar.scss +++ b/src/components/UserAvatar/UserAvatar.scss @@ -3,13 +3,16 @@ $block: '.#{variables.$ns}user-avatar'; #{$block} { - box-sizing: border-box; display: inline-block; + overflow: hidden; + + box-sizing: border-box; + + border-radius: 50%; background-color: var(--yc-color-base-background); background-repeat: no-repeat; background-position: center; background-size: cover; - border-radius: 50%; &_size { &_xs { @@ -37,4 +40,8 @@ $block: '.#{variables.$ns}user-avatar'; height: 50px; } } + + &__figure { + object-fit: cover; + } } diff --git a/src/components/UserAvatar/UserAvatar.tsx b/src/components/UserAvatar/UserAvatar.tsx index 28da8c28ff..994f66f125 100644 --- a/src/components/UserAvatar/UserAvatar.tsx +++ b/src/components/UserAvatar/UserAvatar.tsx @@ -1,12 +1,14 @@ import React from 'react'; import {block} from '../utils/cn'; +import {SIZES} from './constants'; +import type {UserAvatarSize} from './types'; import './UserAvatar.scss'; -export type UserAvatarSize = 'xs' | 's' | 'm' | 'l' | 'xl'; - export interface UserAvatarProps { imgUrl?: string; size?: UserAvatarSize; + srcSet?: string; + sizes?: string; title?: string; className?: string; /** @deprecated Use appropriate component, like ` + diff --git a/src/components/Button/__stories__/ButtonShowcase.tsx b/src/components/Button/__stories__/ButtonShowcase.tsx index 6e30ccef93..e795d907b0 100644 --- a/src/components/Button/__stories__/ButtonShowcase.tsx +++ b/src/components/Button/__stories__/ButtonShowcase.tsx @@ -16,6 +16,8 @@ export function ButtonShowcase() { {renderViewGrid()}

+ + diff --git a/src/components/Button/__stories__/examples/ButtonExampleView/ButtonExampleView.tsx b/src/components/Button/__stories__/examples/ButtonExampleView/ButtonExampleView.tsx index 266af18a3b..ff44910699 100644 --- a/src/components/Button/__stories__/examples/ButtonExampleView/ButtonExampleView.tsx +++ b/src/components/Button/__stories__/examples/ButtonExampleView/ButtonExampleView.tsx @@ -238,6 +238,7 @@ export function ButtonExampleState() { export function ButtonExampleSize() { return ( + diff --git a/src/components/Button/__tests__/Button.test.tsx b/src/components/Button/__tests__/Button.test.tsx index b9204269b4..389879a8f8 100644 --- a/src/components/Button/__tests__/Button.test.tsx +++ b/src/components/Button/__tests__/Button.test.tsx @@ -48,12 +48,15 @@ describe('Button', () => { expect(button).not.toBeDisabled(); }); - test.each(new Array('s', 'm', 'l', 'xl'))('render with given "%s" size', (size) => { - render(