diff --git a/components/dropdown/Dropdown.jsx b/components/dropdown/Dropdown.jsx index 8ed8f30d..97b66f72 100644 --- a/components/dropdown/Dropdown.jsx +++ b/components/dropdown/Dropdown.jsx @@ -1,5 +1,7 @@ import React from 'react'; import ClassNames from 'classnames'; +import Input from '../input'; +import events from '../utils/events'; import style from './style'; class Dropdown extends React.Component { @@ -7,6 +9,7 @@ class Dropdown extends React.Component { auto: React.PropTypes.bool, className: React.PropTypes.string, disabled: React.PropTypes.bool, + error: React.PropTypes.string, label: React.PropTypes.string, onChange: React.PropTypes.func, source: React.PropTypes.array.isRequired, @@ -25,7 +28,8 @@ class Dropdown extends React.Component { up: false }; - handleClick = (event) => { + handleMouseDown = (event) => { + events.pauseEvent(event); const client = event.target.getBoundingClientRect(); const screen_height = window.innerHeight || document.documentElement.offsetHeight; const up = this.props.auto ? client.top > ((screen_height / 2) + client.height) : false; @@ -49,7 +53,24 @@ class Dropdown extends React.Component { } }; - renderItem (item, idx) { + renderTemplateValue (selected) { + const className = ClassNames(style.field, { + [style.errored]: this.props.error, + [style.disabled]: this.props.disabled + }); + + return ( +
+
+ {this.props.template(selected)} +
+ {this.props.label ? : null} + {this.props.error ? {this.props.error} : null} +
+ ); + } + + renderValue (item, idx) { const className = item.value === this.props.value ? style.selected : null; return (
  • @@ -59,6 +80,7 @@ class Dropdown extends React.Component { } render () { + const {template, source, ...others} = this.props; const selected = this.getSelectedItem(); const className = ClassNames(style.root, { [style.up]: this.state.up, @@ -68,15 +90,18 @@ class Dropdown extends React.Component { return (
    - {this.props.label ? : null} - -
    ); } diff --git a/components/dropdown/readme.md b/components/dropdown/readme.md index 39609dfe..89f3f71d 100644 --- a/components/dropdown/readme.md +++ b/components/dropdown/readme.md @@ -42,6 +42,7 @@ class DropdownTest extends React.Component { | `auto` | `Boolean` | `true` | If true, the dropdown will open up or down depending on the position in the screen .| | `className` | `String` | `''` | Set the class to give custom styles to the dropdown. | `disabled` | `Boolean` | `false` | Set the component as disabled. +| `error` | `String` | | Give an error string to display under the field.| | `label` | `String` | | The text string to use for the floating label element. | `onChange` | `Function` | | Callback function that is fired when the component's value changes. | `source` | `Array` | | Array of data objects with the data to represent in the dropdown. diff --git a/components/dropdown/style.scss b/components/dropdown/style.scss index 2a7390ca..3e370fce 100644 --- a/components/dropdown/style.scss +++ b/components/dropdown/style.scss @@ -4,11 +4,6 @@ .root { position: relative; - width: inherit; - margin-bottom: $dropdown-offset; - color: $color-text; - cursor: pointer; - border-bottom: 1px solid $input-text-bottom-border-color; &:not(.active) { > .values { max-height: 0; @@ -25,15 +20,6 @@ box-shadow: $zdepth-shadow-1; } } - &.disabled { - color: $color-text-secondary; - pointer-events: none; - cursor: normal; - border-bottom-style: dotted; - > .value:after { - transform: scale(0); - } - } &:not(.up) > .values { top: 0; bottom: auto; @@ -42,19 +28,84 @@ top: auto; bottom: 0; } + &.disabled { + pointer-events: none; + cursor: normal; + } +} + +.value { + > input { + cursor: pointer; + } + &:after { + $size: ($input-field-height / 7); + $border: $size solid transparent; + position: absolute; + right: ($dropdown-offset / 2); + top: 50%; + width: 0; + height: 0; + content: ""; + border-top: $size solid $input-text-bottom-border-color; + border-right: $border; + border-left: $border; + transition: transform $animation-duration $animation-curve-default; + } +} +.field { + position: relative; + padding: $input-padding 0; + cursor: pointer; + &.errored { + padding-bottom: 0; + > .label { + color: $input-text-error-color; + } + > .valueWrapper { + border-bottom: 1px solid $input-text-error-color; + } + } + &.disabled { + cursor: normal; + pointer-events: none; + > .templateValue { + opacity: .7; + border-bottom-style: dotted; + } + } +} + +.templateValue { + border-bottom: 1px solid $input-text-bottom-border-color; + color: $color-text; + min-height: $input-field-height; + background-color: $input-text-background-color; + padding: $input-field-padding 0; + position: relative; } .label { - font-size: $font-size-tiny; - color: $color-text-secondary; + position: absolute; + left: 0; + font-size: $input-label-font-size; + line-height: $input-field-font-size; + color: $input-text-label-color; + top: $input-focus-label-top; +} + +.error { + margin-bottom: - $input-underline-height; + font-size: $input-label-font-size; + line-height: $input-underline-height; + color: $input-text-error-color; } .values { @include no-webkit-scrollbar; + z-index: $z-index-high; position: absolute; - z-index: 2; width: 100%; - overflow-x: hidden; overflow-y: auto; list-style: none; background-color: $dropdown-color-white; @@ -75,30 +126,3 @@ } } } - -.value { - display: block; - > span { - display: inline-block; - height: $input-field-height; - font-size: $input-field-font-size; - line-height: $input-field-height; - } - > :not(span) { - margin: ($dropdown-offset / 2) 0; - } - &:after { - $size: ($input-field-height / 7); - $border: $size solid transparent; - position: absolute; - right: ($dropdown-offset / 2); - bottom: $dropdown-offset; - width: 0; - height: 0; - content: ""; - border-top: $size solid $input-text-bottom-border-color; - border-right: $border; - border-left: $border; - transition: transform $animation-duration $animation-curve-default; - } -} diff --git a/components/input/_config.scss b/components/input/_config.scss index bc7c5450..81f78e0a 100644 --- a/components/input/_config.scss +++ b/components/input/_config.scss @@ -1,7 +1,7 @@ $input-padding: 2 * $unit; $input-field-padding: .8 * $unit; $input-field-font-size: 1.6 * $unit; -$input-field-height: $input-field-padding * 2 + $input-field-font-size; +$input-field-height: $input-field-padding * 2 + $input-field-font-size * 1.4; $input-label-font-size: 1.2 * $unit; $input-focus-label-top: .6 * $unit; $input-text-background-color: transparent !default; diff --git a/components/input/style.scss b/components/input/style.scss index 6d613fe5..f77b5896 100644 --- a/components/input/style.scss +++ b/components/input/style.scss @@ -111,6 +111,7 @@ .errored { padding-bottom: 0; > .input { + margin-top: 1px; border-bottom-color: $input-text-error-color; &:focus { ~ .label:not(.fixed) { diff --git a/spec/components/dropdown.jsx b/spec/components/dropdown.jsx index a38797e7..14dc6112 100644 --- a/spec/components/dropdown.jsx +++ b/spec/components/dropdown.jsx @@ -41,6 +41,7 @@ class DropdownTest extends React.Component {

    lorem ipsum...

    - - );