Merge remote-tracking branch 'remotes/upstream/dev' into dev

# Conflicts:
#	components/autocomplete/Autocomplete.js
old
Craig Cartmell 2016-12-01 11:46:00 +00:00
commit 0ca01a8395
15 changed files with 80 additions and 20 deletions

View File

@ -177,6 +177,8 @@ render(
A couple of things here. First you need to use raw components to get this styles properly applied. Second, you have to add dependency themes by yourself. For example, the `Button` requires `Ripple` so you have to provide styles for both of them. A couple of things here. First you need to use raw components to get this styles properly applied. Second, you have to add dependency themes by yourself. For example, the `Button` requires `Ripple` so you have to provide styles for both of them.
Also, recall that all components accepts a theme verifying required classNames but there may be some missing. If any property is missing you can check the selectors you want to override straight in the DevTools.
## Roboto Font and Material Design Icons ## Roboto Font and Material Design Icons
React Toolbox assumes that you are importing [Roboto Font](https://fonts.google.com/specimen/Roboto) and [Material Design Icons](https://material.io/icons/). React Toolbox assumes that you are importing [Roboto Font](https://fonts.google.com/specimen/Roboto) and [Material Design Icons](https://material.io/icons/).
@ -207,6 +209,7 @@ To start the documentation site locally, you'll need to install the dependencies
``` ```
$ git clone https://github.com/react-toolbox/react-toolbox.git $ git clone https://github.com/react-toolbox/react-toolbox.git
$ cd react-toolbox/
$ npm install $ npm install
$ cd docs/ $ cd docs/
$ npm install $ npm install
@ -215,6 +218,10 @@ $ npm start
Local documentation will then be available at `http://localhost:8081/`. Local documentation will then be available at `http://localhost:8081/`.
## Extensions
We don't officially support components that are not covered by [Google Material Design](https://www.google.com/design/spec/material-design/introduction.html). If you want to implement some complementary component feel free to open a PR adding your a link in this section. For now you can check [on github: react-toolbox-additions](https://github.com/MaximKomlev/react-toolbox-additions) and [on npm: react-toolbox-additions](https://www.npmjs.com/package/react-toolbox-additions).
## License ## License
This project is licensed under the terms of the [MIT license](https://github.com/react-toolbox/react-toolbox/blob/master/LICENSE). This project is licensed under the terms of the [MIT license](https://github.com/react-toolbox/react-toolbox/blob/master/LICENSE).

View File

@ -54,8 +54,8 @@ const factory = (Chip, Input) => {
keepFocusOnChange: false, keepFocusOnChange: false,
multiple: true, multiple: true,
selectedPosition: 'above', selectedPosition: 'above',
showSuggestionsWhenValueIsSet: false,
showSelectedWhenNotInSource: false, showSelectedWhenNotInSource: false,
showSuggestionsWhenValueIsSet: false,
source: {}, source: {},
suggestionMatch: 'start' suggestionMatch: 'start'
}; };
@ -108,9 +108,9 @@ const factory = (Chip, Input) => {
} }
}; };
handleMouseDown = () => { handleMouseDown = (event) => {
this.selectOrCreateActiveItem(); this.selectOrCreateActiveItem(event);
}; }
handleQueryBlur = (event) => { handleQueryBlur = (event) => {
if (this.state.focus) this.setState({focus: false}); if (this.state.focus) this.setState({focus: false});
@ -140,7 +140,7 @@ const factory = (Chip, Input) => {
} }
if (event.which === 13) { if (event.which === 13) {
this.selectOrCreateActiveItem(); this.selectOrCreateActiveItem(event);
} }
}; };
@ -180,7 +180,7 @@ const factory = (Chip, Input) => {
return query_value; return query_value;
} }
selectOrCreateActiveItem () { selectOrCreateActiveItem (event) {
let target = this.state.active; let target = this.state.active;
if (!target) { if (!target) {
target = this.props.allowCreate target = this.props.allowCreate

View File

@ -9,6 +9,8 @@ $button-accent-color-hover: rgba($color-accent, .2) !default;
$button-accent-color: $color-accent !default; $button-accent-color: $color-accent !default;
$button-disabled-text-color: rgba($color-black, 0.26) !default; $button-disabled-text-color: rgba($color-black, 0.26) !default;
$button-disabled-background-color: rgba($color-black, 0.12) !default; $button-disabled-background-color: rgba($color-black, 0.12) !default;
$button-disabled-text-color-inverse: rgba($color-white, 0.54) !default;
$button-disabled-background-inverse: rgba($color-white, 0.08) !default;
$button-border-radius: 0.2 * $unit !default; $button-border-radius: 0.2 * $unit !default;
$button-floating-font-size: $unit * 2.4 !default; $button-floating-font-size: $unit * 2.4 !default;
$button-floating-height: $unit * 5.6 !default; $button-floating-height: $unit * 5.6 !default;

View File

@ -178,5 +178,10 @@
} }
} }
.neutral.inverse[disabled] {
color: $button-disabled-text-color-inverse;
background-color: $button-disabled-background-inverse;
}
@include btn-colors("primary", $button-primary-color-contrast, $button-primary-color, $button-primary-color-hover); @include btn-colors("primary", $button-primary-color-contrast, $button-primary-color, $button-primary-color-hover);
@include btn-colors("accent", $button-accent-color-contrast, $button-accent-color, $button-accent-color-hover); @include btn-colors("accent", $button-accent-color-contrast, $button-accent-color, $button-accent-color-hover);

