Skip to content

Commit

Permalink
Merge pull request #7666 from VKCOM/e.muhamethanov/7665/users-stack-d…
Browse files Browse the repository at this point in the history
…irection-to-avatarsPosition

feat(UsersStack): replace direction prop to avatarsPosition
  • Loading branch information
EldarMuhamethanov authored Sep 26, 2024
2 parents 4b12821 + 830bf51 commit f0f463c
Show file tree
Hide file tree
Showing 23 changed files with 208 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { UsersStack } from '@vkontakte/vkui';
import React from 'react';

const App = () => {
return (
<React.Fragment>
{/* direction="row" -> avatarsPosition="start" */}
<UsersStack
photos={[]}
direction="row"
size="s"
>
Иван и ещё 2 ваших друга подписаны
</UsersStack>

{/* direction="row-reverse" -> avatarsPosition="end" */}
<UsersStack
photos={[]}
direction={"row-reverse"}
size="m"
>
Иван и ещё 2 ваших друга подписаны
</UsersStack>

{/* direction="column" -> avatarsPosition="top" */}
<UsersStack
photos={[]}
direction="column"
size="l"
>
Иван и ещё 2 ваших друга подписаны
</UsersStack>

{/* do nothing */}
<UsersStack
photos={[]}
size="s"
>
Иван и ещё 2 ваших друга подписаны
</UsersStack>
</React.Fragment>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`users-stack transforms correctly 1`] = `
"import { UsersStack } from '@vkontakte/vkui';
import React from 'react';
const App = () => {
return (
(<React.Fragment>
{/* direction="row" -> avatarsPosition="start" */}
<UsersStack
photos={[]}
avatarsPosition="inline-start"
size="s"
>
Иван и ещё 2 ваших друга подписаны
</UsersStack>
{/* direction="row-reverse" -> avatarsPosition="end" */}
<UsersStack
photos={[]}
avatarsPosition="inline-end"
size="m"
>
Иван и ещё 2 ваших друга подписаны
</UsersStack>
{/* direction="column" -> avatarsPosition="top" */}
<UsersStack
photos={[]}
avatarsPosition="block-start"
size="l"
>
Иван и ещё 2 ваших друга подписаны
</UsersStack>
{/* do nothing */}
<UsersStack
photos={[]}
size="s"
>
Иван и ещё 2 ваших друга подписаны
</UsersStack>
</React.Fragment>)
);
};"
`;
11 changes: 11 additions & 0 deletions packages/codemods/src/transforms/v7/__tests__/users-stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
jest.autoMockOff();
import { defineSnapshotTestFromFixture } from '../../../testHelpers/testHelper';

const name = 'users-stack';
const fixtures = ['basic'] as const;

describe(name, () => {
fixtures.forEach((test) =>
defineSnapshotTestFromFixture(__dirname, name, global.TRANSFORM_OPTIONS, `${name}/${test}`),
);
});
57 changes: 57 additions & 0 deletions packages/codemods/src/transforms/v7/users-stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { API, FileInfo, JSXAttribute } from 'jscodeshift';
import { getImportInfo } from '../../codemod-helpers';
import { report } from '../../report';
import { JSCodeShiftOptions } from '../../types';

export const parser = 'tsx';

export default function transformer(file: FileInfo, api: API, options: JSCodeShiftOptions) {
const { alias } = options;
const j = api.jscodeshift;
const source = j(file.source);
const { localName } = getImportInfo(j, file, 'UsersStack', alias);
if (!localName) {
return source.toSource();
}

const attributeToReplace = 'direction';
const newAttributeName = 'avatarsPosition';

const directionToAvatarsPosition: Record<string, string> = {
'row': 'inline-start',
'row-reverse': 'inline-end',
'column': 'block-start',
};

const getValueFromAttribute = (attribute: JSXAttribute): string | null => {
if (attribute.value?.type === 'StringLiteral') {
return attribute.value.value;
}
if (attribute.value?.type === 'JSXExpressionContainer') {
const expression = attribute.value.expression;
if (expression.type === 'StringLiteral') {
return expression.value;
}
}
return null;
};

source
.find(j.JSXElement, { openingElement: { name: { name: localName } } })
.find(j.JSXAttribute, { name: { name: attributeToReplace } })
.forEach((path) => {
const avatar = path.node;
avatar.name.name = newAttributeName;
const value = getValueFromAttribute(avatar);
if (!value || !directionToAvatarsPosition[value]) {
report(
api,
`: ${localName} has been changed. Manual changes required: need to change direction prop to avatarsPosition`,
);
return;
}
avatar.value = j.stringLiteral(directionToAvatarsPosition[value]);
});

return source.toSource();
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ export const ModalCardPlayground = (props: ComponentPlaygroundProps) => {
children: [
<React.Fragment key="userstack">
<Spacing size={20} />
<UsersStack photos={['', '', '', '']} size="l" visibleCount={3} direction="column">
<UsersStack
photos={['', '', '', '']}
size="l"
visibleCount={3}
avatarsPosition="block-start"
>
Алексей, Илья, Михаил
<br />и ещё 3 человека
</UsersStack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export const CardWithComplexContent: Story = {
]}
size="l"
visibleCount={3}
direction="column"
avatarsPosition="block-start"
>
Алексей, Илья, Михаил
<br />и ещё 3 человека
Expand Down
2 changes: 1 addition & 1 deletion packages/vkui/src/components/ModalCardBase/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
}
>
<Spacing size={20} />
<UsersStack photos={[getAvatarUrl('user_lihachyov')]} direction="column">
<UsersStack photos={[getAvatarUrl('user_lihachyov')]} avatarsPosition="block-start">
Понравилось Муртолу Левзачеву
</UsersStack>
</ModalCardBase>
Expand Down
2 changes: 1 addition & 1 deletion packages/vkui/src/components/ModalRoot/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ const App = () => {
]}
size="l"
visibleCount={3}
direction="column"
avatarsPosition="block-start"
>
Алексей, Илья, Михаил
<br />и ещё 3 человека
Expand Down
6 changes: 3 additions & 3 deletions packages/vkui/src/components/UsersStack/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const App = () => {
</UsersStack>
</Div>
<Div>
<UsersStack direction="row-reverse" photos={[getAvatarUrl('user_lihachyov')]}>
<UsersStack avatarsPosition="inline-end" photos={[getAvatarUrl('user_lihachyov')]}>
Понравилось Муртолу Левзачеву
</UsersStack>
</Div>
Expand Down Expand Up @@ -74,7 +74,7 @@ const App = () => {
getAvatarUrl('user_xyz'),
]}
size="l"
direction="column"
avatarsPosition="block-start"
>
Алексей, Илья, Михаил
<br />и ещё 3 человека
Expand Down Expand Up @@ -114,7 +114,7 @@ const App = () => {
{ src: getAvatarUrl('user_xyz'), renderWrapper: AvatarWrapper },
]}
size="l"
direction="column"
avatarsPosition="block-start"
>
Иван и ещё 2 ваших друга подписаны
</UsersStack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const UsersStackPlayground = (props: ComponentPlaygroundProps) => {
{
children: ['Понравилось Анне и ещё XX людям'],
size: ['s', 'm', 'l'],
direction: ['row', 'column', 'row-reverse'],
avatarsPosition: ['inline-start', 'block-start', 'inline-end'],
photos: [
[base64Image],
[base64Image, base64Image],
Expand All @@ -27,7 +27,7 @@ export const UsersStackPlayground = (props: ComponentPlaygroundProps) => {
// при пустом children отсутствуют отступы
{
children: [undefined],
direction: ['row', 'column', 'row-reverse'],
avatarsPosition: ['inline-start', 'block-start', 'inline-end'],
photos: [[base64Image, base64Image, base64Image]],
},
]}
Expand Down
10 changes: 5 additions & 5 deletions packages/vkui/src/components/UsersStack/UsersStack.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
color: var(--vkui--color_text_secondary);
}

.directionRowReverse {
.avatarsPositionInlineEnd {
flex-direction: row-reverse;
}

.directionColumn {
.avatarsPositionBlockStart {
flex-direction: column;
justify-content: center;
}
Expand Down Expand Up @@ -58,15 +58,15 @@
flex: 1;
}

.directionColumn .text {
.avatarsPositionBlockStart .text {
text-align: center;
margin-block-start: 8px;
}

.directionRow .text {
.avatarsPositionInlineStart .text {
margin-inline-start: 8px;
}

.directionRowReverse .text {
.avatarsPositionInlineEnd .text {
margin-inline-end: 8px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const Playground: Story = {
args: {
children: 'Алексей, Илья, Михаил и ещё 1 человек',
photos: [getAvatarUrl(), getAvatarUrl(), getAvatarUrl(), getAvatarUrl()],
direction: 'row',
avatarsPosition: 'inline-start',
},
};

Expand Down
23 changes: 13 additions & 10 deletions packages/vkui/src/components/UsersStack/UsersStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ const stylesSize = {
l: styles.sizeL,
};

const stylesDirection = {
'row': styles.directionRow,
'row-reverse': styles.directionRowReverse,
'column': styles.directionColumn,
const avatarsPositionStyles = {
'inline-start': styles.avatarsPositionInlineStart,
'inline-end': styles.avatarsPositionInlineEnd,
'block-start': styles.avatarsPositionBlockStart,
};

export type UsersStackRenderWrapperProps = {
Expand Down Expand Up @@ -49,11 +49,10 @@ export interface UsersStackProps extends HTMLAttributesWithRootRef<HTMLDivElemen
*/
count?: number;
/**
* Определяет положение элементов
* Режим `column` рекомендуется использовать с размером `m`
* @since 5.3.0
* Определяет положение аватаров
* Режим `block-start` рекомендуется использовать с размером `m`
*/
direction?: 'row' | 'row-reverse' | 'column';
avatarsPosition?: 'inline-start' | 'block-start' | 'inline-end';
}

interface PathElementProps extends React.SVGAttributes<SVGElement> {
Expand Down Expand Up @@ -132,7 +131,7 @@ export const UsersStack = ({
count = Math.max(0, photos.length - visibleCount),
size = 'm',
children,
direction = 'row',
avatarsPosition = 'inline-start',
...restProps
}: UsersStackProps): React.ReactNode => {
const cmpId = React.useId();
Expand Down Expand Up @@ -193,7 +192,11 @@ export const UsersStack = ({
return (
<RootComponent
{...restProps}
baseClassName={classNames(styles.host, stylesSize[size], stylesDirection[direction])}
baseClassName={classNames(
styles.host,
stylesSize[size],
avatarsPositionStyles[avatarsPosition],
)}
>
{(photosElements.length > 0 || othersElement) && (
<div className={styles.photos} aria-hidden>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f0f463c

Please sign in to comment.