🧱 Adds reusable Button and Heading components

This commit is contained in:
Alicia Sykes 2022-06-25 19:50:03 +01:00
parent 2cfcd9426b
commit 090c97b8ac
3 changed files with 97 additions and 32 deletions

View File

@ -0,0 +1,50 @@
import styled from 'styled-components';
import colors from 'styles/colors';
import { InputSize, applySize } from 'styles/dimensions';
interface ButtonProps {
children: React.ReactNode;
onClick?: React.MouseEventHandler<HTMLButtonElement>;
size?: InputSize,
bgColor?: string,
fgColor?: string,
};
const StyledButton = styled.button<ButtonProps>`
cursor: pointer;
border: none;
border-radius: 0.25rem;
font-family: PTMono;
box-sizing: border-box;
width: -moz-available;
box-shadow: 3px 3px 0px ${colors.fgShadowColor};
&:hover {
box-shadow: 5px 5px 0px ${colors.fgShadowColor};
}
&:active {
box-shadow: -3px -3px 0px ${colors.fgShadowColor};
}
${props => applySize(props.size)};
${(props) => props.bgColor ?
`background: ${props.bgColor};` : `background: ${colors.primary};`
}
${(props) => props.fgColor ?
`color: ${props.fgColor};` : `color: ${colors.background};`
}
`;
const Button = (props: ButtonProps): JSX.Element => {
const { children, size, bgColor, fgColor, onClick } = props;
return (
<StyledButton
onClick={onClick || (() => null) }
size={size}
bgColor={bgColor}
fgColor={fgColor}
>
{children}
</StyledButton>
);
};
export default Button;

View File

@ -0,0 +1,44 @@
import styled from 'styled-components';
import colors from 'styles/colors';
interface HeadingProps {
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'p';
align?: 'left' | 'center' | 'right';
color?: string;
size?: 'small' | 'medium' | 'large';
inline?: boolean;
children: React.ReactNode;
};
const StyledHeading = styled.h1<HeadingProps>`
margin: 0.5rem;
text-shadow: 2px 2px 0px ${colors.bgShadowColor};
${props => {
switch (props.size) {
case 'small': return 'font-size: 1rem;';
case 'medium': return 'font-size: 2rem;';
case 'large': return 'font-size: 3rem;';
}
}};
${props => {
switch (props.align) {
case 'left': return 'text-align: left;';
case 'right': return 'text-align: right;';
case 'center': return 'text-align: center;';
}
}};
${props => props.color ? `color: ${props.color};` : '' }
${props => props.inline ? 'display: inline;' : '' }
`;
const Heading = (props: HeadingProps): JSX.Element => {
const { children, as, size, align, color, inline } = props;
return (
<StyledHeading as={as} size={size} align={align} color={color} inline={inline}>
{children}
</StyledHeading>
);
}
export default Heading;

View File

@ -1,9 +1,8 @@
import { InputHTMLAttributes } from 'react';
import styled from 'styled-components';
import colors from 'styles/colors';
import { InputSize, applySize } from 'styles/dimensions';
type InputSize = 'small' | 'medium' | 'large';
type Orientation = 'horizontal' | 'vertical';
interface Props {
@ -22,36 +21,6 @@ interface StyledInputTypes extends InputHTMLAttributes<SupportedElements> {
orientation?: Orientation;
};
const applySize = (inputSize?: InputSize) => {
const sizeSpecificStyles = {
small: `
font-size: 1rem;
border-radius: 0.25rem;
padding: 0.5rem 1rem;
margin: 0.5rem;
`,
medium: `
font-size: 1.5rem;
border-radius: 0.25rem;
padding: 0.75rem 1.5rem;
margin: 0.5rem;
`,
large: `
font-size: 2rem;
border-radius: 0.25rem;
padding: 1rem 1.75rem;
margin: 0.5rem;
`,
};
switch (inputSize) {
case 'small': return sizeSpecificStyles.small;
case 'medium': return sizeSpecificStyles.medium;
case 'large': return sizeSpecificStyles.large;
default: return sizeSpecificStyles.small;
}
};
const InputContainer = styled.div<StyledInputTypes>`
display: flex;
${props => props.orientation === 'vertical' ? 'flex-direction: column;' : ''};
@ -62,6 +31,8 @@ const StyledInput = styled.input<StyledInputTypes>`
color: ${colors.textColor};
border: none;
border-radius: 0.25rem;
font-family: PTMono;
box-shadow: 3px 3px 0px ${colors.backgroundDarker};
&:focus {
outline: 1px solid ${colors.primary}
}