} | } | ||||
} | } | ||||
handleSelectChange = (item: string, selected: boolean) => { | |||||
handleSelectChange = (selected: boolean, item: string) => { | |||||
if (selected) { | if (selected) { | ||||
this.onSelectItem(item); | this.onSelectItem(item); | ||||
} else { | } else { |
*/ | */ | ||||
import * as classNames from 'classnames'; | import * as classNames from 'classnames'; | ||||
import * as React from 'react'; | 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; | active?: boolean; | ||||
custom?: boolean; | custom?: boolean; | ||||
disabled?: boolean; | disabled?: boolean; | ||||
element: string; | 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; | renderLabel: (element: string) => React.ReactNode; | ||||
selected?: boolean; | 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> | |||||
); | |||||
} | } |
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | 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', () => { | 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} | |||||
/> | |||||
); | |||||
} |
// Jest Snapshot v1, https://goo.gl/fbAQLP | // 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" | 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> | </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="" | 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> | </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> | </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> | </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="" | 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> | </li> | ||||
`; | `; |
continue=Continue | continue=Continue | ||||
copy=Copy | copy=Copy | ||||
create=Create | create=Create | ||||
create_new_element=Create new element | |||||
created=Created | created=Created | ||||
created_on=Created on | created_on=Created on | ||||
critical=Critical | critical=Critical |