diff --git a/client/common/Button.jsx b/client/common/Button.jsx index bd22f44c..16b35c8d 100644 --- a/client/common/Button.jsx +++ b/client/common/Button.jsx @@ -4,6 +4,7 @@ import styled from 'styled-components'; import { Link } from 'react-router'; import { remSize, prop } from '../theme'; +import Icon, { ValidIconNameType } from './Icon'; // The '&&&' will increase the specificity of the // component's CSS so that it overrides the more @@ -28,6 +29,10 @@ const StyledButton = styled.button` &:hover:not(:disabled) { color: ${prop('buttonHoverColor')}; background-color: ${prop('buttonHoverColorBackground')}; + + svg * { + fill: ${prop('buttonHoverColor')}; + } } &:disabled { @@ -46,27 +51,36 @@ const StyledButton = styled.button` * A Button performs an primary action */ const Button = ({ - children, href, label, to, type, ...props + children, href, iconAfterName, iconBeforeName, label, to, type, ...props }) => { + const iconAfter = iconAfterName && ; + const iconBefore = iconBeforeName && ; + + const content = <>{iconBefore}{children}{iconAfter}; + if (href) { - return {children}; + return {content}; } if (to) { - return {children}; + return {content}; } - return {children}; + return {content}; }; Button.defaultProps = { disabled: false, + iconAfterName: null, + iconBeforeName: null, href: null, label: null, to: null, type: 'button', }; +Button.iconNames = Icon.names; + Button.propTypes = { /** * The visible part of the button, telling the user what @@ -77,6 +91,15 @@ Button.propTypes = { If the button can be activated or not */ disabled: PropTypes.bool, + /** + * Name of icon to place before child content + */ + iconAfterName: ValidIconNameType, + + /** + * Name of icon to place after child content + */ + iconBeforeName: ValidIconNameType, /** * Specifying an href will use an to link to the URL */ diff --git a/client/common/Button.stories.jsx b/client/common/Button.stories.jsx index 69ec920c..601d7fe9 100644 --- a/client/common/Button.stories.jsx +++ b/client/common/Button.stories.jsx @@ -35,12 +35,10 @@ export const ReactRouterLink = () => ( ); -export const InternalElementMargin = () => ( - +export const ButtonWithIconBefore = () => ( + +); + +export const ButtonWithIconAfter = () => ( + ); diff --git a/client/common/Icon.jsx b/client/common/Icon.jsx index 66863101..70638f90 100644 --- a/client/common/Icon.jsx +++ b/client/common/Icon.jsx @@ -22,6 +22,8 @@ const icons = { */ const names = lodash.mapValues(icons, (value, key) => key); +export const ValidIconNameType = PropTypes.oneOf(Object.keys(names)); + function Icon({ name, ...props }) { return ( @@ -29,10 +31,11 @@ function Icon({ name, ...props }) { ); } + Icon.names = names; Icon.propTypes = { - name: PropTypes.oneOf(Object.keys(names)).isRequired + name: ValidIconNameType.isRequired }; export default Icon; diff --git a/client/images/google.svg b/client/images/google.svg index 542fea64..005c874f 100644 --- a/client/images/google.svg +++ b/client/images/google.svg @@ -1,47 +1,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + diff --git a/client/modules/User/components/APIKeyForm.jsx b/client/modules/User/components/APIKeyForm.jsx index acef4e38..39ebfd35 100644 --- a/client/modules/User/components/APIKeyForm.jsx +++ b/client/modules/User/components/APIKeyForm.jsx @@ -1,9 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; -import InlineSVG from 'react-inlinesvg'; import Button from '../../../common/Button'; -import Icon from '../../../common/Icon'; import CopyableInput from '../../IDE/components/CopyableInput'; import APIKeyList from './APIKeyList'; @@ -82,13 +80,12 @@ class APIKeyForm extends React.Component { value={this.state.keyLabel} /> diff --git a/client/modules/User/components/Collection.jsx b/client/modules/User/components/Collection.jsx index 620901a7..7e554bf6 100644 --- a/client/modules/User/components/Collection.jsx +++ b/client/modules/User/components/Collection.jsx @@ -9,7 +9,6 @@ import { bindActionCreators } from 'redux'; import classNames from 'classnames'; import Button from '../../../common/Button'; -import Icon from '../../../common/Icon'; import * as ProjectActions from '../../IDE/actions/project'; import * as ProjectsActions from '../../IDE/actions/projects'; import * as CollectionsActions from '../../IDE/actions/collections'; @@ -54,9 +53,9 @@ const ShareURL = ({ value }) => { return (
{ showURL &&
diff --git a/client/modules/User/components/SocialAuthButton.jsx b/client/modules/User/components/SocialAuthButton.jsx index c3c5dd74..c0539eb6 100644 --- a/client/modules/User/components/SocialAuthButton.jsx +++ b/client/modules/User/components/SocialAuthButton.jsx @@ -2,10 +2,9 @@ import PropTypes from 'prop-types'; import React from 'react'; import styled from 'styled-components'; -import { remSize, prop } from '../../../theme'; +import { remSize } from '../../../theme'; import Button from '../../../common/Button'; -import Icon from '../../../common/Icon'; const authUrls = { github: '/auth-github', @@ -24,24 +23,15 @@ const services = { const StyledButton = styled(Button)` width: ${remSize(300)}; - - > * + * { - margin-left: ${remSize(10)}; - } -`; - -const StyledIcon = styled(Icon)` - width: ${remSize(32)}; - height: ${remSize(32)}; `; function SocialAuthButton({ service }) { return ( - - {labels[service]} + {labels[service]} ); }