diff --git a/packages/ui-toolkit/src/breakpoints/index.js b/packages/ui-toolkit/src/breakpoints/index.js
index 043ba650..b9d4fede 100644
--- a/packages/ui-toolkit/src/breakpoints/index.js
+++ b/packages/ui-toolkit/src/breakpoints/index.js
@@ -1,40 +1,42 @@
import { css } from 'styled-components';
import remcalc from 'remcalc';
-const bounds = {
+export const breakpoints = {
small: {
- upper: remcalc(768)
+ upper: 768
},
medium: {
- upper: remcalc(1024),
- lower: remcalc(769)
+ upper: 1024,
+ lower: 769
},
large: {
- upper: remcalc(1200),
- lower: remcalc(1025)
+ upper: 1200,
+ lower: 1025
},
xlarge: {
- lower: remcalc(1201)
+ lower: 1201
}
};
const screens = {
// >= 768px
- smallOnly: `only screen and (max-width: ${bounds.small.upper})`,
- small: `only screen and (min-width: ${bounds.small.upper}})`,
+ smallOnly: `only screen and (max-width: ${remcalc(breakpoints.small.upper)})`,
+ small: `only screen and (min-width: ${remcalc(breakpoints.small.upper)})`,
// >= 1024px
- mediumOnly: `only screen and (min-width: ${bounds.medium.lower})
- and (max-width: ${bounds.medium.upper})`,
- mediumDown: `only screen and (max-width: ${bounds.medium.upper})`,
- medium: `only screen and (min-width: ${bounds.medium.lower})`,
+ mediumOnly: `only screen and (min-width: ${remcalc(breakpoints.medium.lower)})
+ and (max-width: ${remcalc(breakpoints.medium.upper)})`,
+ mediumDown: `only screen and (max-width: ${remcalc(
+ breakpoints.medium.upper
+ )})`,
+ medium: `only screen and (min-width: ${remcalc(breakpoints.medium.lower)})`,
// >= 1200px
- largeOnly: `only screen and (min-width: ${bounds.large.lower})
- and (max-width: ${bounds.large.upper})`,
- largeDown: `only screen and (max-width: ${bounds.large.upper})`,
- large: `only screen and (min-width: ${bounds.large.upper})`,
- xlarge: `only screen and (min-width: ${bounds.xlarge.lower})
- and (max-width: ${bounds.xlarge.upper})`,
- xlargeUp: `only screen and (min-width: ${bounds.xlarge.lower})`
+ largeOnly: `only screen and (min-width: ${remcalc(breakpoints.large.lower)})
+ and (max-width: ${remcalc(breakpoints.large.upper)})`,
+ largeDown: `only screen and (max-width: ${remcalc(breakpoints.large.upper)})`,
+ large: `only screen and (min-width: ${remcalc(breakpoints.large.upper)})`,
+ xlarge: `only screen and (min-width: ${remcalc(breakpoints.xlarge.lower)})
+ and (max-width: ${remcalc(breakpoints.xlarge.upper)})`,
+ xlargeUp: `only screen and (min-width: ${remcalc(breakpoints.xlarge.lower)})`
};
const breakpoint = label => (...args) => css`
@@ -64,5 +66,6 @@ export default {
largeDown,
large,
xlarge,
- xlargeUp
+ xlargeUp,
+ breakpoints
};
diff --git a/packages/ui-toolkit/src/dropdown/index.js b/packages/ui-toolkit/src/dropdown/index.js
new file mode 100644
index 00000000..e32d12b5
--- /dev/null
+++ b/packages/ui-toolkit/src/dropdown/index.js
@@ -0,0 +1,131 @@
+import React, { Component } from 'react';
+import ReactDOM from 'react-dom';
+import PropTypes from 'prop-types';
+import styled from 'styled-components';
+import { Select } from '../form';
+import { Tooltip, TooltipButton as DropdownItem } from '../tooltip';
+import Baseline from '../baseline';
+import { small, smallOnly } from '../breakpoints';
+import { ArrowIcon } from '../icons';
+import remcalc from 'remcalc';
+
+const StyledSelectList = styled(Tooltip)`
+ ${smallOnly`
+ display: none;
+ `};
+ width: 100%;
+ ul {
+ position: relative;
+ display: block;
+ left: auto;
+ }
+ ul:after, ul:before {
+ left: 97%;
+ }
+`;
+
+const StyledSelect = styled(Select)`
+ ${small`
+ option {
+ display: none;
+ }
+ `}
+`;
+
+const StyledArrowIcon = styled(ArrowIcon)`
+ ${smallOnly`
+ display: none;
+ `};
+ position: absolute;
+ left: 97%;
+ top: 50%;
+ margin-left: -${remcalc(4.5)};
+`;
+
+const Container = styled.div`
+ position: relative;
+`;
+
+/**
+ * @example ./usage.md
+ */
+class Dropdown extends Component {
+ constructor(props) {
+ super(props);
+
+ this.toggleDropdown = this.toggleDropdown.bind(this);
+ this.dropdownOnChange = this.dropdownOnChange.bind(this);
+ this.dropdownOnBlur = this.dropdownOnBlur.bind(this);
+
+ this.state = {
+ isDroppedDown: false
+ };
+ }
+ componentDidMount() {
+ window.addEventListener('click', this.dropdownOnBlur);
+ }
+ componentWillUnmount() {
+ window.addEventListener('click', this.dropdownOnBlur);
+ }
+ toggleDropdown() {
+ this.setState(prevState => ({ isDroppedDown: !prevState.isDroppedDown }));
+ }
+ dropdownOnBlur(ev) {
+ if (
+ !ReactDOM.findDOMNode(this).contains(ev.target) &&
+ this.state.isDroppedDown
+ ) {
+ this.toggleDropdown();
+ }
+ }
+ dropdownOnChange(ev) {
+ this.setState({ isDroppedDown: false });
+ if (!this.props.onChange) {
+ return;
+ }
+ this.props.onChange(ev.target.value);
+ }
+ render() {
+ const { data, placeholder, className, id, ...rest } = this.props;
+ return (
+