Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PB] Row component #1753

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ const testVenia = inPackage => ({
// @magento namespaced packages like Peregrine and Venia UI as well, when
// it's testing Venia. That way, changes in sibling packages don't require a
// full compile.
transformIgnorePatterns: ['node_modules/(?!@magento/)']
transformIgnorePatterns: [
'node_modules/(?!@magento|jarallax|video-worker/)'
]
});

const configureProject = (dir, displayName, cb) =>
Expand Down
1 change: 0 additions & 1 deletion packages/venia-concept/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@
"react-apollo": "2.5.5",
"react-dom": "~16.9.0",
"react-feather": "~2.0.3",
"react-parallax": "~2.2.0",
"react-redux": "~7.1.1",
"react-router-dom": "~5.0.0",
"react-tabs": "~3.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders a Row component 1`] = `
exports[`render row with all props configured 1`] = `
<div
className="test-class"
style={
Object {
"backgroundAttachment": "fixed",
"backgroundColor": "red",
"backgroundImage": "url(desktop.jpg)",
"backgroundPosition": "center center",
"backgroundRepeat": "repeat",
"backgroundSize": "contain",
"border": "solid",
"borderColor": "red",
"borderRadius": "15px",
"borderWidth": "10px",
"display": "flex",
"flexDirection": "column",
"justifyContent": "center",
"marginBottom": "10px",
"marginLeft": "10px",
"marginRight": "10px",
"marginTop": "10px",
"minHeight": "200px",
"paddingBottom": "10px",
"paddingLeft": "10px",
"paddingRight": "10px",
"paddingTop": "10px",
"textAlign": "right",
}
}
>
<div
className="contained"
/>
</div>
`;

