Skip to content

Commit a2b9e22

Browse files
authored
MediaCarousel functionality improvements (#64)
* Fix MediaCarousel to correctly show images of varying heights/widths * Allow for thumbnails to be on any side of the carousel * PR cleanup * Version bump
1 parent cf9a131 commit a2b9e22

File tree

7 files changed

+267
-41
lines changed

7 files changed

+267
-41
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-storefront",
3-
"version": "7.10.0",
3+
"version": "7.11.0",
44
"description": "Build and deploy e-commerce progressive web apps (PWAs) in record time.",
55
"module": "./index.js",
66
"license": "Apache-2.0",

src/carousel/Carousel.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const styles = theme => ({
1717
flexDirection: 'column',
1818
alignItems: 'stretch',
1919
position: 'relative',
20+
flexBasis: '100%',
2021
'& img': {
2122
display: 'block',
2223
},

src/carousel/CarouselThumbnails.js

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import React from 'react'
33
import clsx from 'clsx'
44
import Tabs from '@material-ui/core/Tabs'
55
import Tab from '@material-ui/core/Tab'
6-
import { makeStyles } from '@material-ui/core/styles'
6+
import { makeStyles, useTheme } from '@material-ui/core/styles'
7+
import useMediaQuery from '@material-ui/core/useMediaQuery'
78
import Image from '../Image'
89

910
export const styles = theme => ({
@@ -35,7 +36,47 @@ export const styles = theme => ({
3536
/**
3637
* Styles applied to the root element of the Tabs element
3738
*/
38-
tabsRoot: {
39+
tabsRoot: {},
40+
/**
41+
* Styles applied the to the root element of the Tabs element when `thumbnailPosition` is `left` or `right`.
42+
*/
43+
tabsVertical: {
44+
[theme.breakpoints.up('sm')]: {
45+
flexDirection: 'column',
46+
},
47+
},
48+
/**
49+
* Styles applied to the root element of the Tabs element when `thumbnailPosition` is `left`.
50+
*/
51+
tabsRootLeft: {
52+
[theme.breakpoints.down('xs')]: {
53+
marginTop: theme.spacing(2),
54+
},
55+
[theme.breakpoints.up('sm')]: {
56+
marginRight: theme.spacing(2),
57+
},
58+
},
59+
/**
60+
* Styles applied to the root element of the Tabs element when `thumbnailPosition` is `right`.
61+
*/
62+
tabsRootRight: {
63+
[theme.breakpoints.down('xs')]: {
64+
marginTop: theme.spacing(2),
65+
},
66+
[theme.breakpoints.up('sm')]: {
67+
marginLeft: theme.spacing(2),
68+
},
69+
},
70+
/**
71+
* Styles applied to the root element of the Tabs element when `thumbnailPosition` is `top`.
72+
*/
73+
tabsRootTop: {
74+
marginBottom: theme.spacing(2),
75+
},
76+
/**
77+
* Styles applied to the root element of the Tabs element when `thumbnailPosition` is `bottom`.
78+
*/
79+
tabsRootBottom: {
3980
marginTop: theme.spacing(2),
4081
},
4182
/**
@@ -79,17 +120,34 @@ const useStyles = makeStyles(styles, { name: 'RSFCarouselThumbnails' })
79120
* be clicked to switch to the given slide. Internally, `CarouselThumbnails` uses MaterialUI's
80121
* [`Tabs`](https://material-ui.com/api/tabs) component to indicate which slide is selected
81122
*/
82-
function CarouselThumbnails({ thumbnails, selected, setSelected, classes, className }) {
123+
function CarouselThumbnails({
124+
thumbnails,
125+
selected,
126+
setSelected,
127+
classes,
128+
className,
129+
thumbnailPosition,
130+
}) {
83131
const styles = useStyles({ classes })
132+
const theme = useTheme()
133+
const isSmall = useMediaQuery(theme.breakpoints.down('xs'))
134+
const isVertical = !isSmall && ['left', 'right'].includes(thumbnailPosition)
84135

85136
return (
86137
<div className={clsx(className, styles.thumbs)}>
87138
<Tabs
88139
value={selected}
89140
variant="scrollable"
90141
onChange={(_, index) => setSelected(index)}
142+
orientation={isVertical ? 'vertical' : 'horizontal'}
91143
classes={{
92-
root: styles.tabsRoot,
144+
root: clsx(styles.tabsRoot, {
145+
[styles.tabsVertical]: isVertical,
146+
[styles.tabsRootLeft]: thumbnailPosition === 'left',
147+
[styles.tabsRootRight]: thumbnailPosition === 'right',
148+
[styles.tabsRootTop]: thumbnailPosition === 'top',
149+
[styles.tabsRootBottom]: thumbnailPosition === 'bottom',
150+
}),
93151
indicator: styles.tabsIndicator,
94152
}}
95153
>
@@ -134,14 +192,19 @@ CarouselThumbnails.propTypes = {
134192
setSelected: PropTypes.func,
135193

136194
/**
137-
* Array of objects containing the data for an image to be used for each thumbnail
195+
* Array of objects containing the data for an image to be used for each thumbnail.
138196
*/
139197
thumbnails: PropTypes.arrayOf(
140198
PropTypes.shape({
141199
src: PropTypes.string,
142200
alt: PropTypes.string,
143201
}),
144202
),
203+
204+
/**
205+
* Position of the thumbnails, relative to the main carousel image.
206+
*/
207+
thumbnailPosition: PropTypes.oneOf(['bottom', 'top', 'left', 'right']),
145208
}
146209

147210
export default React.memo(CarouselThumbnails)

src/carousel/Media.js

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,65 @@ import PropTypes from 'prop-types'
22
import React from 'react'
33
import Image from '../Image'
44
import ReactImageMagnify from 'react-image-magnify'
5+
import clsx from 'clsx'
6+
import { makeStyles } from '@material-ui/core/styles'
7+
8+
const useStyles = makeStyles(theme => ({
9+
rimRoot: {
10+
height: '100% !important',
11+
width: '100% !important',
12+
},
13+
rimSmallImage: {
14+
height: '100% !important',
15+
width: '100% !important',
16+
},
17+
}))
518

619
/**
720
* An element that determines the proper tag to use for a media node within a
821
* [`Carousel`](/apiReference/carousel%f2Carousel).
922
*/
10-
export default function Media({ magnifyProps, imageProps, src, alt, magnify, type = 'image' }) {
23+
export default function Media({
24+
magnifyProps,
25+
imageProps,
26+
src,
27+
alt,
28+
magnify,
29+
poster,
30+
type = 'image',
31+
}) {
32+
const classes = useStyles()
33+
34+
const adjustMagnifyProps = () => {
35+
const appliedMagnifyProps = { ...(magnifyProps || {}) }
36+
appliedMagnifyProps.style = {
37+
...((magnifyProps && magnifyProps.style) || {}),
38+
display: 'flex',
39+
objectFit: 'contain',
40+
}
41+
appliedMagnifyProps.imageStyle = {
42+
...((magnifyProps && magnifyProps.imageStyle) || {}),
43+
objectFit: 'contain',
44+
}
45+
appliedMagnifyProps.className = clsx(magnifyProps && magnifyProps.className, classes.rimRoot)
46+
appliedMagnifyProps.imageClassName = clsx(
47+
magnifyProps && magnifyProps.imageClassName,
48+
classes.rimSmallImage,
49+
)
50+
appliedMagnifyProps.enlargedImageStyle = {
51+
...((magnifyProps && magnifyProps.enlargedImageStyle) || {}),
52+
height: '100%',
53+
}
54+
return appliedMagnifyProps
55+
}
56+
1157
if (type === 'video') {
12-
return <video src={src} alt={alt} />
58+
return <video src={src} alt={alt} poster={poster} />
1359
} else if (magnify) {
1460
return (
1561
<ReactImageMagnify
1662
enlargedImagePosition="over"
17-
{...magnifyProps}
63+
{...adjustMagnifyProps()}
1864
smallImage={{
1965
src: src,
2066
alt: alt,
@@ -36,7 +82,7 @@ Media.propTypes = {
3682

3783
/**
3884
* Props passed to the [`ReactImageMagnify`](https://github.com/ethanselzer/react-image-magnify#usage)
39-
* element for an `'image'` type when [`magnify`](#prop-magnify) is `true`.
85+
* element for an `'image'` type when [`magnify`](#prop-magnify) is defined.
4086
*/
4187
magnifyProps: PropTypes.object,
4288

@@ -46,15 +92,20 @@ Media.propTypes = {
4692
imageProps: PropTypes.object,
4793

4894
/**
49-
* Used as the `alt` tag for an `'image'` type.
95+
* Used as the `alt` attribute for the `<img>` or `<video>`.
5096
*/
5197
alt: PropTypes.string,
5298

5399
/**
54-
* Used as the `src` tag for an `'image'` type.
100+
* Used as the `src` attribute for the `<img>` or `<video>`.
55101
*/
56102
src: PropTypes.string,
57103

104+
/**
105+
* Used as the `poster` attribute for a `<video>`.
106+
*/
107+
poster: PropTypes.string,
108+
58109
/**
59110
* An object to pass to pass to `ReactImageMagnify` containing the data for the magnified image.
60111
* If `false`, the media is not able to be magnified.

0 commit comments

Comments
 (0)