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'