diff --git a/ui/app/components/app/index.scss b/ui/app/components/app/index.scss
index 49468037a..1f91ad3e4 100644
--- a/ui/app/components/app/index.scss
+++ b/ui/app/components/app/index.scss
@@ -100,6 +100,8 @@
@import '../ui/check-box/index';
+@import '../ui/dropdown/dropdown';
+
@import 'permissions-connect-header/index';
@import 'permissions-connect-footer/index';
diff --git a/ui/app/components/ui/dropdown/dropdown.js b/ui/app/components/ui/dropdown/dropdown.js
new file mode 100644
index 000000000..c709793b1
--- /dev/null
+++ b/ui/app/components/ui/dropdown/dropdown.js
@@ -0,0 +1,63 @@
+import React, { useCallback } from 'react'
+import PropTypes from 'prop-types'
+import classnames from 'classnames'
+
+const Dropdown = ({ className, disabled, onChange, options, selectedOption, style, title }) => {
+ const _onChange = useCallback(
+ (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ onChange(event.target.value)
+ },
+ [onChange],
+ )
+
+ return (
+
+ )
+}
+
+Dropdown.propTypes = {
+ className: PropTypes.string,
+ disabled: PropTypes.bool,
+ title: PropTypes.string,
+ onChange: PropTypes.func.isRequired,
+ options: PropTypes.arrayOf(
+ PropTypes.exact({
+ name: PropTypes.string,
+ value: PropTypes.string.isRequired,
+ })
+ ).isRequired,
+ selectedOption: PropTypes.string,
+ style: PropTypes.object,
+}
+
+Dropdown.defaultProps = {
+ className: undefined,
+ disabled: false,
+ title: undefined,
+ selectedOption: null,
+ style: undefined,
+}
+
+export default Dropdown
diff --git a/ui/app/components/ui/dropdown/dropdown.scss b/ui/app/components/ui/dropdown/dropdown.scss
new file mode 100644
index 000000000..064c0788b
--- /dev/null
+++ b/ui/app/components/ui/dropdown/dropdown.scss
@@ -0,0 +1,22 @@
+.dropdown {
+ appearance: none;
+
+ // TODO: remove these after getting autoprefixer working in Storybook
+ -moz-appearance: none;
+ -webkit-appearance: none;
+
+ border: 1px solid $Grey-500;
+ border-radius: 6px;
+ background-image: url('/images/icons/caret-down.svg');
+ background-repeat: no-repeat, repeat;
+ background-position: right 18px top 50%;
+ background-color: white;
+ padding: 8px 32px 8px 16px;
+ font-family: Roboto, 'sans-serif';
+ font-size: 14px;
+
+ [dir='rtl'] & {
+ background-position: left 18px top 50%;
+ padding: 8px 16px 8px 32px;
+ }
+}
diff --git a/ui/app/components/ui/dropdown/dropdown.stories.js b/ui/app/components/ui/dropdown/dropdown.stories.js
new file mode 100644
index 000000000..6e864e2ed
--- /dev/null
+++ b/ui/app/components/ui/dropdown/dropdown.stories.js
@@ -0,0 +1,90 @@
+import React from 'react'
+import { action } from '@storybook/addon-actions'
+import Dropdown from '.'
+import { boolean, select, text } from '@storybook/addon-knobs/react'
+
+export default {
+ title: 'Dropdown',
+}
+
+const unnamedOptions = [...Array(10).keys()].map((index) => {
+ return { value: `option${index}` }
+})
+
+const namedOptions = unnamedOptions.map((option, index) => {
+ return Object.assign({}, option, { name: `Option ${index}` })
+})
+
+const namedOptionsWithVeryLongNames = unnamedOptions.map((option, index) => {
+ return Object.assign({}, option, { name: `Option ${index} with a very${', very'.repeat(index)} long name` })
+})
+
+
+export const simple = () => (
+ option.value),
+ namedOptions[0].value
+ )
+ }
+ />
+)
+
+export const optionsWithoutNames = () => (
+ option.value),
+ unnamedOptions[0].value
+ )
+ }
+ />
+)
+
+export const optionsWithLongNames = () => (
+ option.value),
+ namedOptionsWithVeryLongNames[0].value
+ )
+ }
+ />
+)
+
+export const optionsWithLongNamesAndShortWidth = () => (
+ option.value),
+ namedOptionsWithVeryLongNames[0].value
+ )
+ }
+ style={{ width: '200px' }}
+ />
+)
diff --git a/ui/app/components/ui/dropdown/index.js b/ui/app/components/ui/dropdown/index.js
new file mode 100644
index 000000000..8d23b5709
--- /dev/null
+++ b/ui/app/components/ui/dropdown/index.js
@@ -0,0 +1 @@
+export { default } from './dropdown'