Skip to content

Commit

Permalink
get MagicSelect roughly working #1
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Pollock committed Jul 5, 2018
1 parent 5577685 commit d6b879e
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 34 deletions.
147 changes: 118 additions & 29 deletions src/components/fields/magic-select/MagicSelect.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,149 @@
import React from 'react';
import {fieldInnerPropTypes, inputTypeProp, onValueChangePropType, optionsShapeProp, valuePropType} from '../propTypes';
import {
onValueChangePropType,
optionsShapeProp,
valuePropType
} from '../propTypes';
import classNames from 'classnames';
import Autocomplete from 'react-autocomplete'
import PropTypes from "prop-types";

/**
* Encapsulates a complete Magic Select field
*/
export const MagicSelect = (props) => {
export class MagicSelect extends React.PureComponent {

/**
* Create a MagicSelect component
*
* @param {Object} props
*/
constructor(props) {
super(props);
this.state = {
currentList: props.defaultList,
isOpen: props.isOpen
};
this.onChange = this.onChange.bind(this);
this.items = this.items.bind(this);
this.onChange = this.onChange.bind(this);
this.onSelect = this.onSelect.bind(this);
this.onInputFocus = this.onInputFocus.bind(this);
}

const onChange = (event) => {
/**
* Handle direct change events
*
* Probably not needed
* @param {Event} event
*/
onChange(event) {
this.props.onValueChange(event.target.value);
};

return (
<div
className={classNames('', props.className)}
>
<Autocomplete
id={props.id}
getItemValue={(item) => item.label}
items={[
{ label: 'apple' },
{ label: 'banana' },
{ label: 'pear' }
]}
renderItem={(item, isHighlighted) =>
<div style={{ background: isHighlighted ? 'lightgray' : 'white' }}>
{item.label}
</div>
}
value={props.value}
onChange={onChange}
onSelect={(val) => value = val}
/>
</div>
);
/**
* Create the list of items
*
* @return {Array}
*/
items() {
let items = [];
if (Array.isArray(this.props.options) && this.props.options.length) {
items = this.props.options;
} else if ('system' === this.state.currentList) {
items = this.props.systemTagsList
} else {
items = this.props.fieldsList;
}

if (items.length) {
items.forEach((item, itemIndex) => {
items[itemIndex].key = `${item.value}-${itemIndex}`;
});
}

return items;

}

/**
* Handle when the field gets focus
*/
onInputFocus() {
this.setState({isOpen: true});
}

/**
* Handle when the option is chosen
* @param {String|number} value
*/
onSelect(value) {
this.props.onValueChange(value);
this.setState({isOpen: false});
}

/**
* Render MagicSelect component
* @return {*}
*/
render() {
return (
<div
className={classNames('magic-select', this.props.className)}
>
<Autocomplete
getItemValue={(item) => item.value}
items={this.items()}
inputProps={{
id: this.props.id,
value: this.props.value,
className: `${this.props.id}-magic-input`,
onFocus: this.onInputFocus,
}}
renderItem={(item, isHighlighted) =>
<div
style={{background: isHighlighted ? 'lightgray' : 'white'}}
className={classNames(`${this.props.id}-magic-input`, item.value, 'magic-input-option')}
>
{item.label}
</div>
}
value={this.props.value}
onChange={this.onChange}
open={this.state.isOpen}
selectOnBlur={true}
onSelect={this.onSelect}

/>
</div>
);
};
}


/**
* Prop definitions for MagicSelect component
*/
*/
MagicSelect.propTypes = {
id: PropTypes.string.isRequired,
fieldsList: optionsShapeProp,
systemTagsList: optionsShapeProp,
options: optionsShapeProp,
isRequired: PropTypes.bool,
help: PropTypes.string,
value: valuePropType,
onValueChange: onValueChangePropType,
options: PropTypes.array,
disabled: PropTypes.bool,
defaultList: PropTypes.string,
isOpen: PropTypes.bool
};

/**
* Default property values for MagicSelect component
*
* @type {{}}
*/
MagicSelect.defaultProps = {};
MagicSelect.defaultProps = {
defaultList: 'fields',
isOpen: false,
};
93 changes: 89 additions & 4 deletions src/components/fields/magic-select/MagicSelect.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

import renderer from 'react-test-renderer';
import React from 'react';
import {mount} from 'enzyme';
import {mount,shallow} from 'enzyme';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import {MagicSelect } from "./MagicSelect";
Expand All @@ -10,8 +10,6 @@ Enzyme.configure({adapter: new Adapter()});

const genericChangeHandler = () => {};
describe( 'MagicSelect component', () => {
let selectFieldValue = 'html';


it( 'Matches snapshot', () => {
const component = renderer.create(
Expand All @@ -32,5 +30,92 @@ describe( 'MagicSelect component', () => {
/>
);
expect( component.toJSON() ).toMatchSnapshot();
})
});

it( 'Has inner input', () => {
const component = mount(
<MagicSelect
id={'magic-2a'}
fieldClassName={'magic'}
onValueChange={genericChangeHandler}
options={[
{
label: 'HTML',
value: 'html'
},
{
label: 'Plain Text',
value: 'plain'
}
]}
/>
);
expect( component.find( 'input' ).length ).toBe(1);
});

it( 'puts the right id attribute on inner input', () => {
const component = mount(
<MagicSelect
id={'magic-2'}
fieldClassName={'magic'}
onValueChange={genericChangeHandler}
options={[
{
label: 'HTML',
value: 'html'
},
{
label: 'Plain Text',
value: 'plain'
}
]}
/>
);
expect( component.find( 'input' ).prop( 'id') ).toBe('magic-2');
});

describe( 'Options', () => {
it( 'shows none if closed', () => {
const component = mount(
<MagicSelect
id={'magic-3'}
fieldClassName={'magic'}
onValueChange={genericChangeHandler}
options={[
{
label: 'HTML',
value: 'html'
},
{
label: 'Plain Text',
value: 'plain'
}
]}
isOpen={false}
/>
);
expect( component.find( '.magic-input-option' ).length ).toBe(0);
});
it( 'Uses options prop by default - right number of options', () => {
const component = mount(
<MagicSelect
id={'magic-4'}
fieldClassName={'magic'}
onValueChange={genericChangeHandler}
options={[
{
label: 'HTML',
value: 'html'
},
{
label: 'Plain Text',
value: 'plain'
}
]}
isOpen={true}
/>
);
expect( component.find( '.magic-input-option' ).length ).toBe(2);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

exports[`MagicSelect component Matches snapshot 1`] = `
<div
className=""
className="magic-select"
>
<div
style={
Expand All @@ -15,6 +15,8 @@ exports[`MagicSelect component Matches snapshot 1`] = `
aria-autocomplete="list"
aria-expanded={false}
autoComplete="off"
className="magic-1-magic-input"
id="magic-1"
onBlur={[Function]}
onChange={[Function]}
onClick={[Function]}
Expand Down

0 comments on commit d6b879e

Please sign in to comment.