Skip to content

Commit

Permalink
feat(HorizontalCell): add custom width support (#7807)
Browse files Browse the repository at this point in the history
* feat(HorizontalCell): add custom width support

* fix: fix codemod error

* feat(HorizontalCellShowMore): change size values

feat(ScrollArrow): change size values
  • Loading branch information
BlackySoul authored Oct 22, 2024
1 parent 1d4b706 commit 90ea9e0
Show file tree
Hide file tree
Showing 60 changed files with 363 additions and 197 deletions.
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
import { HorizontalCellShowMore, HorizontalScroll } from '@vkontakte/vkui';
import { HorizontalCellShowMore } from '@vkontakte/vkui';
import React from 'react';
import '@vkontakte/vkui/dist/vkui.css';

const App = () => {
return (
<React.Fragment>
<HorizontalScroll>
<div />
<div />
<div />
<HorizontalCellShowMore onClick={() => {}} compensateLastCellIndent size="m" height={88} />
</HorizontalScroll>
<HorizontalScroll>
<div />
<div />
<div />
<HorizontalCellShowMore onClick={() => {}} compensateLastCellIndent={true} size="m" height={88} />
</HorizontalScroll>
<HorizontalCellShowMore compensateLastCellIndent size="m" height={88} />
<HorizontalCellShowMore compensateLastCellIndent={true} size="l" height={88} />
<HorizontalCellShowMore compensateLastCellIndent={false} size="s" height={88} />
</React.Fragment>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Gallery, HorizontalScroll, ScrollArrow } from '@vkontakte/vkui';
import React from 'react';

const App = () => {
return (
<React.Fragment>
<ScrollArrow direction='down' size='m' />
<ScrollArrow direction='left' size='l' />
<HorizontalScroll arrowSize='m' />
<HorizontalScroll arrowSize='l' />
<Gallery arrowSize='m' />
<Gallery arrowSize='l' />
</React.Fragment>
);
};
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`horizontal-cell-show-more transforms correctly 1`] = `
"import { HorizontalCellShowMore, HorizontalScroll } from '@vkontakte/vkui';
"import { HorizontalCellShowMore } from '@vkontakte/vkui';
import React from 'react';
import '@vkontakte/vkui/dist/vkui.css';
const App = () => {
return (
(<React.Fragment>
<HorizontalScroll>
<div />
<div />
<div />
<HorizontalCellShowMore onClick={() => {}} size="m" height={88} />
</HorizontalScroll>
<HorizontalScroll>
<div />
<div />
<div />
<HorizontalCellShowMore onClick={() => {}} size="m" height={88} />
</HorizontalScroll>
<HorizontalCellShowMore size="m" height={88} />
<HorizontalCellShowMore size="m" height={88} />
<HorizontalCellShowMore size="s" height={88} />
</React.Fragment>)
);
};"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`scroll-arrow transforms correctly 1`] = `
"import { Gallery, HorizontalScroll, ScrollArrow } from '@vkontakte/vkui';
import React from 'react';
const App = () => {
return (
(<React.Fragment>
<ScrollArrow direction='down' size="s" />
<ScrollArrow direction='left' size="m" />
<HorizontalScroll arrowSize="s" />
<HorizontalScroll arrowSize="m" />
<Gallery arrowSize="s" />
<Gallery arrowSize="m" />
</React.Fragment>)
);
};"
`;
12 changes: 12 additions & 0 deletions packages/codemods/src/transforms/v7/__tests__/scroll-arrow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
jest.autoMockOff();

import { defineSnapshotTestFromFixture } from '../../../testHelpers/testHelper';

const name = 'scroll-arrow';
const fixtures = ['basic'] as const;

describe(name, () => {
fixtures.forEach((test) =>
defineSnapshotTestFromFixture(__dirname, name, global.TRANSFORM_OPTIONS, `${name}/${test}`),
);
});
65 changes: 46 additions & 19 deletions packages/codemods/src/transforms/v7/horizontal-cell-show-more.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
import { API, FileInfo } from 'jscodeshift';
import { API, ASTPath, FileInfo, JSXAttribute } from 'jscodeshift';
import { getImportInfo } from '../../codemod-helpers';
import { report } from '../../report';
import { JSCodeShiftOptions } from '../../types';

export const parser = 'tsx';

const componentName = 'HorizontalCellShowMore';

function compensateLastCellIndentManipulator(api: API, attribute: ASTPath<JSXAttribute>) {
const node = attribute.node;

if (!node.value) {
api.jscodeshift(attribute).remove();
} else if (
node.value.type === 'JSXExpressionContainer' &&
node.value.expression.type === 'BooleanLiteral'
) {
api.jscodeshift(attribute).remove();
} else {
report(
api,
`Manual changes required for ${componentName}'s "compensateLastCellIndent" prop. You might not need it anymore.`,
);
}
}

