@@ -119,7 +119,7 @@ export default class MultiSelect extends React.PureComponent<Props, State> { | |||
} | |||
} | |||
handleSelectChange = (item: string, selected: boolean) => { | |||
handleSelectChange = (selected: boolean, item: string) => { | |||
if (selected) { | |||
this.onSelectItem(item); | |||
} else { |
@@ -19,51 +19,47 @@ | |||
*/ | |||
import * as classNames from 'classnames'; | |||
import * as React from 'react'; | |||
import Checkbox from 'sonar-ui-common/components/controls/Checkbox'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
interface Props { | |||
export interface MultiSelectOptionProps { | |||
active?: boolean; | |||
custom?: boolean; | |||
disabled?: boolean; | |||
element: string; | |||
onHover: (elem: string) => void; | |||
onSelectChange: (elem: string, selected: boolean) => void; | |||
onHover: (element: string) => void; | |||
onSelectChange: (selected: boolean, element: string) => void; | |||
renderLabel: (element: string) => React.ReactNode; | |||
selected?: boolean; | |||
} | |||
export default class MultiSelectOption extends React.PureComponent<Props> { | |||
handleSelect = (evt: React.SyntheticEvent<HTMLAnchorElement>) => { | |||
evt.stopPropagation(); | |||
evt.preventDefault(); | |||
evt.currentTarget.blur(); | |||
export default function MultiSelectOption(props: MultiSelectOptionProps) { | |||
const { active, custom, disabled, element, selected } = props; | |||
const onHover = () => props.onHover(element); | |||
const className = classNames({ active, disabled }); | |||
const label = props.renderLabel(element); | |||
if (!this.props.disabled) { | |||
this.props.onSelectChange(this.props.element, !this.props.selected); | |||
} | |||
}; | |||
handleHover = () => this.props.onHover(this.props.element); | |||
render() { | |||
const { selected, disabled } = this.props; | |||
const className = classNames('icon-checkbox', { | |||
'icon-checkbox-checked': selected, | |||
'icon-checkbox-invisible': disabled | |||
}); | |||
const activeClass = classNames({ active: this.props.active, disabled }); | |||
return ( | |||
<li> | |||
<a | |||
className={activeClass} | |||
href="#" | |||
onClick={this.handleSelect} | |||
onFocus={this.handleHover} | |||
onMouseOver={this.handleHover}> | |||
<i className={className} /> {this.props.custom && '+ '} | |||
{this.props.renderLabel(this.props.element)} | |||
</a> | |||
</li> | |||
); | |||
} | |||
return ( | |||
<li onFocus={onHover} onMouseOver={onHover}> | |||
<Checkbox | |||
checked={Boolean(selected)} | |||
className={className} | |||
disabled={disabled} | |||
id={element} | |||
onCheck={props.onSelectChange}> | |||
{custom ? ( | |||
<span | |||
aria-label={`${translate('create_new_element')}: ${label}`} | |||
className="little-spacer-left"> | |||
<span aria-hidden={true} className="little-spacer-right"> | |||
+ | |||
</span> | |||
{label} | |||
</span> | |||
) : ( | |||
<span className="little-spacer-left">{label}</span> | |||
)} | |||
</Checkbox> | |||
</li> | |||
); | |||
} |
@@ -19,31 +19,24 @@ | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import MultiSelectOption from '../MultiSelectOption'; | |||
const props = { | |||
element: 'mytag', | |||
onSelectChange: () => {}, | |||
onHover: () => {}, | |||
renderLabel: (element: string) => element | |||
}; | |||
import MultiSelectOption, { MultiSelectOptionProps } from '../MultiSelectOption'; | |||
it('should render standard element', () => { | |||
expect(shallow(<MultiSelectOption {...props} />)).toMatchSnapshot(); | |||
}); | |||
it('should render selected element', () => { | |||
expect(shallow(<MultiSelectOption {...props} selected={true} />)).toMatchSnapshot(); | |||
}); | |||
it('should render custom element', () => { | |||
expect(shallow(<MultiSelectOption {...props} custom={true} />)).toMatchSnapshot(); | |||
}); | |||
it('should render active element', () => { | |||
expect(shallow(<MultiSelectOption {...props} active={true} selected={true} />)).toMatchSnapshot(); | |||
expect(shallowRender()).toMatchSnapshot('default element'); | |||
expect(shallowRender({ selected: true })).toMatchSnapshot('selected element'); | |||
expect(shallowRender({ custom: true })).toMatchSnapshot('custom element'); | |||
expect(shallowRender({ active: true, selected: true })).toMatchSnapshot('active element'); | |||
expect(shallowRender({ disabled: true })).toMatchSnapshot('disabled element'); | |||
}); | |||
it('should render disabled element', () => { | |||
expect(shallow(<MultiSelectOption {...props} disabled={true} />)).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<MultiSelectOptionProps> = {}) { | |||
return shallow( | |||
<MultiSelectOption | |||
element="mytag" | |||
onHover={jest.fn()} | |||
onSelectChange={jest.fn()} | |||
renderLabel={(element: string) => element} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -1,92 +1,114 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render active element 1`] = ` | |||
<li> | |||
<a | |||
exports[`should render standard element: active element 1`] = ` | |||
<li | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
> | |||
<Checkbox | |||
checked={true} | |||
className="active" | |||
href="#" | |||
onClick={[Function]} | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
id="mytag" | |||
onCheck={[MockFunction]} | |||
thirdState={false} | |||
> | |||
<i | |||
className="icon-checkbox icon-checkbox-checked" | |||
/> | |||
mytag | |||
</a> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
mytag | |||
</span> | |||
</Checkbox> | |||
</li> | |||
`; | |||
exports[`should render custom element 1`] = ` | |||
<li> | |||
<a | |||
exports[`should render standard element: custom element 1`] = ` | |||
<li | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
> | |||
<Checkbox | |||
checked={false} | |||
className="" | |||
href="#" | |||
onClick={[Function]} | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
id="mytag" | |||
onCheck={[MockFunction]} | |||
thirdState={false} | |||
> | |||
<i | |||
className="icon-checkbox" | |||
/> | |||
+ | |||
mytag | |||
</a> | |||
<span | |||
aria-label="create_new_element: mytag" | |||
className="little-spacer-left" | |||
> | |||
<span | |||
aria-hidden={true} | |||
className="little-spacer-right" | |||
> | |||
+ | |||
</span> | |||
mytag | |||
</span> | |||
</Checkbox> | |||
</li> | |||
`; | |||
exports[`should render disabled element 1`] = ` | |||
<li> | |||
<a | |||
className="disabled" | |||
href="#" | |||
onClick={[Function]} | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
exports[`should render standard element: default element 1`] = ` | |||
<li | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
> | |||
<Checkbox | |||
checked={false} | |||
className="" | |||
id="mytag" | |||
onCheck={[MockFunction]} | |||
thirdState={false} | |||
> | |||
<i | |||
className="icon-checkbox icon-checkbox-invisible" | |||
/> | |||
mytag | |||
</a> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
mytag | |||
</span> | |||
</Checkbox> | |||
</li> | |||
`; | |||
exports[`should render selected element 1`] = ` | |||
<li> | |||
<a | |||
className="" | |||
href="#" | |||
onClick={[Function]} | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
exports[`should render standard element: disabled element 1`] = ` | |||
<li | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
> | |||
<Checkbox | |||
checked={false} | |||
className="disabled" | |||
disabled={true} | |||
id="mytag" | |||
onCheck={[MockFunction]} | |||
thirdState={false} | |||
> | |||
<i | |||
className="icon-checkbox icon-checkbox-checked" | |||
/> | |||
mytag | |||
</a> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
mytag | |||
</span> | |||
</Checkbox> | |||
</li> | |||
`; | |||
exports[`should render standard element 1`] = ` | |||
<li> | |||
<a | |||
exports[`should render standard element: selected element 1`] = ` | |||
<li | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
> | |||
<Checkbox | |||
checked={true} | |||
className="" | |||
href="#" | |||
onClick={[Function]} | |||
onFocus={[Function]} | |||
onMouseOver={[Function]} | |||
id="mytag" | |||
onCheck={[MockFunction]} | |||
thirdState={false} | |||
> | |||
<i | |||
className="icon-checkbox" | |||
/> | |||
mytag | |||
</a> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
mytag | |||
</span> | |||
</Checkbox> | |||
</li> | |||
`; |
@@ -47,6 +47,7 @@ confirm=Confirm | |||
continue=Continue | |||
copy=Copy | |||
create=Create | |||
create_new_element=Create new element | |||
created=Created | |||
created_on=Created on | |||
critical=Critical |