Skip to content

Commit

Permalink
feat(Carousel): large mobilePageOffset support (#887)
Browse files Browse the repository at this point in the history
* WEB-1525 feat(Carousel): large mobilePageOffset support

* simplify var

* set mobilePageOffset to 36 in tablet

* remove unused import
  • Loading branch information
atabel authored Sep 22, 2023
1 parent dc861d5 commit 803506a
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 2 deletions.
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.
29 changes: 29 additions & 0 deletions src/__screenshot_tests__/carousel-screenshot-test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {openStoryPage, screen} from '../test-utils';
import {VIVO_NEW_SKIN} from '../skins/constants';

import type {ElementHandle} from 'puppeteer';

Expand All @@ -17,6 +18,34 @@ test('Carousel mobile', async () => {
expect(await page.screenshot()).toMatchImageSnapshot();
});

test('Carousel mobile in Vivo new', async () => {
const page = await openStoryPage({
id: 'components-carousels-carousel--default',
device: 'MOBILE_IOS',
skin: VIVO_NEW_SKIN,
});

expect(await page.screenshot()).toMatchImageSnapshot();

await (await screen.findByLabelText('Carousel item 2')).evaluate((el) => el.scrollIntoView());

expect(await page.screenshot()).toMatchImageSnapshot();
});

test('Carousel mobile with large mobilePageOffset', async () => {
const page = await openStoryPage({
id: 'components-carousels-carousel--default',
device: 'MOBILE_IOS',
args: {mobilePageOffset: 'large'},
});

expect(await page.screenshot()).toMatchImageSnapshot();

await (await screen.findByLabelText('Carousel item 2')).evaluate((el) => el.scrollIntoView());

expect(await page.screenshot()).toMatchImageSnapshot();
});

test('Carousel mobile with initialActiveItem=1', async () => {
const page = await openStoryPage({
id: 'components-carousels-carousel--default',
Expand Down
12 changes: 12 additions & 0 deletions src/__stories__/carousel-story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export default {
title: 'Components/Carousels/Carousel',
};

const mobilePageOffsetOptions = ['regular', 'large'] as const;

type Args = {
numItems: number;
itemsPerPageMobile: number;
Expand All @@ -26,6 +28,7 @@ type Args = {
withBullets: boolean;
free: boolean;
itemsToScroll: number;
mobilePageOffset: (typeof mobilePageOffsetOptions)[number];
autoplay: boolean;
loop: boolean;
initialActiveItem: number;
Expand All @@ -39,6 +42,7 @@ export const Default: StoryComponent<Args> = ({
itemsPerPageDesktop,
free,
itemsToScroll,
mobilePageOffset,
autoplay,
loop,
initialActiveItem,
Expand All @@ -65,6 +69,7 @@ export const Default: StoryComponent<Args> = ({
desktop: itemsPerPageDesktop,
}}
itemsToScroll={itemsToScroll}
mobilePageOffset={mobilePageOffset}
autoplay={autoplay ? {time: 5000, loop} : false}
onPageChange={setPageInfo}
items={Array.from({length: numItems}, (_, idx) => (
Expand Down Expand Up @@ -106,4 +111,11 @@ Default.args = {
loop: false,
itemsToScroll: 0,
initialActiveItem: 0,
mobilePageOffset: 'regular',
};
Default.argTypes = {
mobilePageOffset: {
options: mobilePageOffsetOptions,
control: {type: 'select'},
},
};
12 changes: 11 additions & 1 deletion src/carousel.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const arrowButtonBase = style([
]);

export const carouselContainer = sprinkles({
isolation: 'isolate',
// This minWidth value is a workaround to solve an issue when the page is rendered in a hidden webview
// in that case the window size is reported as 0 and the scroll snap is placed at the wrong slide
minWidth: 64,
Expand All @@ -99,16 +100,20 @@ const itemsPerPageMobile = createVar();
const itemsPerPageTablet = createVar();
const itemsPerPageDesktop = createVar();
const gap = createVar();
const mobilePageOffset = createVar();

export const vars = {
itemsPerPageMobile,
itemsPerPageTablet,
itemsPerPageDesktop,
gap,
mobilePageOffset,
};

export const DEFAULT_DESKTOP_GAP = 16;
const DEFAULT_MOBILE_GAP = 8;
const DEFAULT_MOBILE_PAGE_OFFSET = '16px';
const DEFAULT_TABLET_PAGE_OFFSET = '36px';

export const carousel = style([
hideScrollbar,
Expand All @@ -121,9 +126,15 @@ export const carousel = style([

vars: {
[gap]: String(DEFAULT_MOBILE_GAP),
[mobilePageOffset]: DEFAULT_MOBILE_PAGE_OFFSET,
},

'@media': {
[mq.tablet]: {
vars: {
[mobilePageOffset]: DEFAULT_TABLET_PAGE_OFFSET,
},
},
[mq.desktopOrBigger]: {
vars: {
[gap]: String(DEFAULT_DESKTOP_GAP),
Expand All @@ -134,7 +145,6 @@ export const carousel = style([
]);

const responsiveLayoutSideMargin = fallbackVar(responsiveLayoutVars.sideMargin, '0px');
const mobilePageOffset = fallbackVar(responsiveLayoutVars.sideMargin, '16px');

export const carouselWithScroll = style({
margin: `0 calc(${responsiveLayoutSideMargin} * -1)`,
Expand Down
14 changes: 13 additions & 1 deletion src/carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import * as styles from './carousel.css';
import {assignInlineVars} from '@vanilla-extract/dynamic';
import {sprinkles} from './sprinkles.css';
import {useDesktopContainerType} from './desktop-container-type-context';
import {VIVO_NEW_SKIN} from './skins/constants';

import type {DesktopContainerType} from './desktop-container-type-context';
import type {DataAttributes} from './utils/types';
Expand Down Expand Up @@ -167,6 +168,7 @@ type BaseCarouselProps = {
itemsPerPage?: ItemsPerPageProp;
/** scrolls one page by default */
itemsToScroll?: number;
mobilePageOffset?: 'regular' | 'large';
/** If true, scroll snap doesn't apply and the user has a free scroll */
free?: boolean;
gap?: number;
Expand All @@ -187,14 +189,15 @@ const BaseCarousel: React.FC<BaseCarouselProps> = ({
initialActiveItem,
itemsPerPage,
itemsToScroll,
mobilePageOffset,
gap,
free,
centered,
autoplay,
onPageChange,
dataAttributes,
}) => {
const {texts, platformOverrides} = useTheme();
const {texts, platformOverrides, skinName} = useTheme();

const desktopContainerType = useDesktopContainerType();
const itemsPerPageConfig = normalizeItemsPerPage(desktopContainerType || 'large', itemsPerPage);
Expand Down Expand Up @@ -372,6 +375,9 @@ const BaseCarousel: React.FC<BaseCarouselProps> = ({
);
}

const largePageOffset = '64px';
const vivoNewMobilePageOffset = '36px';

return (
<Stack space={24} dataAttributes={{'component-name': 'Carousel', ...dataAttributes}}>
<div className={styles.carouselContainer}>
Expand All @@ -395,6 +401,11 @@ const BaseCarousel: React.FC<BaseCarouselProps> = ({
[styles.vars.itemsPerPageDesktop]: String(itemsPerPageConfig.desktop),
[styles.vars.itemsPerPageTablet]: String(itemsPerPageConfig.tablet),
[styles.vars.itemsPerPageMobile]: String(itemsPerPageConfig.mobile),
...(mobilePageOffset === 'large'
? {[styles.vars.mobilePageOffset]: largePageOffset}
: skinName === VIVO_NEW_SKIN
? {[styles.vars.mobilePageOffset]: vivoNewMobilePageOffset}
: {}),
...(gap !== undefined ? {[styles.vars.gap]: String(gap)} : {}),
}),
scrollSnapType: free ? 'initial' : 'x mandatory',
Expand Down Expand Up @@ -441,6 +452,7 @@ type CarouselProps = {
itemsPerPage?: ItemsPerPageProp;
/** scrolls one page by default */
itemsToScroll?: number;
mobilePageOffset?: 'regular' | 'large';
/** If true, scroll snap doesn't apply and the user has a free scroll */
free?: boolean;
autoplay?: boolean | {time: number; loop?: boolean};
Expand Down
1 change: 1 addition & 0 deletions src/sprinkles.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const responsiveProperties = defineProperties({

const commonProperties = defineProperties({
properties: {
isolation: ['isolate'],
position: ['relative', 'absolute', 'fixed', 'static', 'sticky'],
display: ['none', 'flex', 'inline-flex', 'block', 'inline', 'inline-block'],
flexDirection: ['row', 'column'],
Expand Down

0 comments on commit 803506a

Please sign in to comment.