exports[`render row with mobile image displayed and parallax enabled 1`] = `
<div
className="contained"
style={
Object {
"backgroundAttachment": undefined,
"backgroundColor": undefined,
"backgroundImage": null,
"backgroundImage": "url(mobile.jpg)",
"backgroundPosition": undefined,
"backgroundRepeat": "no-repeat",
"backgroundSize": undefined,
Expand All @@ -30,62 +67,32 @@ exports[`renders a Row component 1`] = `
/>
`;

exports[`renders a Row component with all props configured 1`] = `
exports[`render row with no props 1`] = `
<div
className="react-parallax test-class"
className="contained"
style={
Object {
"backgroundColor": "red",
"border": "solid",
"borderColor": "red",
"borderRadius": "15px",
"borderWidth": "10px",
"display": "flex",
"flexDirection": "column",
"justifyContent": "center",
"marginBottom": "10px",
"marginLeft": "10px",
"marginRight": "10px",
"marginTop": "10px",
"minHeight": "200px",
"overflow": "hidden",
"paddingBottom": "10px",
"paddingLeft": "10px",
"paddingRight": "10px",
"paddingTop": "10px",
"position": "relative",
"textAlign": "right",
"backgroundAttachment": undefined,
"backgroundColor": undefined,
"backgroundImage": null,
"backgroundPosition": undefined,
"backgroundRepeat": "no-repeat",
"backgroundSize": undefined,
"border": undefined,
"borderColor": undefined,
"borderRadius": undefined,
"borderWidth": undefined,
"marginBottom": undefined,
"marginLeft": undefined,
"marginRight": undefined,
"marginTop": undefined,
"minHeight": undefined,
"paddingBottom": undefined,
"paddingLeft": undefined,
"paddingRight": undefined,
"paddingTop": undefined,
"textAlign": undefined,
}
}
>
<img
alt=""
className="react-parallax-bgimage"
src="desktop.jpg"
style={
Object {
"MozBackfaceVisibility": "hidden",
"MsBackfaceVisibility": "hidden",
"WebkitBackfaceVisibility": "hidden",
"WebkitTransform": "translate3d(-50%, 0, 0)",
"WebkitTransformStyle": "preserve-3d",
"left": "50%",
"position": "absolute",
"transform": "translate3d(-50%, 0, 0)",
}
}
/>
<div
className="react-parallax-content"
style={
Object {
"position": "relative",
}
}
>
<div
className="contained"
/>
</div>
</div>
/>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,51 @@ import React from 'react';
import { createTestInstance } from '@magento/peregrine';
import Row from '../row';

jest.mock('jarallax', () => {
return {
jarallax: jest.fn()
};
});
import { jarallax } from 'jarallax';
const mockJarallax = jarallax.mockImplementation(() => {});

jest.mock('../../../../../../classify');

test('renders a Row component', () => {
test('render row with no props', () => {
const component = createTestInstance(<Row />);

expect(component.toJSON()).toMatchSnapshot();
});

test('renders a Row component with all props configured', () => {
test('render row with parallax initializes Jarallax', () => {
const rowProps = {
enableParallax: true,
parallaxSpeed: 0.75
};
createTestInstance(<Row {...rowProps} />);

expect(mockJarallax).toHaveBeenCalledWith(null, { speed: 0.75 });
});

test('row unmount causes Jarallax to be destroyed', () => {
const rowProps = {
enableParallax: true,
parallaxSpeed: 0.75
};
const component = createTestInstance(<Row {...rowProps} />, {
createNodeMock: () => {
return true;
}
});
component.unmount();

expect(mockJarallax.mock.calls).toEqual([
[true, { speed: 0.75 }],
[true, 'destroy']
]);
});

test('render row with all props configured', () => {
const rowProps = {
appearance: 'full-width',
verticalAlignment: 'middle',
Expand All @@ -22,7 +58,7 @@ test('renders a Row component with all props configured', () => {
backgroundPosition: 'center center',
backgroundAttachment: 'fixed',
backgroundRepeat: true,
enableParallax: true,
enableParallax: false,
parallaxSpeed: 0.5,
textAlign: 'right',
border: 'solid',
Expand All @@ -43,3 +79,27 @@ test('renders a Row component with all props configured', () => {

expect(component.toJSON()).toMatchSnapshot();
});

test('render row with mobile image displayed and parallax enabled', () => {
const rowProps = {
mobileImage: 'mobile.jpg',
enableParallax: true
};

window.matchMedia = jest.fn().mockImplementation(query => {
return {
matches: true,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn()
};
});

const component = createTestInstance(<Row {...rowProps} />);

expect(component.toJSON()).toMatchSnapshot();
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import React from 'react';
import React, { useEffect, useRef } from 'react';
import defaultClasses from './row.css';
import { verticalAlignmentToFlex } from '../../utils';
import { Parallax } from 'react-parallax';
import { mergeClasses } from '../../../../../classify';
import { arrayOf, oneOf, shape, bool, string, number } from 'prop-types';
import { jarallax } from 'jarallax';

/**
* Page Builder Row component.
*
* This component is part of the Page Builder / PWA integration. It can be consumed without Page Builder.
*
* @typedef Row
* @kind functional component
*
* @param {props} props React component props
*
* @returns {React.Element} A React component that displays a Row which contains content.
*/
const Row = props => {
const backgroundElement = useRef(null);
const classes = mergeClasses(defaultClasses, props.classes);
const {
appearance = 'contained',
Expand Down Expand Up @@ -59,19 +72,14 @@ const Row = props => {
paddingTop,
paddingRight,
paddingBottom,
paddingLeft
paddingLeft,
backgroundImage: image ? `url(${image})` : null,
backgroundSize,
backgroundPosition,
backgroundAttachment,
backgroundRepeat: backgroundRepeat ? 'repeat' : 'no-repeat'
};

if (!enableParallax) {
dynamicStyles.backgroundImage = image ? `url(${image})` : null;
dynamicStyles.backgroundSize = backgroundSize;
dynamicStyles.backgroundPosition = backgroundPosition;
dynamicStyles.backgroundAttachment = backgroundAttachment;
dynamicStyles.backgroundRepeat = backgroundRepeat
? 'repeat'
: 'no-repeat';
}

if (verticalAlignment) {
dynamicStyles.display = 'flex';
dynamicStyles.justifyContent = verticalAlignmentToFlex(
Expand All @@ -90,26 +98,63 @@ const Row = props => {
children = <div className={classes.contained}>{children}</div>;
}

if (enableParallax) {
return (
<Parallax
strength={parallaxSpeed * 200}
bgImage={image}
style={dynamicStyles}
className={cssClasses.join(' ')}
>
{children}
</Parallax>
);
}
useEffect(() => {
let parallaxElement;
if (enableParallax) {
parallaxElement = backgroundElement.current;
jarallax(parallaxElement, { speed: parallaxSpeed || 0.5 });
davemacaulay marked this conversation as resolved.
Show resolved Hide resolved
}

return () => {
if (enableParallax && parallaxElement) {
jarallax(parallaxElement, 'destroy');
}
};
}, []);

return (
<div style={dynamicStyles} className={cssClasses.join(' ')}>
<div
ref={backgroundElement}
style={dynamicStyles}
className={cssClasses.join(' ')}
>
{children}
</div>
);
};

/**
* Props for {@link Row}
*
* @typedef props
*
* @property {Object} classes An object containing the class names for the Video
davemacaulay marked this conversation as resolved.
Show resolved Hide resolved
* @property {String} classes.contained CSS classes for the contained appearance element
* @property {String} minHeight CSS minimum height property
* @property {String} backgroundColor CSS background-color property
* @property {String} desktopImage Background image URL to be displayed on desktop devices
* @property {String} mobileImage Background image URL to be displayed on mobile devices
* @property {String} backgroundSize CSS background-size property
* @property {String} backgroundPosition CSS background-position property
* @property {String} backgroundAttachment CSS background-attachment property
* @property {Boolean} backgroundRepeat CSS background-repeat property
* @property {Boolean} enableParallax Enable parallax on this row
* @property {Number} parallaxSpeed The speed which Parallax should scroll, from -1.0 to 2.0
* @property {String} textAlign Alignment of the video within the parent container
davemacaulay marked this conversation as resolved.
Show resolved Hide resolved
* @property {String} border CSS border property
* @property {String} borderColor CSS border color property
* @property {String} borderWidth CSS border width property
* @property {String} borderRadius CSS border radius property
* @property {String} marginTop CSS margin top property
* @property {String} marginRight CSS margin right property
* @property {String} marginBottom CSS margin bottom property
* @property {String} marginLeft CSS margin left property
* @property {String} paddingTop CSS padding top property
* @property {String} paddingRight CSS padding right property
* @property {String} paddingBottom CSS padding bottom property
* @property {String} paddingLeft CSS padding left property
* @property {Array} cssClasses List of CSS classes to be applied to the component
*/
Row.propTypes = {
classes: shape({
contained: string
Expand Down
1 change: 1 addition & 0 deletions packages/venia-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"homepage": "https://github.com/magento-research/pwa-studio/tree/master/packages/venia-ui#readme",
"dependencies": {
"informed": "~2.1.13",
"jarallax": "~1.11.1",
"lodash.over": "~4.7.0",
"memoize-one": "~5.0.0",
"prop-types": "~15.7.2",
Expand Down
Loading