Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
Merge pull request #82 from multicolaure/master
Browse files Browse the repository at this point in the history
feat(select): add Select component
  • Loading branch information
Matteo Vivona authored Oct 21, 2019
2 parents 7f275f3 + dd1186f commit d4af802
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { Component } from 'react'
import { FormControl, FormControlProps } from 'react-bootstrap'
import { getControlSize } from '../../helpers/ControlSize'

interface Props {
/** When multiple is true, the user can select multiple options. Otherwise, one option only. False by default. */
multiple?: boolean
/** Determines whether the Select should be disabled. False by default. */
disabled?: boolean
/** Determines whether the Select should be invalid. False by default. */
isInvalid?: boolean
/** Determines whether to render a small or large TextField. By default, it is undefined. */
size?: 'small' | 'large'
/** Selected value in the */
value?: string

/** Handles the onChange event for the Select. */
onChange?: (event: React.FormEvent<FormControl & FormControlProps>) => void
}

class Select extends Component<Props, {}> {
render() {
return (
<FormControl
as="select"
value={this.props.value}
multiple={this.props.multiple}
isInvalid={this.props.isInvalid}
disabled={this.props.disabled}
size={getControlSize(this.props.size)}
onChange={this.props.onChange}
>
{this.props.children}
</FormControl>
)
}
}

export { Select }
1 change: 1 addition & 0 deletions src/components/Select/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Select'
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from './components/Switch'
export * from './components/Radio'
export * from './components/Alert'
export * from './components/TextInput'
export * from './components/Select'
90 changes: 90 additions & 0 deletions stories/select.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import { Select } from '../src'

storiesOf('Select', module)
.addParameters({
info: {
inline: true,
},
})
.addDecorator(storyFn => <div style={{ textAlign: 'center' }}>{storyFn()}</div>)
.add('Select', () => (
<div>
<Select>
<option selected disabled>
Choose your sweet
</option>
<option>Marshmallow</option>
<option>Nougat</option>
<option>Ice cream</option>
<option>Gingerbread</option>
</Select>
</div>
))
.add('Select multiple', () => (
<div>
<Select multiple>
<option>Marshmallow</option>
<option selected>Nougat</option>
<option>Ice cream</option>
<option selected>Gingerbread</option>
</Select>
</div>
))
.add('Disabled select', () => (
<div>
<Select disabled>
<option selected disabled>
Choose your sweet
</option>
<option>Marshmallow</option>
<option>Nougat</option>
<option>Ice cream</option>
<option>Gingerbread</option>
</Select>
</div>
))
.add('Invalid select', () => (
<div>
<Select isInvalid>
<option selected disabled>
Choose your sweet
</option>
<option>Marshmallow</option>
<option>Nougat</option>
<option>Ice cream</option>
<option>Gingerbread</option>
</Select>
</div>
))
.add('Working with value', () => (
<div>
<Select value="nougat">
<option value="marshmallow">Marshmallow</option>
<option value="nougat">Nougat</option>
<option value="icecream">Ice cream</option>
<option value="gingerbread">Gingerbread</option>
</Select>
</div>
))
.add('Small select', () => (
<div>
<Select value="nougat" size="small">
<option value="marshmallow">Marshmallow</option>
<option value="nougat">Nougat</option>
<option value="icecream">Ice cream</option>
<option value="gingerbread">Gingerbread</option>
</Select>
</div>
))
.add('Large select', () => (
<div>
<Select value="nougat" size="large">
<option value="marshmallow">Marshmallow</option>
<option value="nougat">Nougat</option>
<option value="icecream">Ice cream</option>
<option value="gingerbread">Gingerbread</option>
</Select>
</div>
))
89 changes: 89 additions & 0 deletions test/select.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import * as React from 'react'
import { shallow, mount } from 'enzyme'
import { FormControl as BootstrapFormControl } from 'react-bootstrap'
import { Select } from '../src'

describe('Select', () => {
it('Select renders itself without crashing', () => {
const selectWrapper = shallow(
<Select>
<option value="a">Option A</option>
<option value="b">Option B</option>
<option value="b">Option C</option>
</Select>,
)
expect(selectWrapper.find(BootstrapFormControl)).toHaveLength(1)
})

it('Select renders as disabled when the disabled prop is used', () => {
const selectWrapper = shallow(
<Select disabled>
<option value="a">Option A</option>
<option value="b">Option B</option>
<option value="b">Option C</option>
</Select>,
)
const bootstratSelect = selectWrapper.find(BootstrapFormControl)
expect(bootstratSelect.props().disabled).toEqual(true)
})

it('Select renders as invalid when the isInvalid prop is used', () => {
const selectWrapper = shallow(
<Select isInvalid>
<option value="a">Option A</option>
<option value="b">Option B</option>
<option value="b">Option C</option>
</Select>,
)
const bootstratSelect = selectWrapper.find(BootstrapFormControl)
expect(bootstratSelect.props().isInvalid).toEqual(true)
})

it('Select uses the multiple prop', () => {
const selectWrapper = shallow(
<Select multiple>
<option value="a">Option A</option>
<option value="b">Option B</option>
<option value="b">Option C</option>
</Select>,
)
const bootstratSelect = selectWrapper.find(BootstrapFormControl)
expect(bootstratSelect.props().multiple).toEqual(true)
})

it('Select displays provided options', () => {
const selectWrapper = mount(
<Select>
<option value="a">Option A</option>
<option value="b">Option B</option>
<option value="b">Option C</option>
</Select>,
)
const htmlSelect = selectWrapper.find(HTMLSelectElement)
expect(htmlSelect.children().length).toBe(3)
})

it('Select renders in large size', () => {
const selectWrapper = shallow(
<Select size="large">
<option value="a">Option A</option>
<option value="b">Option B</option>
<option value="b">Option C</option>
</Select>,
)
const bootstratSelect = selectWrapper.find(BootstrapFormControl)
expect(bootstratSelect.props().size).toEqual('lg')
})

it('Select renders in small size', () => {
const selectWrapper = shallow(
<Select size="small">
<option value="a">Option A</option>
<option value="b">Option B</option>
<option value="b">Option C</option>
</Select>,
)
const bootstratSelect = selectWrapper.find(BootstrapFormControl)
expect(bootstratSelect.props().size).toEqual('sm')
})
})

0 comments on commit d4af802

Please sign in to comment.