View File

@ -18,6 +18,8 @@ const factory = (Check) => {
]), ]),
name: PropTypes.string, name: PropTypes.string,
onChange: PropTypes.func, onChange: PropTypes.func,
onMouseEnter: PropTypes.func,
onMouseLeave: PropTypes.func,
style: PropTypes.object, style: PropTypes.object,
theme: PropTypes.shape({ theme: PropTypes.shape({
disabled: PropTypes.string, disabled: PropTypes.string,
@ -49,17 +51,25 @@ const factory = (Check) => {
} }
render () { render () {
const { checked, children, disabled, label, style, theme, ...others } = this.props; const { checked, children, disabled, label, name, style, onChange, // eslint-disable-line
onMouseEnter, onMouseLeave, theme, ...others } = this.props;
const className = classnames(theme.field, { const className = classnames(theme.field, {
[theme.disabled]: this.props.disabled [theme.disabled]: this.props.disabled
}, this.props.className); }, this.props.className);
return ( return (
<label {...others} data-react-toolbox='checkbox' className={className}> <label
data-react-toolbox='checkbox'
className={className}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<input <input
{...others}
checked={checked} checked={checked}
className={theme.input} className={theme.input}
disabled={disabled} disabled={disabled}
name={name}
onChange={() => {}} onChange={() => {}}
onClick={this.handleToggle} onClick={this.handleToggle}
ref={node => { this.inputNode = node; }} ref={node => { this.inputNode = node; }}

View File

@ -79,6 +79,7 @@ If you want to provide a theme via context, the component key is `RTDatePicker`.
| `disabled` | Added to day element when day is disabled.| | `disabled` | Added to day element when day is disabled.|
| `header` | Used for the dialog header,.| | `header` | Used for the dialog header,.|
| `input` | Used for Input element that opens the picker.| | `input` | Used for Input element that opens the picker.|
| `label` | Used for the label element.|
| `month` | Used for the month root element.| | `month` | Used for the month root element.|
| `monthsDisplay` | Added to the root dialog when months are displayed.| | `monthsDisplay` | Added to the root dialog when months are displayed.|
| `next` | Used for the next month icon.| | `next` | Used for the next month icon.|

View File

@ -80,7 +80,7 @@ const factory = (Input) => {
touchend: this.handleDocumentClick touchend: this.handleDocumentClick
}); });
open = () => { open = (event) => {
const client = event.target.getBoundingClientRect(); const client = event.target.getBoundingClientRect();
const screenHeight = window.innerHeight || document.documentElement.offsetHeight; const screenHeight = window.innerHeight || document.documentElement.offsetHeight;
const up = this.props.auto ? client.top > ((screenHeight / 2) + client.height) : false; const up = this.props.auto ? client.top > ((screenHeight / 2) + client.height) : false;
@ -101,7 +101,7 @@ const factory = (Input) => {
}; };
handleClick = (event) => { handleClick = (event) => {
this.open(); this.open(event);
events.pauseEvent(event); events.pauseEvent(event);
if (this.props.onClick) this.props.onClick(event); if (this.props.onClick) this.props.onClick(event);
}; };
@ -162,7 +162,7 @@ const factory = (Input) => {
handleFocus = event => { handleFocus = event => {
event.stopPropagation(); event.stopPropagation();
if (!this.props.disabled) this.open(); if (!this.props.disabled) this.open(event);
if (this.props.onFocus) this.props.onFocus(event); if (this.props.onFocus) this.props.onFocus(event);
}; };

View File

@ -108,6 +108,10 @@ interface DropdownProps extends ReactToolbox.Props {
* Default value using JSON data. * Default value using JSON data.
*/ */
value?: string | number; value?: string | number;
/**
* If true, the dropdown has a required attribute.
*/
required?: boolean;
} }
export class Dropdown extends React.Component<DropdownProps, {}> { } export class Dropdown extends React.Component<DropdownProps, {}> { }

View File

@ -20,6 +20,8 @@ const factory = (Radio) => {
onBlur: PropTypes.func, onBlur: PropTypes.func,
onChange: PropTypes.func, onChange: PropTypes.func,
onFocus: PropTypes.func, onFocus: PropTypes.func,
onMouseEnter: PropTypes.func,
onMouseLeave: PropTypes.func,
theme: PropTypes.shape({ theme: PropTypes.shape({
disabled: PropTypes.string, disabled: PropTypes.string,
field: PropTypes.string, field: PropTypes.string,
@ -50,20 +52,24 @@ const factory = (Radio) => {
} }
render () { render () {
const { checked, children, className, disabled, label, onChange, theme, ...others } = this.props; // eslint-disable-line const { checked, children, className, disabled, label, name, onChange, // eslint-disable-line
onMouseEnter, onMouseLeave, theme, ...others } = this.props;
const _className = classnames(theme[this.props.disabled ? 'disabled' : 'field'], className); const _className = classnames(theme[this.props.disabled ? 'disabled' : 'field'], className);
return ( return (
<label <label
{...others}
data-react-toolbox='radio-button' data-react-toolbox='radio-button'
className={_className} className={_className}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
> >
<input <input
{...others}
checked={checked} checked={checked}
className={theme.input} className={theme.input}
disabled={disabled} disabled={disabled}
onClick={this.handleClick} name={name}
onChange={() => {}} onChange={() => {}}
onClick={this.handleClick}
ref={node => { this.inputNode = node; }} ref={node => { this.inputNode = node; }}
type='radio' type='radio'
/> />

View File

@ -41,7 +41,7 @@ interface TabsProps extends ReactToolbox.Props {
index?: number; index?: number;
/** /**
* `unmounted` mode will not mount the tab content of inactive tabs. * `unmounted` mode will not mount the tab content of inactive tabs.
* `display` mode will mount but hide inactive tabs. * `display` mode will mount but hide inactive tabs.
* Consider holding state outside of the Tabs component before using `display` mode * Consider holding state outside of the Tabs component before using `display` mode
* @default unmounted * @default unmounted
*/ */
@ -50,6 +50,10 @@ interface TabsProps extends ReactToolbox.Props {
* If True, the tabs will have an inverse style. * If True, the tabs will have an inverse style.
*/ */
inverse?: boolean; inverse?: boolean;
/**
* If True, the tabs will be fixed, covering the whole width.
*/
fixed?: boolean;
/** /**
* Callback function that is fired when the tab changes. * Callback function that is fired when the tab changes.
*/ */

View File

@ -47,7 +47,7 @@ const factory = (Dialog) => {
displayTime: new Date(this.props.value.getTime()) displayTime: new Date(this.props.value.getTime())
}; };
componentWillUpdate (nextProps) { componentWillReceiveProps (nextProps) {
if (nextProps.value.getTime() !== this.state.displayTime.getTime()) { if (nextProps.value.getTime() !== this.state.displayTime.getTime()) {
this.setState({ displayTime: new Date(nextProps.value.getTime()) }); this.setState({ displayTime: new Date(nextProps.value.getTime()) });
} }

View File

@ -19,6 +19,7 @@ const defaults = {
className: '', className: '',
delay: 0, delay: 0,
hideOnClick: true, hideOnClick: true,
showOnClick: false,
position: POSITION.VERTICAL, position: POSITION.VERTICAL,
theme: {} theme: {}
}; };
@ -28,6 +29,7 @@ const tooltipFactory = (options = {}) => {
className: defaultClassName, className: defaultClassName,
delay: defaultDelay, delay: defaultDelay,
hideOnClick: defaultHideOnClick, hideOnClick: defaultHideOnClick,
showOnClick: defaultShowOnClick,
position: defaultPosition, position: defaultPosition,
theme: defaultTheme theme: defaultTheme
} = {...defaults, ...options}; } = {...defaults, ...options};
@ -51,14 +53,16 @@ const tooltipFactory = (options = {}) => {
]), ]),
tooltipDelay: PropTypes.number, tooltipDelay: PropTypes.number,
tooltipHideOnClick: PropTypes.bool, tooltipHideOnClick: PropTypes.bool,
tooltipPosition: PropTypes.oneOf(Object.keys(POSITION).map(key => POSITION[key])) tooltipPosition: PropTypes.oneOf(Object.keys(POSITION).map(key => POSITION[key])),
tooltipShowOnClick: PropTypes.bool
}; };
static defaultProps = { static defaultProps = {
className: defaultClassName, className: defaultClassName,
tooltipDelay: defaultDelay, tooltipDelay: defaultDelay,
tooltipHideOnClick: defaultHideOnClick, tooltipHideOnClick: defaultHideOnClick,
tooltipPosition: defaultPosition tooltipPosition: defaultPosition,
tooltipShowOnClick: defaultShowOnClick
}; };
state = { state = {
@ -158,7 +162,14 @@ const tooltipFactory = (options = {}) => {
}; };
handleClick = (event) => { handleClick = (event) => {
if (this.props.tooltipHideOnClick) this.deactivate(); if (this.props.tooltipHideOnClick && this.state.active) {
this.deactivate();
}
if (this.props.tooltipShowOnClick && !this.state.active) {
this.activate(this.calculatePosition(event.target));
}
if (this.props.onClick) this.props.onClick(event); if (this.props.onClick) this.props.onClick(event);
}; };
@ -173,6 +184,7 @@ const tooltipFactory = (options = {}) => {
tooltipDelay, //eslint-disable-line no-unused-vars tooltipDelay, //eslint-disable-line no-unused-vars
tooltipHideOnClick, //eslint-disable-line no-unused-vars tooltipHideOnClick, //eslint-disable-line no-unused-vars
tooltipPosition, //eslint-disable-line no-unused-vars tooltipPosition, //eslint-disable-line no-unused-vars
tooltipShowOnClick, //eslint-disable-line no-unused-vars
...other ...other
} = this.props; } = this.props;

View File

@ -38,6 +38,7 @@ In any component you decorate with the Tooltip you'd get some additional props:
| `tooltipDelay` | `Number` | | Amount of time in miliseconds spent before the tooltip is visible.| | `tooltipDelay` | `Number` | | Amount of time in miliseconds spent before the tooltip is visible.|
| `tooltipHideOnClick` | `Boolean` | `true` | If true, the Tooltip hides after a click in the host component.| | `tooltipHideOnClick` | `Boolean` | `true` | If true, the Tooltip hides after a click in the host component.|
| `tooltipPosition` | `String` | `vertical` | Determines the position of the tooltip. It can be automatic with `vertical` and `horizontal` values or forced with `bottom`, `top`, `left` or `right`.| | `tooltipPosition` | `String` | `vertical` | Determines the position of the tooltip. It can be automatic with `vertical` and `horizontal` values or forced with `bottom`, `top`, `left` or `right`.|
| `tooltipShowOnClick` | `Boolean` | `false` | Determines the tooltip should be toggled when clicked. This is useful for mobile where there is no mouse enter.|
## Theming ## Theming

View File

@ -2,7 +2,7 @@
"name": "react-toolbox", "name": "react-toolbox",
"description": "A set of React components implementing Google's Material Design specification with the power of CSS Modules.", "description": "A set of React components implementing Google's Material Design specification with the power of CSS Modules.",
"homepage": "http://www.react-toolbox.com", "homepage": "http://www.react-toolbox.com",
"version": "1.2.5", "version": "1.3.1",
"main": "./lib", "main": "./lib",
"author": { "author": {
"name": "React Toolbox Team", "name": "React Toolbox Team",

View File

@ -24,6 +24,14 @@ const TooltipTest = () => (
/> />
<TooltipInput tooltip='lorem ipsum...' /> <TooltipInput tooltip='lorem ipsum...' />
<p>Lorem ipsum dolor sit amet, <TooltipStrong tooltip='This is a auto show tooltip'>consectetur</TooltipStrong> adipiscing elit.</p> <p>Lorem ipsum dolor sit amet, <TooltipStrong tooltip='This is a auto show tooltip'>consectetur</TooltipStrong> adipiscing elit.</p>
<p>
Click this next word to show and hide on click:
{' '}
<TooltipStrong tooltip='This is a auto show tooltip' tooltipShowOnClick>
oh hai
</TooltipStrong>
{' '}. This is useful for mobile!
</p>
</section> </section>
); );