Skip to content
Snippets Groups Projects
Commit bbf64191 authored by Paul Kaplan's avatar Paul Kaplan
Browse files

Extract IconButton component and reuse for the sprite and backdrop buttons

parent cecccee8
No related branches found
No related tags found
No related merge requests found
......@@ -4,6 +4,7 @@ import React from 'react';
import SpriteSelectorItem from '../../containers/sprite-selector-item.jsx';
import Box from '../box/box.jsx';
import IconButton from '../icon-button/icon-button.jsx';
import styles from './selector.css';
const Selector = props => {
......@@ -34,19 +35,12 @@ const Selector = props => {
</Box>
<Box className={styles.newButtons}>
{buttons.map(({message, img, onClick}, index) => (
<Box
className={styles.newButton}
<IconButton
img={img}
key={index}
title={message}
onClick={onClick}
>
<img
className={styles.newButtonIcon}
src={img}
/>
<Box className={styles.newButtonLabel}>
{message}
</Box>
</Box>
/>
))}
</Box>
</Box>
......
@import "../../css/colors.css";
.container {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
transition: 0.2s;
font-size: 0.75rem;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.container:hover {
transform: scale(1.1);
}
.container + .container {
margin-top: 1.25rem;
}
.title {
margin-top: 0.5rem;
color: $motion-primary;
}
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
import Box from '../box/box.jsx';
import styles from './icon-button.css';
const IconButton = ({
img,
className,
title,
onClick
}) => (
<Box
className={classNames(styles.container, className)}
onClick={onClick}
>
<img
className={styles.icon}
src={img}
/>
<Box className={styles.title}>
{title}
</Box>
</Box>
);
IconButton.propTypes = {
className: PropTypes.string,
img: PropTypes.string,
onClick: PropTypes.func.isRequired,
title: PropTypes.node.isRequired
};
export default IconButton;
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
......@@ -3,51 +3,32 @@
.target-pane {
/* Makes columns for the sprite library selector + and the stage selector */
display: flex;
flex-direction: row;
flex-direction: row;
height: 100%;
}
.stage-selector-wrapper {
flex-basis: 72px;
flex-shrink: 0;
margin-left: calc($space / 2);
margin-left: calc($space / 2);
}
.add-button-wrapper {
display: flex;
position: absolute;
justify-content: center;
align-items: center;
z-index: 1;
bottom: 1rem;
width: 2.25rem !important;
height: 2.25rem !important;
background-color: #4c97ff;
bottom: 0.5rem;
border: 0;
border-radius: 50% !important;
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
transition: all 0.15s ease-out; /* @todo: standardize with var */
transition: all 0.15s ease-out; /* @todo: standardize with var */
cursor: pointer;
user-select: none;
}
.add-button-wrapper:hover {
transform: scale(1.1, 1.1);
box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.1);
}
.add-button-wrapper:focus {
outline: none;
border: 0;
}
.add-button {
height: 0.8rem;
margin: auto;
font-size: 0.55rem;
font-weight: bold;
}
/* @todo: This is hacky. Better: move buttons in their corresponding panes, and set values relatively */
.add-button-wrapper--sprite { right: 7rem; }
.add-button-wrapper--stage { right: 1.6rem; }
.add-button-wrapper--costume { right: 1.6rem; }
.add-button-wrapper--stage { right: 0.8rem; }
......@@ -11,9 +11,12 @@ import SoundLibrary from '../../containers/sound-library.jsx';
import SpriteLibrary from '../../containers/sprite-library.jsx';
import SpriteSelectorComponent from '../sprite-selector/sprite-selector.jsx';
import StageSelector from '../../containers/stage-selector.jsx';
import IconButton from '../icon-button/icon-button.jsx';
import styles from './target-pane.css';
import addIcon from './icon--add.svg';
import spriteIcon from './icon--sprite.svg';
import backdropIcon from './icon--backdrop.svg';
/*
* Pane that contains the sprite selector, sprite info, stage selector,
......@@ -75,29 +78,22 @@ const TargetPane = ({
onSelect={onSelectSprite}
/>}
<Box>
<button
className={classNames(styles.addButtonWrapper, styles.addButtonWrapperSprite)}
title="Add sprite"
onClick={onNewSpriteClick}
>
<img
<Box className={classNames(styles.addButtonWrapper, styles.addButtonWrapperSprite)}>
<IconButton
className={styles.addButton}
src={addIcon}
img={spriteIcon}
title="Add Sprite"
onClick={onNewSpriteClick}
/>
</button>
<button
className={classNames(styles.addButtonWrapper, styles.addButtonWrapperStage)}
title="Add backdrop"
onClick={onNewBackdropClick}
>
<img
</Box>
<Box className={classNames(styles.addButtonWrapper, styles.addButtonWrapperStage)}>
<IconButton
className={styles.addButton}
src={addIcon}
img={backdropIcon}
title="Add Backdrop"
onClick={onNewBackdropClick}
/>
</button>
</Box>
<SpriteLibrary
visible={spriteLibraryVisible}
vm={vm}
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`IconButtonComponent matches snapshot 1`] = `
<div
className="custom-class-name"
onClick={[Function]}
style={
Object {
"alignContent": undefined,
"alignItems": undefined,
"alignSelf": undefined,
"flexBasis": undefined,
"flexDirection": undefined,
"flexGrow": undefined,
"flexShrink": undefined,
"flexWrap": undefined,
"height": undefined,
"justifyContent": undefined,
"width": undefined,
}
}
>
<img
className={undefined}
src="imgSrc"
/>
<div
className=""
style={
Object {
"alignContent": undefined,
"alignItems": undefined,
"alignSelf": undefined,
"flexBasis": undefined,
"flexDirection": undefined,
"flexGrow": undefined,
"flexShrink": undefined,
"flexWrap": undefined,
"height": undefined,
"justifyContent": undefined,
"width": undefined,
}
}
>
<div>
Text
</div>
</div>
</div>
`;
/* eslint-env jest */
import React from 'react'; // eslint-disable-line no-unused-vars
import {shallow} from 'enzyme';
import IconButton from '../../../src/components/icon-button/icon-button'; // eslint-disable-line no-unused-vars
import renderer from 'react-test-renderer';
describe('IconButtonComponent', () => {
test('matches snapshot', () => {
const onClick = jest.fn();
const title = <div>Text</div>;
const imgSrc = 'imgSrc';
const className = 'custom-class-name';
const component = renderer.create(
<IconButton
className={className}
img={imgSrc}
title={title}
onClick={onClick}
/>
);
expect(component.toJSON()).toMatchSnapshot();
});
test('triggers callback when clicked', () => {
const onClick = jest.fn();
const title = <div>Text</div>;
const imgSrc = 'imgSrc';
const componentShallowWrapper = shallow(
<IconButton
img={imgSrc}
title={title}
onClick={onClick}
/>
);
componentShallowWrapper.simulate('click');
expect(onClick).toHaveBeenCalled();
});
});
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