diff --git a/components/autocomplete/theme.css b/components/autocomplete/theme.css index 9ab93056..1c3f7d6b 100644 --- a/components/autocomplete/theme.css +++ b/components/autocomplete/theme.css @@ -21,11 +21,11 @@ } .withclear input { - text-indent: 28px !important; + text-indent: 28px; } .withclear label { - transition-property: top, left, font-size, color !important; + transition-property: top, left, font-size, color; } .inputFilled { @@ -33,7 +33,7 @@ } .withclear input:not(:focus):not(.inputFilled) ~ label { - left: 28px !important; + left: 28px; } .values { diff --git a/components/dropdown/Dropdown.d.ts b/components/dropdown/Dropdown.d.ts deleted file mode 100644 index 3ed67817..00000000 --- a/components/dropdown/Dropdown.d.ts +++ /dev/null @@ -1,132 +0,0 @@ -import * as React from "react"; -import ReactToolbox from "../index"; - -export interface DropdownTheme { - /** - * Added to the root element when the dropdown is active. - */ - active?: string; - /** - * Added to the root element when it's disabled. - */ - disabled?: string; - /** - * Root element class. - */ - dropdown?: string; - /** - * Used for the error element. - */ - error?: string; - /** - * Added to the inner wrapper if it's errored. - */ - errored?: string; - /** - * Used for the inner wrapper of the component. - */ - field?: string; - /** - * Used for the the label element. - */ - label?: string; - /** - * Used when dropdown has required attribute. - */ - required?: string; - /** - * Used to highlight the selected value. - */ - selected?: string; - /** - * Used as a wrapper for the given template value. - */ - templateValue?: string; - /** - * Added to the root element when it's opening up. - */ - up?: string; - /** - * Used for each value in the dropdown component. - */ - value?: string; - /** - * Used for the list of values. - */ - values?: string; -} - -export interface DropdownProps extends ReactToolbox.Props { - /** - * If true the dropdown will preselect the first item if the supplied value matches none of the options' values. - * @default true - */ - allowBlank?: boolean; - /** - * If true, the dropdown will open up or down depending on the position in the screen. - * @default true - */ - auto?: boolean; - /** - * Set the component as disabled. - * @default false - */ - disabled?: boolean; - /** - * Give an error string to display under the field. - */ - error?: string; - /** - * The text string to use for the floating label element. - */ - label?: string; - /** - * Used for setting the label from source - */ - labelKey?: string; - /** - * Name for the input field. - */ - name?: string; - /** - * Callback function that is fired when the component is blurred. - */ - onBlur?: Function; - /** - * Callback function that is fired when the component's value changes. - */ - onChange?: Function; - /** - * Callback function that is fired when the component is focused. - */ - onFocus?: Function; - /** - * If true, the dropdown has a required attribute. - * @default false - */ - required?: boolean; - /** - * Array of data objects with the data to represent in the dropdown. - */ - source: any[]; - /** - * Callback function that returns a JSX template to represent the element. - */ - template?: Function; - /** - * Classnames object defining the component style. - */ - theme?: DropdownTheme; - /** - * Default value using JSON data. - */ - value?: string | number; - /** - * Used for setting the value from source - */ - valueKey?: string; -} - -export class Dropdown extends React.Component { } - -export default Dropdown; diff --git a/components/dropdown/Dropdown.js b/components/dropdown/Dropdown.js deleted file mode 100644 index e0bc3048..00000000 --- a/components/dropdown/Dropdown.js +++ /dev/null @@ -1,247 +0,0 @@ -/* eslint-disable */ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import ReactDOM from 'react-dom'; -import classnames from 'classnames'; -import { themr } from 'react-css-themr'; -import { DROPDOWN } from '../identifiers'; -import InjectInput from '../input/Input'; -import events from '../utils/events'; - -const factory = (Input) => { - class Dropdown extends Component { - static propTypes = { - allowBlank: PropTypes.bool, - allowClear: PropTypes.bool, - clearTooltip: PropTypes.string, - auto: PropTypes.bool, - className: PropTypes.string, - disabled: PropTypes.bool, - error: PropTypes.string, - label: PropTypes.string, - labelKey: PropTypes.string, - name: PropTypes.string, - onBlur: PropTypes.func, - onChange: PropTypes.func, - onClick: PropTypes.func, - onFocus: PropTypes.func, - required: PropTypes.bool, - source: PropTypes.arrayOf(PropTypes.oneOfType([ - PropTypes.string, - PropTypes.object, - ])).isRequired, - template: PropTypes.func, - theme: PropTypes.shape({ - active: PropTypes.string, - disabled: PropTypes.string, - dropdown: PropTypes.string, - error: PropTypes.string, - errored: PropTypes.string, - field: PropTypes.string, - label: PropTypes.string, - required: PropTypes.string, - selected: PropTypes.string, - templateValue: PropTypes.string, - up: PropTypes.string, - value: PropTypes.string, - values: PropTypes.string, - }), - value: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number, - ]), - valueKey: PropTypes.string, - }; - - static defaultProps = { - auto: true, - className: '', - allowBlank: true, - allowClear: false, - clearTooltip: 'Clear', - disabled: false, - labelKey: 'label', - required: false, - valueKey: 'value', - }; - - state = { - active: false, - up: false, - }; - - componentWillUpdate(nextProps, nextState) { - if (!this.state.active && nextState.active) { - events.addEventsToDocument(this.getDocumentEvents()); - } - } - - componentDidUpdate(prevProps, prevState) { - if (prevState.active && !this.state.active) { - events.removeEventsFromDocument(this.getDocumentEvents()); - } - } - - componentWillUnmount() { - if (this.state.active) { - events.removeEventsFromDocument(this.getDocumentEvents()); - } - } - - getDocumentEvents = () => ({ - click: this.handleDocumentClick, - touchend: this.handleDocumentClick, - }); - - getSelectedItem = () => { - for (const item of this.props.source) { - if (item[this.props.valueKey] === this.props.value) return item; - } - return !this.props.allowBlank - ? this.props.source[0] - : undefined; - }; - - handleSelect = (item, event) => { - if (!this.props.disabled && this.props.onChange) { - if (this.props.name) event.target.name = this.props.name; - this.props.onChange(item, event); - this.close(); - } - }; - - handleClick = (event) => { - this.open(event); - events.pauseEvent(event); - if (this.props.onClick) this.props.onClick(event); - }; - - handleDocumentClick = (event) => { - if (this.state.active && !events.targetIsDescendant(event, ReactDOM.findDOMNode(this))) { - this.setState({ active: false }); - } - }; - - close = () => { - if (this.state.active) { - this.setState({ active: false }); - if (this.props.onBlur) this.props.onBlur(event); - } - } - - open = (event) => { - if (this.state.active) return; - const client = event.target.getBoundingClientRect(); - const screenHeight = window.innerHeight || document.documentElement.offsetHeight; - const up = this.props.auto ? client.top > ((screenHeight / 2) + client.height) : false; - this.setState({ active: true, up }); - if (this.props.onFocus) this.props.onFocus(event); - }; - - handleFocus = (event) => { - event.stopPropagation(); - if (!this.props.disabled) this.open(event); - }; - - handleBlur = (event) => { - event.stopPropagation(); - if (this.state.active) this.close(); - } - - renderTemplateValue(selected) { - const { theme } = this.props; - const className = classnames(theme.field, { - [theme.errored]: this.props.error, - [theme.disabled]: this.props.disabled, - [theme.required]: this.props.required, - }); - - return ( -
-
- {this.props.template(selected)} -
- {this.props.label - ? ( - - ) : null} - {this.props.error ? {this.props.error} : null} -
- ); - } - - renderValue = (item, idx) => { - const { labelKey, theme, valueKey } = this.props; - const className = classnames({ - [theme.selected]: item[valueKey] === this.props.value, - [theme.disabled]: item.disabled, - }); - return ( -
  • - {this.props.template ? this.props.template(item) : item[labelKey]} -
  • - ); - }; - - render() { - const { - allowBlank, allowClear, clearTooltip, auto, labelKey, required, onChange, onFocus, onBlur, // eslint-disable-line no-unused-vars - source, template, theme, valueKey, ...others - } = this.props; - const selected = this.getSelectedItem(); - const className = classnames(theme.dropdown, { - [theme.up]: this.state.up, - [theme.active]: this.state.active, - [theme.disabled]: this.props.disabled, - [theme.required]: this.props.required, - [theme.withclear]: allowClear && selected, - }, this.props.className); - - return ( -
    - {allowClear && selected ? this.props.onChange(null, e)}>clear : null} - - {template && selected ? this.renderTemplateValue(selected) : null} - -
    - ); - } - } - - return Dropdown; -}; - -const Dropdown = factory(InjectInput); -export default themr(DROPDOWN)(Dropdown); -export { factory as dropdownFactory }; -export { Dropdown }; diff --git a/components/dropdown/config.css b/components/dropdown/config.css deleted file mode 100644 index fa0a790e..00000000 --- a/components/dropdown/config.css +++ /dev/null @@ -1,10 +0,0 @@ -:root { - --dropdown-value-border-size: calc(var(--input-field-height) / 7); - --dropdown-color-white: var(--color-white); - --dropdown-color-primary: var(--color-primary); - --dropdown-color-primary-contrast: var(--color-primary-contrast); - --dropdown-color-disabled: color(var(--color-black) a(26%)); - --dropdown-value-hover-background: var(--palette-grey-200); - --dropdown-overflow-max-height: 45vh; - --dropdown-value-border-radius: calc(0.2 * var(--unit)); -} diff --git a/components/dropdown/index.d.ts b/components/dropdown/index.d.ts deleted file mode 100644 index 8e5196b2..00000000 --- a/components/dropdown/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Dropdown } from './Dropdown'; - -export { DropdownProps, DropdownTheme } from './Dropdown'; -export { Dropdown } -export default Dropdown; diff --git a/components/dropdown/index.js b/components/dropdown/index.js index 419b264a..0bed300a 100644 --- a/components/dropdown/index.js +++ b/components/dropdown/index.js @@ -1,11 +1,26 @@ +/* eslint-disable */ + import { themr } from 'react-css-themr'; -import { DROPDOWN } from '../identifiers'; -import { dropdownFactory } from './Dropdown'; +import { autocompleteFactory } from '../autocomplete'; +import { Chip } from '../chip'; import { Input } from '../input'; -import theme from './theme.css'; -const Dropdown = dropdownFactory(Input); -const ThemedDropdown = themr(DROPDOWN, theme)(Dropdown); +import theme from '../autocomplete/theme.css'; +import overrides from './overrides.css'; -export default ThemedDropdown; -export { ThemedDropdown as Dropdown }; +const overriddenTheme = { ...theme, inputInputElement: theme.inputInputElement+' '+overrides.inputInputElement }; + +const Autocomplete = autocompleteFactory(Chip, Input); +const ThemedAutocomplete = themr(AUTOCOMPLETE, overriddenTheme, { withRef: true })(Autocomplete); + +export const Dropdown = (props) => ; + +export default Dropdown; diff --git a/components/dropdown/overrides.css b/components/dropdown/overrides.css new file mode 100644 index 00000000..4e62bf98 --- /dev/null +++ b/components/dropdown/overrides.css @@ -0,0 +1,4 @@ +.inputInputElement { + caret-color: transparent; + cursor: pointer; +} diff --git a/components/dropdown/readme.md b/components/dropdown/readme.md deleted file mode 100644 index 7d7870a4..00000000 --- a/components/dropdown/readme.md +++ /dev/null @@ -1,73 +0,0 @@ -# Dropdown - -The Dropdown selects an option between multiple selections. The element displays the current state and a down arrow. When it is clicked, it displays the list of available options. - - -```jsx -import Dropdown from 'react-toolbox/lib/dropdown'; - -const countries = [ - { value: 'EN-gb', label: 'England' }, - { value: 'ES-es', label: 'Spain'}, - { value: 'TH-th', label: 'Thailand' }, - { value: 'EN-en', label: 'USA'} -]; - -class DropdownTest extends React.Component { - state = { value: 'ES-es' }; - - handleChange = (value) => { - this.setState({value: value}); - }; - - render () { - return ( - - ); - } -} -``` - -If you want to provide a theme via context, the component key is `RTDropdown`. - -## Properties - -| Name | Type | Default | Description | -|:-------------|:-----------|:--------|:------------| -| `allowBlank` | `Boolean` | `true` | If false the dropdown will preselect the first item if the supplied value matches none of the options' values.| -| `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.| -| `onBlur` | `Function` | | Callback function that is fired when the component is blurred.| -| `onChange` | `Function` | | Callback function that is fired when the component's value changes.| -| `onFocus` | `Function` | | Callback function that is fired when the component is focused.| -| `source` | `Array` | | Array of data objects with the data to represent in the dropdown.| -| `template` | `Function` | | Callback function that returns a JSX template to represent the element.| -| `value` | `String` | | Default value using JSON data.| -| `required` | `Boolean` | `false` | If true, the dropdown has a required attribute.| - -## Theming - -This component uses an `Input` under the covers. The theme object is passed down namespaced under `input` keyword. This means you can use the same theme classNames from `Input` component but namespaced with `input`. For example, to style the label you have to use `inputLabel` className. - -| Name | Description| -|:----------------|:-----------| -| `active` | Added to the root element when the dropdown is active.| -| `disabled` | Added to the root element when it's disabled.| -| `dropdown` | Root element class.| -| `error` | Used for the error element.| -| `errored` | Added to the inner wrapper if it's errored.| -| `field` | Used for the inner wrapper of the component.| -| `label` | Used for the the label element.| -| `selected` | Used to highlight the selected value.| -| `templateValue` | Used as a wrapper for the given template value.| -| `up` | Added to the root element when it's opening up.| -| `value` | Used for each value in the dropdown component.| -| `values` | Used for the list of values.| diff --git a/components/dropdown/theme.css b/components/dropdown/theme.css deleted file mode 100644 index ce7bb580..00000000 --- a/components/dropdown/theme.css +++ /dev/null @@ -1,180 +0,0 @@ -@import '../colors.css'; -@import '../variables.css'; -@import '../input/config.css'; -@import './config.css'; - -.dropdown { - position: relative; - - @apply --reset; - - &:not(.active) { - & > .values { - max-height: 0; - visibility: hidden; - } - } - - &.active { - & > .label, - & > .value { - opacity: 0.5; - } - - & > .values { - box-shadow: var(--zdepth-shadow-1); - max-height: var(--dropdown-overflow-max-height); - visibility: visible; - } - } - - &:not(.up) > .values { - bottom: auto; - top: 0; - } - - &.up > .values { - bottom: 0; - top: auto; - } - - &.disabled { - cursor: normal; - pointer-events: none; - } - - &.withclear input { - text-indent: 28px !important; - } -} - -.value { - & > input { - cursor: pointer; - } - - &::after { - border-left: var(--dropdown-value-border-size) solid transparent; - border-right: var(--dropdown-value-border-size) solid transparent; - border-top: var(--dropdown-value-border-size) solid var(--input-text-bottom-border-color); - content: ''; - height: 0; - pointer-events: none; - position: absolute; - right: var(--input-chevron-offset); - top: 50%; - transition: transform var(--animation-duration) var(--animation-curve-default); - width: 0; - } -} - -.field { - cursor: pointer; - padding: var(--input-padding) 0; - position: relative; - - &.errored { - padding-bottom: 0; - - & > .label { - color: var(--input-text-error-color); - } - - & > .templateValue { - border-bottom: 1px solid var(--input-text-error-color); - } - - & > .label > .required { - color: var(--input-text-error-color); - } - } - - &.disabled { - cursor: normal; - pointer-events: none; - - & > .templateValue { - border-bottom-style: dotted; - opacity: 0.7; - } - } -} - -.templateValue { - background-color: var(--input-text-background-color); - border-bottom: 1px solid var(--input-text-bottom-border-color); - color: var(--color-text); - min-height: var(--input-field-height); - padding: var(--input-field-padding) 0; - position: relative; -} - -.label { - color: var(--input-text-label-color); - font-size: var(--input-label-font-size); - left: 0; - line-height: var(--input-field-font-size); - position: absolute; - top: var(--input-focus-label-top); - - & .required { - color: var(--input-text-error-color); - } -} - -.error { - color: var(--input-text-error-color); - font-size: var(--input-label-font-size); - line-height: var(--input-underline-height); - margin-bottom: calc(-1 * var(--input-underline-height)); -} - -.values { - background-color: var(--dropdown-color-white); - border-radius: var(--dropdown-value-border-radius); - list-style: none; - margin: 0; - overflow-y: auto; - padding: 0; - position: absolute; - transition-duration: var(--animation-duration); - transition-property: max-height, box-shadow; - transition-timing-function: var(--animation-curve-default); - width: 100%; - z-index: var(--z-index-high); - - & > * { - cursor: pointer; - overflow: hidden; - padding: var(--unit); - position: relative; - - &:hover:not(.disabled) { - background-color: var(--dropdown-value-hover-background); - } - - &.selected { - color: var(--dropdown-color-primary); - } - - &.disabled { - color: var(--dropdown-color-disabled); - cursor: not-allowed; - } - } - - &::-webkit-scrollbar { - height: 0; - width: 0; - } -} - -.clear { - cursor: pointer; - display: block; - left: -4px; - padding: 4px; - position: absolute; - top: 12px; - z-index: 10; -} diff --git a/package.json b/package.json index 565e5449..3ed9fcf6 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "react-toolbox", "description": "A set of React components implementing Google's Material Design specification with the power of CSS Modules.", "homepage": "http://www.react-toolbox.io", - "version": "2.0.0-beta.22", + "version": "2.0.0-beta.23", "main": "./lib", "module": "./components", "author": {