diff --git a/src/components/Button/Button.stories.tsx b/src/components/Button/Button.stories.tsx
index baf5b83..ebad486 100644
--- a/src/components/Button/Button.stories.tsx
+++ b/src/components/Button/Button.stories.tsx
@@ -1,3 +1,3 @@
-import { Button } from "./Button";
+import Button from "./index";
export default { title: 'BasicButton' };
-export const Test = () =>
\ No newline at end of file
+export const Test = () => ;
\ No newline at end of file
diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx
deleted file mode 100644
index c546e8a..0000000
--- a/src/components/Button/Button.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React from 'react';
-
-interface ButtonProps {
- /**
- * Is this the principal call to action on the page?
- */
- primary?: boolean;
- /**
- * What background color to use
- */
- backgroundColor?: string;
- /**
- * How large should the button be?
- */
- size?: 'small' | 'medium' | 'large';
- /**
- * Button contents
- */
- label: string;
- /**
- * Optional click handler
- */
- onClick?: () => void;
-}
-
-/**
- * Primary UI component for user interaction
- */
-export const Button = ({
- primary = false,
- size = 'medium',
- backgroundColor,
- label,
- ...props
-}: ButtonProps) => {
- const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
- return (
-
- );
-};
diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx
new file mode 100644
index 0000000..f4c4e05
--- /dev/null
+++ b/src/components/Button/index.tsx
@@ -0,0 +1,99 @@
+import React, { FC } from 'react';
+import { ButtonElement } from './styles';
+import {
+ Colors,
+ ButtonProps,
+ FontColors,
+ ActiveColors,
+ DisabledColors,
+ DisabledFontColors
+} from './types';
+import { Botton } from '../typography';
+import {
+ colorObjectToColorString, isBackgroundNone
+} from './utils';
+import Spinner from '../../static/svg/Spinner';
+// import * as Styles from './styles';
+
+enum Cursor {
+ DISABLED = "not-allowed",
+ LOADING = "progress",
+ DEFAULT = "pointer"
+};
+
+enum PaddingVertical {
+ lg = 16,
+ md = 16,
+ sm = 8
+};
+
+enum PaddingHorizontal {
+ lg = 150,
+ md = 68,
+ sm = 16
+};
+
+enum BorderRadius {
+ lg = 12,
+ md = 12,
+ sm = 4
+}
+
+const initialProps: ButtonProps = {
+ fill: "default",
+ size: "md",
+ loading: false,
+ disabled: false,
+ background: true
+};
+
+const Button: FC = (props = initialProps) => {
+ const {
+ children,
+ onClick,
+ disabled,
+ className,
+ fill,
+ leftIcon,
+ rightIcon,
+ loading,
+ size,
+ } = props;
+
+ const cursorType = disabled ? "DISABLED" : loading ? "LOADING" : "DEFAULT";
+ const colorString = colorObjectToColorString(fill, true);
+ const BackgroundColor = disabled ? DisabledColors[colorString] : Colors[colorString];
+ const BackgroundActiveColor = disabled ? DisabledColors[colorString] : ActiveColors[colorString];
+ const FontColor = disabled ? DisabledFontColors[colorString] : FontColors[colorString];
+
+ const styledProps = {
+ cursor: Cursor[cursorType],
+ background: BackgroundColor,
+ activeBackground: loading && isBackgroundNone(colorString) ? BackgroundColor : BackgroundActiveColor,
+ paddingVertical: PaddingVertical[size || "md"],
+ paddingHorizontal: PaddingHorizontal[size || "md"],
+ borderRadius: BorderRadius[size || "md"],
+ size: size || "md",
+ fillStyle: fill || "default",
+ marginLeft: leftIcon ? 6 : 0,
+ marginRight: loading || rightIcon ? 6 : 0,
+ };
+
+ return (
+
+ { leftIcon }
+
+ { children }
+
+ { loading && }
+ { rightIcon }
+
+ )
+};
+
+export default Button;
\ No newline at end of file
diff --git a/src/components/Button/styles.ts b/src/components/Button/styles.ts
new file mode 100644
index 0000000..208e4bf
--- /dev/null
+++ b/src/components/Button/styles.ts
@@ -0,0 +1,76 @@
+import styled from '@emotion/styled';
+import { css } from '@emotion/react';
+import {
+ ButtonElementProps,
+ Colors,
+ FontColors,
+} from './types';
+
+export const ButtonElement = styled.button`
+ display: flex;
+ align-items: center;
+ border: none;
+ cursor: ${(props) => props.cursor};
+ background: ${(props) => props.background};
+ padding: ${(props) => `${props.paddingVertical}px ${props.paddingHorizontal}px`};
+ border-radius: ${(props) => props.borderRadius}px;
+
+ ${(props) => typeof props.fillStyle !== "string" && props.fillStyle.full && Full}
+
+ &:hover, &:active {
+ background: ${(props) => props.activeBackground};
+ }
+
+ & .semicolon-button-typography {
+ margin-left: ${(props) => props.marginLeft}px;
+ margin-right: ${(props) => props.marginRight}px;
+ }
+`;
+
+export const Large = css`
+ border-radius: 12px;
+`;
+
+export const Medium = css`
+ border-radius: 12px;
+`;
+
+export const Small = css`
+ border-radius: 4px;
+`;
+
+export const Default = css`
+`;
+
+export const Purple = css`
+`;
+
+export const PurpleLight = css`
+`;
+
+export const Border = css`
+ border: 1px solid ${Colors.borderColor};
+`;
+
+export const BnDefault = css`
+ background: none;
+`;
+
+export const BnPurple = css`
+ background: none;
+`;
+
+export const Full = css`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 0;
+`;
+
+export const Link = css`
+ &:hover, &:active {
+ text-decoration: underline 1px solid ${FontColors.link};
+ }
+`;
\ No newline at end of file
diff --git a/src/components/Button/types.ts b/src/components/Button/types.ts
new file mode 100644
index 0000000..cbdad04
--- /dev/null
+++ b/src/components/Button/types.ts
@@ -0,0 +1,95 @@
+import { ReactElement, Component, MouseEvent } from 'react';
+import { colors } from '../shared/styles';
+
+export type SizeType = "sm" | "md" | "lg";
+
+export type BackgroundNoneSupportFillStyleType = "default" | "purple";
+
+export type FillStyleType = "purpleLight" | "link" | "border" | BackgroundNoneSupportFillStyleType;
+
+export type BackgroundNoneFillStyleType = "bnDefault" | "bnPurple";
+
+export interface FillStyleObjectType {
+ fillStyle?: FillStyleType,
+ background?: boolean,
+ full?: boolean
+};
+
+export type CursorType = "not-allowed" | "progress" | "pointer";
+
+export interface ButtonProps {
+ leftIcon?: ReactElement ReactElement | null) | (new (props: any) => Component)>;
+ rightIcon?: ReactElement ReactElement | null) | (new (props: any) => Component)>;
+ fill?: FillStyleType | FillStyleObjectType;
+ size?: SizeType;
+ className?: string;
+ loading?: boolean;
+ disabled?: boolean;
+ background?: boolean;
+ onClick?: (event?: MouseEvent) => void;
+};
+
+export interface ButtonElementProps {
+ cursor: CursorType;
+ background: string;
+ activeBackground: string;
+ paddingVertical: number;
+ paddingHorizontal: number;
+ borderRadius: number;
+ size: SizeType;
+ fillStyle: FillStyleType | FillStyleObjectType;
+ marginLeft: number;
+ marginRight: number;
+};
+
+export const Colors = {
+ default: colors.grey100,
+ purple: colors.purple400,
+ purpleLight: colors.purple50,
+ border: colors.white,
+ borderColor: colors.grey100,
+ link: colors.white,
+ bnDefault: colors.white,
+ bnPurple: colors.white,
+};
+
+export const ActiveColors = {
+ default: colors.grey300,
+ purple: colors.purple500,
+ purpleLight: colors.purple100,
+ border: colors.grey100,
+ link: colors.white,
+ bnDefault: colors.grey50,
+ bnPurple: colors.purple50,
+};
+
+export const FontColors = {
+ default: colors.grey700,
+ purple: colors.white,
+ purpleLight: colors.purple400,
+ border: colors.grey700,
+ link: colors.blue400,
+ full: colors.grey700,
+ bnDefault: colors.grey700,
+ bnPurple: colors.purple400
+};
+
+export const DisabledColors = {
+ default: colors.grey50,
+ purple: colors.purple50,
+ purpleLight: colors.grey50,
+ border: colors.grey50,
+ link: colors.grey50,
+ bnDefault: colors.grey50,
+ bnPurple: colors.grey50,
+}
+
+export const DisabledFontColors = {
+ default: colors.grey300,
+ purple: colors.white,
+ purpleLight: colors.grey300,
+ border: colors.grey300,
+ link: colors.grey300,
+ bnDefault: colors.grey300,
+ bnPurple: colors.grey300,
+}
\ No newline at end of file
diff --git a/src/components/Button/utils.ts b/src/components/Button/utils.ts
new file mode 100644
index 0000000..82f4eb4
--- /dev/null
+++ b/src/components/Button/utils.ts
@@ -0,0 +1,95 @@
+import {
+ SizeType,
+ FillStyleType,
+ BackgroundNoneFillStyleType,
+ FillStyleObjectType,
+} from './types';
+import {
+ Small,
+ Medium,
+ Large,
+ Default,
+ Purple,
+ PurpleLight,
+ Link,
+ Full,
+ Border,
+ BnDefault,
+ BnPurple
+} from './styles';
+
+export function sizeToCssObject(size: SizeType) {
+ switch(size) {
+ case "sm":
+ return Small;
+ case "md":
+ return Medium;
+ case "lg":
+ return Large;
+ default:
+ return Medium;
+ }
+}
+
+export function colorToCssObject(color: FillStyleType | BackgroundNoneFillStyleType) {
+ switch(color) {
+ case "default":
+ return Default;
+ case "purple":
+ return Purple;
+ case "purpleLight":
+ return PurpleLight;
+ case "border":
+ return Border;
+ case "link":
+ return Link;
+ case "bnDefault":
+ return BnDefault;
+ case "bnPurple":
+ return BnPurple;
+ default:
+ return Default;
+ }
+}
+
+export function colorObjectToCssObject(color: FillStyleType | FillStyleObjectType) {
+ if(typeof color === "string") {
+ return colorToCssObject(color);
+ } else {
+ if(color.background === true) return colorToCssObject(color.fillStyle || "default");
+ else {
+ switch(color.fillStyle) {
+ case "default":
+ return colorToCssObject(firstCharToTypeMessage(color.fillStyle));
+ case "purple":
+ return colorToCssObject(firstCharToTypeMessage(color.fillStyle));
+ default:
+ return colorToCssObject(color.fillStyle || "default");
+ }
+ }
+ }
+}
+
+export function colorObjectToColorString(color?: FillStyleType | FillStyleObjectType, addedBn?: boolean) {
+ if(typeof color === "string") return color || "default";
+ else if(typeof color === "undefined") return "default"
+ else if(addedBn && color.background === false) {
+ switch(color.fillStyle) {
+ case "default":
+ return firstCharToTypeMessage(color.fillStyle);
+ case "purple":
+ return firstCharToTypeMessage(color.fillStyle);
+ default:
+ return color.fillStyle || "default";
+ }
+ } else return color.fillStyle || "default";
+}
+
+export function firstCharToTypeMessage(message: string): BackgroundNoneFillStyleType {
+ return "bn" + message.charAt(0).toUpperCase() + message.slice(1) as BackgroundNoneFillStyleType;
+}
+
+export function isBackgroundNone(color: string): boolean {
+ if(color.indexOf("bn") !== -1) return true;
+ else return false;
+}
\ No newline at end of file
diff --git a/src/components/index.ts b/src/components/index.ts
index c1a579f..08faf3d 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -1,2 +1,2 @@
-export * from './Button/Button'
+export * from './Button'
export * from './typography'
\ No newline at end of file
diff --git a/src/static/svg/Spinner.tsx b/src/static/svg/Spinner.tsx
new file mode 100644
index 0000000..3e41ce0
--- /dev/null
+++ b/src/static/svg/Spinner.tsx
@@ -0,0 +1,60 @@
+import React, { FC } from 'react';
+import { colors } from '../../components/shared/styles';
+import { FillStyleType, BackgroundNoneFillStyleType } from '../../components/Button/types';
+
+interface SpinnerProps {
+ fill: FillStyleType | BackgroundNoneFillStyleType;
+}
+
+const Colors = {
+ default: {
+ inColor: colors.grey500,
+ outColor: colors.grey300
+ },
+ purple: {
+ inColor: colors.white,
+ outColor: colors.purple500
+ },
+ purpleLight: {
+ inColor: colors.purple400,
+ outColor: colors.purple100
+ },
+ border: {
+ inColor: colors.grey500,
+ outColor: colors.grey300
+ },
+ link: {
+ inColor: colors.white,
+ outColor: colors.white
+ },
+ bnDefault: {
+ inColor: colors.white,
+ outColor: colors.white
+ },
+ bnPurple: {
+ inColor: colors.white,
+ outColor: colors.white
+ },
+}
+
+const Spinner: FC = (props) => {
+ const {outColor, inColor} = Colors[props.fill];
+
+ return (
+
+ )
+}
+
+export default Spinner
\ No newline at end of file