Skip to content

Commit

Permalink
New: Add react-select component
Browse files Browse the repository at this point in the history
 - Custom style overrides
 - single and multi examples and tests
 - Downgraded sass naming convention errors to warnings until we can do inline/file based rules/exclusions
 - Added spacing between example components
 - `allowCreate` dependant on JedWatson/react-select#660
  • Loading branch information
omgaz committed Jan 8, 2016
1 parent b8f1b5a commit 0ceca31
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 3 deletions.
4 changes: 3 additions & 1 deletion .sass-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ rules:
force-pseudo-nesting: 2

# Name Formats
class-name-format: 2
# TODO: When inline linting is supported set as error (https://github.com/sasstools/sass-lint/pull/402) and ignore
# in Select.scss
class-name-format: 1
function-name-format: 2
mixin-name-format: 2
placeholder-name-format: 2
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"dependencies": {
"lodash": "^3.10.1",
"react": "^0.14.6",
"react-dom": "^0.14.6"
"react-dom": "^0.14.6",
"react-select": "^1.0.0-beta8"
}
}
62 changes: 62 additions & 0 deletions src/components/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,50 @@ import {
Tab,
Radio,
RadioGroup,
Select,
Toggle,
} from './distributionEntry';

require('styles/App.scss');

const selectCountriesOptions = [
{ value: 'au', label: 'Australia' },
{ value: 'uk', label: 'United Kingdom' },
{ value: 'us', label: 'United States' },
{ value: 'lt', label: 'Lesotho', disabled: true },
];

const selectFlavoursOptions = [
{ label: 'Chocolate', value: 'chocolate' },
{ label: 'Vanilla', value: 'vanilla' },
{ label: 'Strawberry', value: 'strawberry' },
{ label: 'Caramel', value: 'caramel' },
{ label: 'Cookies and Cream', value: 'cookiescream' },
{ label: 'Peppermint', value: 'peppermint' },
];

