Merge remote-tracking branch 'upstream/dev' into 1.3.1-autocomplete-improvements

# Conflicts:
#	components/autocomplete/Autocomplete.js
old
Craig Cartmell 2016-12-06 12:42:50 +00:00
commit 67d817d43b
9 changed files with 86 additions and 14 deletions

View File

@ -174,7 +174,7 @@ const factory = (Chip, Input) => {
query (key) {
let query_value = '';
if (!this.props.multiple && key) {
const source_value = this.source().get(key);
const source_value = this.source().get(`${key}`);
query_value = source_value ? source_value : key;
}
return query_value;
@ -194,7 +194,7 @@ const factory = (Chip, Input) => {
suggestions () {
let suggest = new Map();
const rawQuery = this.state.query || (this.props.multiple ? '' : this.props.value);
const query = (rawQuery || '').toLowerCase().trim();
const query = (`${rawQuery}`).toLowerCase().trim();
const values = this.values();
const source = this.source();
@ -242,7 +242,7 @@ const factory = (Chip, Input) => {
if (src.hasOwnProperty('length')) {
return new Map(src.map((item) => Array.isArray(item) ? [...item] : [item, item]));
} else {
return new Map(Object.keys(src).map((key) => [key, src[key]]));
return new Map(Object.keys(src).map((key) => [`${key}`, src[key]]));
}
}
@ -254,11 +254,12 @@ const factory = (Chip, Input) => {
}
const valueMap = new Map();
const stringVals = vals.map(v => `${v}`);
for (const [k, v] of this.source()) {
if ((Array.isArray(vals) && vals.indexOf(k) !== -1) || (k in vals)) {
valueMap.set(k, v);
}
if (stringVals.indexOf(k) !== -1) valueMap.set(k, v);
}
return valueMap;
}

View File

@ -8,7 +8,8 @@ const factory = (Avatar) => {
const Chip = ({children, className, deletable, onDeleteClick, theme, ...other}) => {
let hasAvatar = false;
if (React.Children.count(children)) {
const firstChild = children[0];
const flatChildren = React.Children.toArray(children);
const firstChild = flatChildren[0];
hasAvatar = firstChild && firstChild.type && firstChild.type === Avatar;
}

View File

@ -0,0 +1,53 @@
import expect from 'expect';
import React from 'react';
import ReactDOM from 'react-dom';
import ReactTestUtils from 'react-addons-test-utils';
import { themr } from 'react-css-themr';
import { CHIP } from '../../identifiers.js';
import { chipFactory } from '../Chip';
import { tooltipFactory } from '../../tooltip';
const Avatar = ({title}) => <span>{title}</span>; // eslint-disable-line react/prop-types
const Chip = themr(CHIP)(chipFactory(Avatar));
describe('Chip', function () {
describe('with avatar', function () {
it('adds the avatar class to the element', function () {
const tree = ReactTestUtils.renderIntoDocument(
<Chip theme={{avatar: 'avatar-class'}}>
<Avatar title='Test'/>
<span>Test</span>
</Chip>
);
const chip = ReactTestUtils.findRenderedComponentWithType(tree, Chip);
const chipNode = ReactDOM.findDOMNode(chip);
expect(chipNode.className).toMatch(/\bavatar-class\b/);
});
it('works with non-flat children', function () {
const TooltippedChip = tooltipFactory()(Chip);
const tree = ReactTestUtils.renderIntoDocument(
<TooltippedChip theme={{avatar: 'avatar-class'}} tooltip='Test tooltip'>
<Avatar title='Test'/>
<span>Test</span>
</TooltippedChip>
);
const chip = ReactTestUtils.findRenderedComponentWithType(tree, Chip);
const chipNode = ReactDOM.findDOMNode(chip);
expect(chipNode.className).toMatch(/\bavatar-class\b/);
});
});
describe('without avatar', function () {
it('does not add avatar class to the element', function () {
const tree = ReactTestUtils.renderIntoDocument(
<Chip theme={{avatar: 'avatar-class'}}>
<span>Test</span>
</Chip>
);
const chip = ReactTestUtils.findRenderedComponentWithType(tree, Chip);
const chipNode = ReactDOM.findDOMNode(chip);
expect(chipNode.className).toNotMatch(/\bavatar-class\b/);
});
});
});

View File

@ -202,6 +202,8 @@ const factory = (Input) => {
readOnly
ref={node => { this.inputNode = node && node.getWrappedInstance(); }}
type={template && selected ? 'hidden' : null}
theme={theme}
themeNamespace="input"
value={selected && selected.label ? selected.label : ''}
/>
{template && selected ? this.renderTemplateValue(selected) : null}

View File

@ -55,6 +55,8 @@ If you want to provide a theme via context, the component key is `RTDropdown`.
## 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.|

View File

@ -9,7 +9,10 @@ const types = ['auto', 'normal', 'large'];
const factory = (ListItemText) => {
class ListItemContent extends Component {
static propTypes = {
caption: PropTypes.string,
caption: PropTypes.oneOfType([
PropTypes.string,
PropTypes.node
]),
children: PropTypes.any,
legend: PropTypes.string,
theme: PropTypes.shape({

View File

@ -152,7 +152,7 @@ const tooltipFactory = (options = {}) => {
};
handleMouseEnter = (event) => {
this.activate(this.calculatePosition(event.target));
this.activate(this.calculatePosition(event.currentTarget));
if (this.props.onMouseEnter) this.props.onMouseEnter(event);
};
@ -167,7 +167,7 @@ const tooltipFactory = (options = {}) => {
}
if (this.props.tooltipShowOnClick && !this.state.active) {
this.activate(this.calculatePosition(event.target));
this.activate(this.calculatePosition(event.currentTarget));
}
if (this.props.onClick) this.props.onClick(event);
@ -193,6 +193,8 @@ const tooltipFactory = (options = {}) => {
[theme[positionClass]]: theme[positionClass]
});
const isNative = typeof ComposedComponent === 'string';
return (
<ComposedComponent
{...other}
@ -200,7 +202,7 @@ const tooltipFactory = (options = {}) => {
onClick={this.handleClick}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
theme={theme}
{...isNative ? {} : {theme}}
>
{children ? children : null}
{visible && (

View File

@ -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.com",
"version": "1.3.1",
"version": "1.3.2",
"main": "./lib",
"author": {
"name": "React Toolbox Team",

View File

@ -2,6 +2,8 @@ import React from 'react';
import Button from '../../components/button';
import Input from '../../components/input';
import Tooltip from '../../components/tooltip';
import Chip from '../../components/chip';
import Avatar from '../../components/avatar';
const TooltipButton = Tooltip(Button);
const TooltipInput = Tooltip(Input);
@ -9,6 +11,8 @@ const TooltipStrong = Tooltip(({children, ...other}) => {
delete other.theme;
return <strong {...other}>{children}</strong>;
});
const TooltipStrongDirect = Tooltip('strong');
const ChipTooltip = Tooltip(Chip);
const TooltipTest = () => (
<section>
@ -22,14 +26,18 @@ const TooltipTest = () => (
floating
tooltip={<div><p>An example with</p><p>Multiline!</p></div>}
/>
<ChipTooltip tooltip='Dolor sit amet' tooltipPosition='top'>
<Avatar icon='home'/>
<span>Tooltip in a chip</span>
</ChipTooltip>
<TooltipInput tooltip='lorem ipsum...' />
<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>
<TooltipStrongDirect tooltip='This is a auto show tooltip' tooltipShowOnClick>
oh hai
</TooltipStrong>
</TooltipStrongDirect>
{' '}. This is useful for mobile!
</p>
</section>