Skip to content
Snippets Groups Projects
Commit f3d1a915 authored by Chris Garrity's avatar Chris Garrity
Browse files

Add play buttons to sound library tiles for touch

Add prop to library items to show a play button. If a play button is present the ‘play on hover’ only applies over the icon rather than the full tile.
parent a72a420b
No related branches found
No related tags found
No related merge requests found
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
......@@ -7,6 +7,7 @@
align-items: center;
justify-content: flex-start;
flex-basis: 160px;
position: relative;
height: 160px;
max-width: 160px;
margin: $space;
......@@ -200,3 +201,45 @@
[dir="rtl"] .coming-soon-text {
transform: translate(calc(-2 * $space), calc(2 * $space));
}
.play-button {
display: flex;
align-items: center;
justify-content: center;
overflow: hidden; /* Mask the icon animation */
width: 1.5rem;
height: 1.5rem;
background-color: $motion-primary;
color: $ui-white;
border-radius: 50%;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
user-select: none;
cursor: pointer;
transition: all 0.15s ease-out;
}
.play-button {
position: absolute;
position: absolute;
top: 0.125rem;
z-index: auto;
}
.play-button:focus {
outline: none;
}
.play-icon {
width: 50%;
}
[dir="ltr"] .play-button {
right: 0.125rem;
padding-left: .125rem;
}
[dir="rtl"] .play-button {
left: 0.125rem;
padding-right: .125rem;
}
......@@ -8,6 +8,11 @@ import classNames from 'classnames';
import bluetoothIconURL from './bluetooth.svg';
import internetConnectionIconURL from './internet-connection.svg';
import playIcon from './icon--play.svg';
const preventClick = e => {
e.stopPropagation();
};
/* eslint-disable react/prefer-stateless-function */
class LibraryItemComponent extends React.PureComponent {
......@@ -115,12 +120,16 @@ class LibraryItemComponent extends React.PureComponent {
onClick={this.props.onClick}
onFocus={this.props.onFocus}
onKeyPress={this.props.onKeyPress}
onMouseEnter={this.props.onMouseEnter}
onMouseLeave={this.props.onMouseLeave}
onMouseEnter={this.props.showPlayButton ? null : this.props.onMouseEnter}
onMouseLeave={this.props.showPlayButton ? null : this.props.onMouseLeave}
>
{/* Layers of wrapping is to prevent layout thrashing on animation */}
<Box className={styles.libraryItemImageContainerWrapper}>
<Box className={styles.libraryItemImageContainer}>
<Box
className={styles.libraryItemImageContainer}
onMouseEnter={this.props.showPlayButton ? this.props.onMouseEnter : null}
onMouseLeave={this.props.showPlayButton ? this.props.onMouseLeave : null}
>
<img
className={styles.libraryItemImage}
src={this.props.iconURL}
......@@ -128,6 +137,22 @@ class LibraryItemComponent extends React.PureComponent {
</Box>
</Box>
<span className={styles.libraryItemName}>{this.props.name}</span>
{this.props.showPlayButton ? (
<div
aria-label="Play"
className={styles.playButton}
role="button"
tabIndex="0"
onClick={preventClick}
onMouseDown={this.props.onPlay}
>
<img
className={styles.playIcon}
draggable={false}
src={playIcon}
/>
</div>
) : null}
</Box>
);
}
......@@ -158,11 +183,14 @@ LibraryItemComponent.propTypes = {
onFocus: PropTypes.func.isRequired,
onKeyPress: PropTypes.func.isRequired,
onMouseEnter: PropTypes.func.isRequired,
onMouseLeave: PropTypes.func.isRequired
onMouseLeave: PropTypes.func.isRequired,
onPlay: PropTypes.func.isRequired,
showPlayButton: PropTypes.bool
};
LibraryItemComponent.defaultProps = {
disabled: false
disabled: false,
showPlayButton: false
};
export default LibraryItemComponent;
......@@ -187,6 +187,7 @@ class LibraryComponent extends React.Component {
internetConnectionRequired={dataItem.internetConnectionRequired}
key={typeof dataItem.name === 'string' ? dataItem.name : dataItem.rawURL}
name={dataItem.name}
showPlayButton={this.props.showPlayButton}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
onSelect={this.handleSelect}
......@@ -227,12 +228,14 @@ LibraryComponent.propTypes = {
onItemMouseLeave: PropTypes.func,
onItemSelected: PropTypes.func,
onRequestClose: PropTypes.func,
showPlayButton: PropTypes.bool,
tags: PropTypes.arrayOf(PropTypes.shape(TagButton.propTypes)),
title: PropTypes.string.isRequired
};
LibraryComponent.defaultProps = {
filterable: true
filterable: true,
showPlayButton: false
};
export default injectIntl(LibraryComponent);
......@@ -15,6 +15,7 @@ class LibraryItem extends React.PureComponent {
'handleKeyPress',
'handleMouseEnter',
'handleMouseLeave',
'handlePlay',
'rotateIcon',
'startRotatingIcons',
'stopRotatingIcons'
......@@ -62,6 +63,10 @@ class LibraryItem extends React.PureComponent {
}, this.stopRotatingIcons);
}
}
handlePlay (e) {
e.stopPropagation(); // To prevent from bubbling back to handleClick
this.props.onMouseEnter(this.props.id);
}
startRotatingIcons () {
this.rotateIcon();
this.intervalId = setInterval(this.rotateIcon, 300);
......@@ -105,12 +110,14 @@ class LibraryItem extends React.PureComponent {
insetIconURL={this.props.insetIconURL}
internetConnectionRequired={this.props.internetConnectionRequired}
name={this.props.name}
showPlayButton={this.props.showPlayButton}
onBlur={this.handleBlur}
onClick={this.handleClick}
onFocus={this.handleFocus}
onKeyPress={this.handleKeyPress}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
onPlay={this.handlePlay}
/>
);
}
......@@ -143,7 +150,8 @@ LibraryItem.propTypes = {
]),
onMouseEnter: PropTypes.func.isRequired,
onMouseLeave: PropTypes.func.isRequired,
onSelect: PropTypes.func.isRequired
onSelect: PropTypes.func.isRequired,
showPlayButton: PropTypes.bool
};
export default injectIntl(LibraryItem);
......@@ -141,6 +141,7 @@ class SoundLibrary extends React.PureComponent {
return (
<LibraryComponent
showPlayButton
data={soundLibraryThumbnailData}
id="soundLibrary"
tags={soundTags}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment