diff --git a/app/components/Button.mdx b/app/components/Button.mdx
new file mode 100644
index 0000000..c26bb96
--- /dev/null
+++ b/app/components/Button.mdx
@@ -0,0 +1,54 @@
+---
+name: Button
+---
+
+import { Playground, PropsTable } from 'docz'
+
+import { Button } from './button.js'
+import { DoczWrapper } from '../theme.js'
+
+# Button
+
+
+
+## Primary
+
+
+
+ {() => }
+
+
+
+## Secondary
+
+
+
+ {() =>
+
+
+
+## Primary Disabled
+
+
+
+ {() =>
+
+
+
+## Secondary Disabled
+
+
+
+
+ {() =>
+
+
+
+## Link Button
+
+
+
+ {() => }
+
+
diff --git a/app/components/Input.mdx b/app/components/Input.mdx
new file mode 100644
index 0000000..5111f62
--- /dev/null
+++ b/app/components/Input.mdx
@@ -0,0 +1,26 @@
+---
+name: Input
+---
+
+import { Playground, PropsTable } from 'docz'
+
+import { InputComponent } from './input.js'
+import { DoczWrapper } from '../theme.js'
+
+# Input
+
+
+
+## Text Input
+
+
+ {() => }
+
+
+## Textarea
+
+
+
+ {() => }
+
+
diff --git a/app/components/QRCode.mdx b/app/components/QRCode.mdx
new file mode 100644
index 0000000..d424423
--- /dev/null
+++ b/app/components/QRCode.mdx
@@ -0,0 +1,23 @@
+---
+name: QRCode
+---
+
+import { Playground, PropsTable } from 'docz'
+
+import { QRCode } from './qrcode.js'
+
+# QRCode
+
+
+
+## Basic usage
+
+
+
+
+
+## Custom size
+
+
+
+
diff --git a/app/components/button.js b/app/components/button.js
new file mode 100644
index 0000000..650bc7b
--- /dev/null
+++ b/app/components/button.js
@@ -0,0 +1,94 @@
+// @flow
+
+import React from 'react';
+import styled from 'styled-components';
+import { Link } from 'react-router-dom';
+/* eslint-disable import/no-extraneous-dependencies */
+// $FlowFixMe
+import { darken } from 'polished';
+
+const defaultStyles = `
+ padding: 10px 30px;
+ font-family: ${
+ // $FlowFixMe
+ props => props.theme.fontFamily
+};
+ font-weight: bold;
+ font-size: 0.9em;
+ cursor: pointer;
+ outline: none;
+ min-width: 100px;
+ border-radius: 100px;
+ transition: background-color 0.1s ease-in-out;
+`;
+
+const Primary = styled.button`
+ ${defaultStyles};
+ background-color: ${props => props.theme.colors.primary};
+ color: ${props => props.theme.colors.secondary};
+ border: none;
+
+ &:hover {
+ background-color: ${props => darken(0.1, props.theme.colors.primary(props))};
+ }
+
+ &:disabled {
+ background-color: #3e3c42;
+ cursor: not-allowed;
+ opacity: 0.8;
+ }
+`;
+
+const Secondary = styled.button`
+ ${defaultStyles};
+ background-color: Transparent;
+ color: ${props => props.theme.colors.secondary};
+ border: 2px solid #3e3c42;
+
+ &:hover {
+ border-color: ${props => props.theme.colors.primary};
+ }
+
+ &:disabled {
+ background-color: Transparent;
+ cursor: not-allowed;
+ color: #3e3c42;
+
+ &:hover {
+ border-color: #3e3c42;
+ }
+ }
+`;
+
+type Props = {
+ label: string,
+ onClick?: () => void,
+ to?: string,
+ variant?: 'primary' | 'secondary',
+ disabled?: boolean,
+};
+
+export const Button = ({
+ onClick, label, to, variant, disabled,
+}: Props) => {
+ if (to && onClick) throw new Error('Should define either "to" or "onClick"');
+
+ const component = variant === 'primary' ? (
+
+ {label}
+
+ ) : (
+
+ {label}
+
+ );
+
+ return to ? {component} : component;
+};
+
+Button.defaultProps = {
+ to: null,
+ variant: 'primary',
+ onClick: null,
+ disabled: false,
+};
diff --git a/app/components/input.js b/app/components/input.js
new file mode 100644
index 0000000..459ae30
--- /dev/null
+++ b/app/components/input.js
@@ -0,0 +1,53 @@
+// @flow
+import React from 'react';
+
+import styled from 'styled-components';
+
+// TODO: Missing styles
+
+const defaultStyles = `
+ padding: 10px;
+ width: 100%;
+ outline: none;
+ font-family: ${props => props.theme.fontFamily}
+`;
+
+const Input = styled.input.attrs({
+ type: 'text',
+})`
+ ${defaultStyles};
+`;
+
+const Textarea = styled.textarea`
+ ${defaultStyles};
+`;
+
+type Props = {
+ inputType?: 'input' | 'textarea' | 'dropdown',
+ value: string,
+ onChange: string => void,
+ rows?: number,
+ disabled?: boolean,
+ type?: string,
+};
+
+export const InputComponent = ({ inputType, onChange, ...props }: Props) => {
+ const inputTypes = {
+ input: () => onChange(evt.target.value)} {...props} />,
+ textarea: () =>