diff --git a/client/common/Button.jsx b/client/common/Button.jsx new file mode 100644 index 00000000..3791e950 --- /dev/null +++ b/client/common/Button.jsx @@ -0,0 +1,93 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import styled from 'styled-components'; +import { Link } from 'react-router'; + +import { remSize, prop } from '../theme'; + +// The '&&&' will increase the specificity of the +// component's CSS so that it overrides the more +// general global styles +const StyledButton = styled.button` + &&& { + display: flex; + justify-content: center; + align-items: center; + + width: max-content; + text-decoration: none; + + background-color: ${prop('buttonColorBackground')}; + color: ${prop('buttonColor')}; + cursor: pointer; + border: 2px solid ${prop('buttonBorderColor')}; + border-radius: 2px; + padding: ${remSize(8)} ${remSize(25)}; + line-height: 1; + + &:hover:not(:disabled) { + color: ${prop('buttonHoverColor')}; + background-color: ${prop('buttonHoverColorBackground')}; + } + + &:disabled { + color: ${prop('buttonDisabledColor')}; + background-color: ${prop('buttonDisabledColorBackground')}; + cursor: not-allowed; + } + } +`; + +/** + * A Button performs an primary action + */ +const Button = ({ + children, href, label, to, type, ...props +}) => { + if (href) { + return {children}; + } + + if (to) { + return {children}; + } + + return {children}; +}; + +Button.defaultProps = { + disabled: false, + href: null, + to: null, + type: 'button', +}; + +Button.propTypes = { + /** + * The visible part of the button, telling the user what + * the action is + */ + children: PropTypes.element.isRequired, + /** + If the button can be activated or not + */ + disabled: PropTypes.bool, + /** + * Specifying an href will use an to link to the URL + */ + href: PropTypes.string, + /* + * An ARIA Label used for accessibility + */ + label: PropTypes.string.isRequired, + /** + * Specifying a to URL will use a react-router Link + */ + to: PropTypes.string, + /** + * If using a button, then type is defines the type of button + */ + type: PropTypes.oneOf(['button', 'submit']), +}; + +export default Button; diff --git a/client/components/Button/Button.stories.jsx b/client/common/Button.stories.jsx similarity index 71% rename from client/components/Button/Button.stories.jsx rename to client/common/Button.stories.jsx index 1ae8d9f1..9f40ac73 100644 --- a/client/components/Button/Button.stories.jsx +++ b/client/common/Button.stories.jsx @@ -2,10 +2,10 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; import { boolean, text } from '@storybook/addon-knobs'; -import Button from '.'; +import Button from './Button'; export default { - title: 'Common/Button (JS)', + title: 'Common/Button', component: Button }; @@ -26,3 +26,11 @@ export const SubmitButton = () => ( export const PrimaryButton = () => ; export const DisabledButton = () => ; + +export const AnchorButton = () => ( + +); + +export const ReactRouterLink = () => ( + +); diff --git a/client/components/Button/Button.stories.mdx b/client/components/Button/Button.stories.mdx deleted file mode 100644 index 28c48300..00000000 --- a/client/components/Button/Button.stories.mdx +++ /dev/null @@ -1,32 +0,0 @@ -import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; -import { action } from '@storybook/addon-actions'; -import { boolean, text } from '@storybook/addon-knobs'; - -import Button from './'; - - - -# Button - -A button is used to perform an action. - - - - - - - - - - - - - - - diff --git a/client/components/Button/index.js b/client/components/Button/index.js deleted file mode 100644 index ea7afd36..00000000 --- a/client/components/Button/index.js +++ /dev/null @@ -1,50 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import styled from 'styled-components'; -import { remSize, prop } from '../../theme'; - -const StyledButton = styled.button` - background-color: ${prop('buttonColorBackground')}; - color: ${prop('buttonColor')}; - cursor: pointer; - border: 2px solid ${prop('buttonBorderColor')}; - border-radius: 2px; - padding: ${remSize(8)} ${remSize(25)}; - line-height: 1; - margin: 0; - - &:hover:not(:disabled) { - color: ${prop('buttonHoverColor')}; - background-color: ${prop('buttonHoverColorBackground')}; - } - - &:disabled { - color: ${prop('buttonDisabledColor')}; - background-color: ${prop('buttonDisabledColorBackground')}; - cursor: not-allowed; - } -`; - -/** - * This text will be used for the description in the story - */ -const Button = ({ children, label, ...props }) => { - return {children}; -} - -Button.propTypes = { - /** - * The visible part of the button - */ - children: PropTypes.element.isRequired, - /** - If the button can be clicked or not - */ - disabled: PropTypes.bool, - /* - * An ARIA Label used for accessibility - */ - label: PropTypes.string.isRequired, -}; - -export default Button; diff --git a/client/modules/User/components/LoginForm.jsx b/client/modules/User/components/LoginForm.jsx index 3c0c8050..d4163020 100644 --- a/client/modules/User/components/LoginForm.jsx +++ b/client/modules/User/components/LoginForm.jsx @@ -1,5 +1,8 @@ import PropTypes from 'prop-types'; import React from 'react'; + +import Button from '../../../common/Button'; + import { domOnlyProps } from '../../../utils/reduxFormUtils'; function LoginForm(props) { @@ -30,7 +33,12 @@ function LoginForm(props) { /> {password.touched && password.error && {password.error}}

- + ); }