function sizeManipulator(api: API, attribute: ASTPath<JSXAttribute>) {
const node = attribute.node;

if (node.value?.type === 'StringLiteral') {
if (node.value.value !== 's') {
node.value = api.jscodeshift.stringLiteral('m');
}
} else {
report(
api,
`Manual changes required for ${componentName}'s "size" prop. Use "s" or "m" value only.`,
);
}
}

export default function transformer(file: FileInfo, api: API, options: JSCodeShiftOptions) {
const { alias } = options;
const j = api.jscodeshift;
Expand All @@ -21,25 +55,18 @@ export default function transformer(file: FileInfo, api: API, options: JSCodeShi
.filter(
(path) => path.value.name.type === 'JSXIdentifier' && path.value.name.name === localName,
)
.find(j.JSXAttribute)
.filter((attribute) => attribute.node.name.name === 'compensateLastCellIndent')
.find(
j.JSXAttribute,
(attribute) =>
attribute.name.name === 'compensateLastCellIndent' || attribute.name.name === 'size',
)
.forEach((attribute) => {
const node = attribute.node;

if (!node.value) {
j(attribute).remove();
} else if (
node.value.type === 'JSXExpressionContainer' &&
node.value.expression.type === 'BooleanLiteral'
) {
if (node.value.expression.value) {
j(attribute).remove();
} else {
report(
api,
`Manual changes required for ${componentName}'s "compensateLastCellIndent" prop. You might not need it anymore.`,
);
}
const attributeName = attribute.node.name.name;

if (attributeName === 'compensateLastCellIndent') {
compensateLastCellIndentManipulator(api, attribute);
} else if (attributeName === 'size') {
sizeManipulator(api, attribute);
}
});

Expand Down
68 changes: 68 additions & 0 deletions packages/codemods/src/transforms/v7/scroll-arrow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { API, ASTPath, FileInfo, JSXAttribute } from 'jscodeshift';
import { getImportInfo } from '../../codemod-helpers';
import { report } from '../../report';
import { JSCodeShiftOptions } from '../../types';

export const parser = 'tsx';

const componentName = 'ScrollArrow';
const affectedComponents = ['HorizontalScroll', 'Gallery'];

function arrowSizeManipulator(api: API, attribute: ASTPath<JSXAttribute>) {
const node = attribute.node;

if (node.value?.type === 'StringLiteral') {
const oldValue = node.value.value;
const newValue = oldValue === 'm' ? 's' : oldValue === 'l' ? 'm' : undefined;
if (newValue) {
node.value = api.jscodeshift.stringLiteral(newValue);
}
} else {
report(
api,
`Manual changes required for ${componentName}'s "size" prop. Use "s" or "m" value only.`,
);
}
}

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, componentName, alias);
const { localName: horizontalScrollLocalName } = getImportInfo(
j,
file,
affectedComponents[0],
alias,
);
const { localName: galleryLocalName } = getImportInfo(j, file, affectedComponents[1], alias);

if (!localName) {
return source.toSource();
}

source
.find(j.JSXOpeningElement)
.filter(
(path) => path.value.name.type === 'JSXIdentifier' && path.value.name.name === localName,
)
.find(j.JSXAttribute, { name: { name: 'size' } })
.forEach((attribute) => {
arrowSizeManipulator(api, attribute);
});

source
.find(j.JSXOpeningElement)
.filter(
(path) =>
path.value.name.type === 'JSXIdentifier' &&
[horizontalScrollLocalName, galleryLocalName].includes(path.value.name.name),
)
.find(j.JSXAttribute, { name: { name: 'arrowSize' } })
.forEach((attribute) => {
arrowSizeManipulator(api, attribute);
});

return source.toSource();
}
2 changes: 1 addition & 1 deletion packages/vkui/src/components/BaseGallery/BaseGallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const BaseGallery = ({
align = 'left',
showArrows,
getRef,
arrowSize = 'l',
arrowSize = 'm',
...restProps
}: BaseGalleryProps): React.ReactNode => {
const slidesStore = React.useRef<Record<string, HTMLDivElement | null>>({});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const CarouselBase = ({
align = 'left',
showArrows,
getRef,
arrowSize = 'l',
arrowSize = 'm',
...restProps
}: BaseGalleryProps): React.ReactNode => {
const slidesStore = React.useRef<Record<string, HTMLDivElement | null>>({});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const GalleryWithArrowsPlayground = (props: ComponentPlaygroundProps) =>
return (
<ComponentPlayground {...props}>
{(props: GalleryProps) => (
<Gallery initialSlideIndex={1} data-testid="gallery" arrowSize="m" showArrows {...props}>
<Gallery initialSlideIndex={1} data-testid="gallery" arrowSize="s" showArrows {...props}>
{getItems()}
</Gallery>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ export const HorizontalCellPlayground = (props: ComponentPlaygroundProps) => {
>
<Image size={128} borderRadius="l" />
</HorizontalCell>
<HorizontalCell
{...restProps}
title={title}
subtitle={subtitle}
extraSubtitle={extraSubtitle}
size="xl"
>
<Image size={220} borderRadius="l" />
</HorizontalCell>
</div>
)}
</ComponentPlayground>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,19 @@
margin-block-start: 2px;
}

.sized {
--vkui_internal--side_cell_width: calc(
var(--vkui_internal--cell_width) + var(--vkui_internal--side_cell_gap)
);

max-inline-size: var(--vkui_internal--cell_width);
}

.sizeS {
--vkui_internal--side_cell_gap: calc(
var(--vkui--size_base_padding_horizontal--regular) - var(--vkui--spacing_size_m)
);
--vkui_internal--side_cell_width: calc(72px + var(--vkui_internal--side_cell_gap));

max-inline-size: 72px;
--vkui_internal--cell_width: 72px;
}

.image {
Expand All @@ -65,12 +71,18 @@
}

.sizeM {
--vkui_internal--side_cell_width: calc(100px + var(--vkui_internal--side_cell_gap));

max-inline-size: 100px;
--vkui_internal--cell_width: 100px;
}

.sizeL {
--vkui_internal--cell_width: 140px;
}

.sizeXL {
--vkui_internal--cell_width: 232px;
}

.sizeAuto {
inline-size: auto;
}

Expand All @@ -80,12 +92,7 @@
min-inline-size: var(--vkui_internal--side_cell_gap);
}

.sizeS:first-child,
.sizeS:last-child {
max-inline-size: var(--vkui_internal--side_cell_width);
}

.sizeM:first-child,
.sizeM:last-child {
.sized:first-child,
.sized:last-child {
max-inline-size: var(--vkui_internal--side_cell_width);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { render, screen } from '@testing-library/react';
import { baselineComponent } from '../../testing/utils';
import { HorizontalCell } from './HorizontalCell';
import { CUSTOM_CSS_TOKEN_FOR_CELL_WIDTH, HorizontalCell } from './HorizontalCell';
import styles from './HorizontaCell.module.css';

describe('HorizontalCell', () => {
Expand All @@ -24,4 +24,16 @@ describe('HorizontalCell', () => {

expect(document.querySelector(`.${styles.content}`)).not.toBeNull();
});

it('should use custom size', () => {
const h = render(<HorizontalCell size={100} title="Image" />);
expect(h.container.firstElementChild).toHaveStyle(`${CUSTOM_CSS_TOKEN_FOR_CELL_WIDTH}: 100px`);
});

it('should preserve user style', () => {
const h = render(<HorizontalCell size={100} style={{ background: 'red' }} />);
expect(h.container.firstElementChild).toHaveStyle(
`background: red; ${CUSTOM_CSS_TOKEN_FOR_CELL_WIDTH}: 100px`,
);
});
});
Loading

0 comments on commit 90ea9e0

Please sign in to comment.