class AppComponent extends React.Component {
constructor(props) {
super(props);
this.setSelectedCountry = this.setSelectedCountry.bind(this);
this.setSelectedFlavours = this.setSelectedFlavours.bind(this);
this.toggleSimpleModal = this.toggleSimpleModal.bind(this);

this.state = {
selectedCountry: 'au',
selectedFlavours: 'vanilla',
showSimpleModal: false,
};
}

setSelectedCountry(newValue) {
this.setState({ selectedCountry: newValue.value });
}

setSelectedFlavours(newValue) {
this.setState({ selectedFlavours: newValue });
}

toggleSimpleModal() {
this.setState({ showSimpleModal: !this.state.showSimpleModal });
}
Expand Down Expand Up @@ -107,6 +136,7 @@ class AppComponent extends React.Component {
</Modal.Footer>
</Modal>


<h1>Checkboxes</h1>
<div className="example-component-panel">
<Checkbox label="Unchecked" />
Expand All @@ -120,6 +150,8 @@ class AppComponent extends React.Component {
<div className="example-component-panel">
<Checkbox label="Checked and Disabled" checked disabled />
</div>


<h1>Radio Buttons</h1>
<div className="example-component-panel">
<RadioGroup name="testRadio" value="2">
Expand Down Expand Up @@ -149,10 +181,40 @@ class AppComponent extends React.Component {
</RadioGroup>
</div>


<h1>Toggle</h1>
<div className="example-component-panel">
<Toggle />
</div>


<h1>Select</h1>
<div className="example-component-panel">
<Select
clearable={false}
name="countriesSelect"
noResultsText="Sorry, couldn't find that country."
onChange={this.setSelectedCountry}
options={selectCountriesOptions}
placeholder="Countries"
value={this.state.selectedCountry}
/>
</div>

<div className="example-component-panel">
<Select
addLabelText="Add '{label}' flavour?"
allowCreate // Not implemented by react-select v1.0.0-beta8 TODO: When supported, check it works.
multi
name="flavoursSelect"
noResultsText="Noooo, no flavours :("
onChange={this.setSelectedFlavours}
options={selectFlavoursOptions}
placeholder="Select your favs."
simpleValue
value={this.state.selectedFlavours}
/>
</div>
</div>
);
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/distributionEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require('styles/_bootstrap-custom.scss');
require('styles/_icheck-custom.scss');
require('styles/_react-toggle-custom.scss');
require('styles/components/Select.scss');

import Button from 'react-bootstrap/lib/Button';
import Checkbox from 'react-icheck/lib/Checkbox';
Expand All @@ -24,6 +25,8 @@ import {
Slicey,
} from 'alexandria-adslot';

import Select from 'react-select';

module.exports = {
Alert,
Breadcrumb,
Expand All @@ -37,6 +40,7 @@ module.exports = {
Radio,
RadioGroup,
Search,
Select,
Slicey,
Tab,
Tabs,
Expand Down
4 changes: 4 additions & 0 deletions src/styles/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ body {
> .btn-panel + .btn-panel {
margin-top: $etalon-spacing;
}

> .example-component-panel {
margin-bottom: $etalon-spacing / 2;
}
}
83 changes: 83 additions & 0 deletions src/styles/components/Select.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
@import '../variable';

// control options
$select-input-border-color: $color-border-lighter;
$select-input-border-radius: $border-radius-base;
$select-input-border-focus: $select-input-border-color;
$select-input-height: 30px;
$select-padding-vertical: 4px;
$select-padding-horizontal: 7px;
$select-text-color: $color-text;

// menu options
$select-option-color: $color-text-light;
$select-option-focused-color: $select-option-color;
$select-option-focused-bg: $color-gray-white;

// clear "x" button
$select-clear-color: $color-text-light;
$select-clear-hover-color: $color-negative;

// arrow indicator
$select-arrow-color: $color-text-light;
$select-arrow-color-hover: $color-text;

// multi-select item
$select-item-gutter: 4px;
$select-item-color: $color-text-inverse;
$select-item-hover-color: $color-text-light;
$select-item-bg: $color-gray-darker;
$select-item-hover-bg: $select-item-bg;
$select-item-font-size: 11px;
$select-item-padding-vertical: 0;
$select-item-padding-horizontal: 5px;
$select-item-border-radius: 0;


@import './node_modules/react-select/scss/default';


.Select {
&:not(.is-disabled) {
.Select-control {
box-shadow: 0 1px 0 0 $color-border-light;

&:hover,
&:focus {
box-shadow: 0 2px 0 0 $color-border-light;
}
}

&.is-open,
&.is-focused {
&:not(.is-open) {
> .Select-control {
border-color: $color-border-lighter;
}
}
}
}

&--multi {
$multi-select-value-height: $select-input-height - ($select-item-padding-horizontal * 2);

.Select-value {
border: 0;
height: $multi-select-value-height;

&-icon,
&-label {
line-height: 1;
margin-top: 3px;
}

&-icon {
border: 0;
float: right;
font-size: $font-size-subheader;
text-align: left;
width: 13px;
}
}
}
}
60 changes: 59 additions & 1 deletion test/components/MainTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

import createComponent from 'helpers/shallowRenderHelper';
import Main from 'components/Main';
import { isElementOfType } from 'react-addons-test-utils';
import React from 'react';
import { isElementOfType, createRenderer } from 'react-addons-test-utils';
import {
Checkbox,
Radio,
RadioGroup,
Select,
Toggle,
} from '../../src/components/distributionEntry';

Expand Down Expand Up @@ -51,4 +53,60 @@ describe('MainComponent', () => {
const toggleComponent = toggleExampleContainer.props.children;
expect(isElementOfType(toggleComponent, Toggle)).to.equal(true);
});

it('should set and change values for single select', () => {
const getRenderOutputAndCheck = ({ renderer, expectedValue }) => {
const componentRenderOutput = renderer.getRenderOutput();

const selectElContainer = componentRenderOutput.props.children[20];
const selectComponent = selectElContainer.props.children;
expect(isElementOfType(selectComponent, Select)).to.equal(true);
expect(selectComponent.props.value).to.equal(expectedValue);

return { selectComponent };
};

const renderer = createRenderer();
renderer.render(<Main />);

const { selectComponent } = getRenderOutputAndCheck({
renderer,
expectedValue: 'au',
});

selectComponent.props.onChange({ value: 'uk' });

getRenderOutputAndCheck({
renderer,
expectedValue: 'uk',
});
});

it('should set and change values for multi select', () => {
const getRenderOutputAndCheck = ({ renderer, expectedValue }) => {
const componentRenderOutput = renderer.getRenderOutput();

const selectElContainer = componentRenderOutput.props.children[21];
const selectComponent = selectElContainer.props.children;
expect(isElementOfType(selectComponent, Select)).to.equal(true);
expect(selectComponent.props.value).to.eql(expectedValue);

return { selectComponent };
};

const renderer = createRenderer();
renderer.render(<Main />);

const { selectComponent } = getRenderOutputAndCheck({
renderer,
expectedValue: 'vanilla',
});

selectComponent.props.onChange('vanilla,chocolate');

getRenderOutputAndCheck({
renderer,
expectedValue: 'vanilla,chocolate',
});
});
});

0 comments on commit 0ceca31

Please sign in to comment.