Skip to content

Commit

Permalink
Merge branch 'master' into tokenPage
Browse files Browse the repository at this point in the history
  • Loading branch information
iamigo committed Dec 15, 2016
2 parents ce9a6b2 + 90eca9f commit 70236ba
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 23 deletions.
46 changes: 43 additions & 3 deletions tests/view/components/dropdown.js
Expand Up @@ -16,6 +16,7 @@ import { mount } from 'enzyme';
import Dropdown from '../../../view/admin/components/common/Dropdown.js';

describe('Dropdown component tests', () => {
const ZERO = 0;
const ONE = 1;
const DUMMY_STRING = 'COOL';
const DUMMY_FUNCTION = () => {};
Expand All @@ -24,9 +25,10 @@ describe('Dropdown component tests', () => {
* Sets up the component with dummy prop values.
* @param {Object} propAddons Optional object specifying
* overrides to the default props
* @param {ReactElem} childElems The react elements
* @returns {Object} The rendered component
*/
function setup(propAddons) {
function setup(propAddons, childElems) {
const defaultProps = {
options: [],
dropDownStyle: {},
Expand All @@ -38,17 +40,55 @@ describe('Dropdown component tests', () => {
showSearchIcon: false,
onAddNewButton: DUMMY_FUNCTION,
onClickItem: DUMMY_FUNCTION,
showInputElem: false, //default
};
// update props as needed
if (propAddons) {
Object.assign(defaultProps, propAddons);
}
// use monut to test all lifecycle methods, and children
const enzymeWrapper = mount(<Dropdown {...defaultProps} />);

const enzymeWrapper = mount(
<Dropdown {...defaultProps}>{childElems}</Dropdown>
);
return enzymeWrapper;
}

it('calling close from props closes the dropdown', () => {
const enzymeWrapper = setup();
const instance = enzymeWrapper.instance();
instance.handleFocus(); // show the dropdown
expect(instance.state.open).to.equal(true);
enzymeWrapper.setProps({ close: true });
expect(instance.state.open).to.equal(false);
});

it('when showInputElem is false and there are ' +
'child element(s), there is no input rendered', () => {
// by default, showInputElem = false
const enzymeWrapper = setup({}, <div id='lookForMe'/>);
expect(enzymeWrapper.find('.slds-lookup__search-input'))
.to.have.length(ZERO);
});

it('even when showInputElem is false, if given no child elements, ' +
'input is rendered', () => {
// by default, showInputElem = false
const enzymeWrapper = setup();
expect(enzymeWrapper.find('.slds-lookup__search-input'))
.to.have.length(ONE);
});

it('when showInputElem is true, an input is rendered with ' +
'child element(s)', () => {
// by default, showInputElem = false
const enzymeWrapper = setup(
{ showInputElem: true },
<div id='lookForMe'/>);
expect(enzymeWrapper.find('.slds-lookup__search-input'))
.to.have.length(ONE);
expect(enzymeWrapper.find('#lookForMe')).to.have.length(ONE);
});

it('input is rendered by default', () => {
const enzymeWrapper = setup();
expect(enzymeWrapper.find('.slds-lookup__search-input'))
Expand Down
42 changes: 30 additions & 12 deletions view/admin/components/common/Dropdown.js
Expand Up @@ -72,6 +72,9 @@ class Dropdown extends React.Component {
if (nextProps.options !== this.props.options) {
this.setState({ data: nextProps.options });
}
if (nextProps.close) {
this.handleClose();
}
}
render () {
const {
Expand All @@ -84,6 +87,8 @@ class Dropdown extends React.Component {
showSearchIcon,
onAddNewButton,
onClickItem,
showInputElem,
children, // react elements
} = this.props;
const { data } = this.state;
let outputUL = '';
Expand All @@ -94,7 +99,8 @@ class Dropdown extends React.Component {
return (
<li key={ optionsName }
onClick={ onClickItem }
className='slds-lookup__item-action slds-media slds-media--center'>
className={'slds-lookup__item-action ' +
'slds-media slds-media--center'}>
<svg aria-hidden='true'
className={'slds-icon slds-icon-standard-account' +
' slds-icon--small slds-media__figure'}>
Expand All @@ -120,20 +126,27 @@ class Dropdown extends React.Component {
onFocus={ this.handleFocus.bind(this) }
onKeyUp={ this.handleKeyUp.bind(this) }
/>;
// if there's child elements, render them
// if there's child elements and showInputElem is true, show inputElem
// if there's no child elements, show inputElem
return (
<div
title={ title || 'dropdown' }
className='slds-form-element__control slds-grid slds-wrap slds-grid--pull-padded'
ref='dropdown'
title={ title || 'dropdown' }
className={'slds-form-element__control ' +
'slds-grid slds-wrap slds-grid--pull-padded'}
>
<div className="slds-col--padded slds-size--1-of-1">
{ this.props.children }
{ inputElem }
{ !children && inputElem}
{ children }
{ (children && showInputElem) && inputElem }
</div>
<div className={'slds-dropdown-trigger--click ' +
'slds-align-middle slds-m-right--xx-small slds-shrink-none slds-is-open'}>
{ showSearchIcon && <svg aria-hidden='true' className='slds-button__icon'>
<use xlinkHref='../static/icons/utility-sprite/svg/symbols.svg#search'></use>
<div className={'slds-dropdown-trigger--click slds-align-middle ' +
'slds-m-right--xx-small slds-shrink-none slds-is-open'}>
{ showSearchIcon &&
<svg aria-hidden='true' className='slds-button__icon'>
<use xlinkHref={'../static/icons/utility-sprite/' +
'svg/symbols.svg#search'}></use>
</svg>}
{ this.state.open &&
<div
Expand All @@ -149,13 +162,16 @@ class Dropdown extends React.Component {
{ onAddNewButton && <div>
<a role='button'
onClick={ onAddNewButton }
className='slds-lookup__item-action slds-lookup__item-action--label'>
className={'slds-lookup__item-action ' +
'slds-lookup__item-action--label'}>
<span className='lookup__item-action-label'>
<svg aria-hidden='true' className={'slds-icon ' +
'slds-icon--x-small slds-icon-text-default'}>
<use xlinkHref='../static/icons/utility-sprite/svg/symbols.svg#add'></use>
<use xlinkHref={'../static/icons/utility-sprite/' +
'svg/symbols.svg#add'}></use>
</svg>
<span className='slds-truncate'>{ newButtonText || 'Add New' }</span>
<span className='slds-truncate'
>{ newButtonText || 'Add New' }</span>
</span>
</a>
</div>}
Expand All @@ -180,6 +196,8 @@ Dropdown.propTypes = {
onClickItem: PropTypes.func.isRequired,
children: PropTypes.element,
showSearchIcon: PropTypes.bool,
showInputElem: PropTypes.bool,
close: PropTypes.bool, // if true, close dropdown
};

export default Dropdown;
21 changes: 13 additions & 8 deletions view/perspective/CreatePerspective.js
Expand Up @@ -236,10 +236,14 @@ class CreatePerspective extends React.Component {
} else {
newState[dropdownTitle] = [valueToAppend];
}
} else if (valueInState) {
// for single pill fields with non-empty value,
} else { // single pill input
// close the dropdown
config.close = true;
// field had value,
// add replaced value into options
config.options.push(valueInState);
if (valueInState) {
config.options.push(valueInState);
}
}
// remove selected option from available options in dropdown
const arr = filteredArray(config.options || [], valueToAppend);
Expand Down Expand Up @@ -312,24 +316,25 @@ class CreatePerspective extends React.Component {
}
// if display value is array, use multi pill
// else single pill
// showInputElem {Bool} if true, show additional
// input near dropdown
const showInputElem = dropdownConfig[key].isArray;
if (value.length) {
if (dropdownConfig[key].isArray) {
pillOutput = <Pill
title={ value }
onRemove={this.deletePill}
/>;
} else if (typeof value === 'string') {
// Do not show input when there's pills
pillOutput = <Pill
title={ [value] }
icon={ accountIcon }
title={ [value] }
onRemove={this.deletePill}
/>;
}
}
// show input below dropdown, to filter
const _config = Object.assign(
dropdownConfig[key], { showInputWithContent: true },
);
const _config = Object.assign(dropdownConfig[key], { showInputElem });
dropdownObj[key] = (
<Dropdown { ..._config } >
{ pillOutput }
Expand Down

0 comments on commit 70236ba

Please sign in to comment.