react-kd.ui
Version:
Karmadata UI library
270 lines (241 loc) • 7.55 kB
JavaScript
import classNames from 'classnames';
import extend from 'extend';
import React, { PropTypes } from 'react';
import KdPopover from '../KdPopover';
import { dispatchCustomEvent } from '../../utils';
import { ASC, DESC } from '../../constants';
const defaultProps = {
isChickletNone: false,
isLoading: false,
hasMainSelector: false,
autocompleteVisible: false,
draggable: false,
direction: ASC,
labelHandler: ({ label }) => label,
chicklets: {
sortable: false,
visible: true,
fullwidth: false,
buttons: {
ascDesc: { visible: false },
info: { visible: false },
remove: { visible: true },
clearInput: { visible: false },
},
events: {},
clearAll: { visible: false },
},
};
const propTypes = {
theme: PropTypes.oneOfType([
PropTypes.object,
PropTypes.func,
]).isRequired,
onRemove: PropTypes.func,
label: PropTypes.string,
value: PropTypes.oneOfType([
PropTypes.string, PropTypes.array, PropTypes.number, PropTypes.object,
]),
labelHandler: PropTypes.func,
isChickletNone: PropTypes.bool,
hasMainSelector: PropTypes.bool,
isLoading: PropTypes.bool,
autocompleteVisible: PropTypes.bool,
toggleItemDirection: PropTypes.func,
direction: PropTypes.string,
api: PropTypes.shape({
url: PropTypes.string.isRequired,
key: PropTypes.string.isRequired,
}),
kdFilterModel: PropTypes.object,
item: PropTypes.object,
draggable: PropTypes.bool,
category: PropTypes.string,
chicklets: PropTypes.shape({
sortable: PropTypes.bool,
visible: PropTypes.bool,
fullwidth: PropTypes.bool,
prefix: PropTypes.string,
buttons: PropTypes.shape({
ascDesc: PropTypes.shape({ visible: PropTypes.bool }),
info: PropTypes.shape({ visible: PropTypes.bool }),
clearInput: PropTypes.shape({ visible: PropTypes.bool }),
}),
events: PropTypes.shape({
onClick: PropTypes.func,
onClose: PropTypes.func,
onToggleDirection: PropTypes.func,
}),
clearAll: PropTypes.shape({
visible: PropTypes.bool,
onClick: PropTypes.func,
}),
}),
};
class KdItemSelected extends React.Component {
constructor(props) {
super(props);
this.chicklets = extend(true, {}, defaultProps.chicklets, this.props.chicklets);
this.state = { isPopoverOpen: false, direction: this.props.direction };
}
togglePopover = () => {
this.setState({ isPopoverOpen: !this.state.isPopoverOpen });
}
toggleItemDirection = () => {
const { value, item, label, toggleItemDirection } = this.props;
const { events: { onToggleDirection } } = this.chicklets;
const direction = this.state.direction === ASC ? DESC : ASC;
this.setState({ direction });
if (onToggleDirection) {
const data = item || { label, value, direction };
onToggleDirection(data);
}
if (toggleItemDirection) {
toggleItemDirection(value);
}
}
renderInfoButton() {
const { label, api, kdFilterModel, theme } = this.props;
if (this.chicklets.buttons.info.visible) {
return (
<div
className={
classNames(
'c-kd-item-selected__info-button',
theme['c-kd-item-selected__info-button'],
)
}
onClick={this.togglePopover}
>
{
this.state.isPopoverOpen &&
<KdPopover
theme={theme}
onRemove={this.togglePopover}
{...{ label, api, kdFilterModel }}
/>
}
</div>
);
}
return null;
}
handleRemove = () => {
const { onRemove, item, label, value, direction } = this.props;
const data = item || { label, value, direction };
onRemove && onRemove({ data });
dispatchCustomEvent(
this.rootElement,
'kd:ui:SelectEntity:onChickletClose',
{ data }
);
}
handleOnClick = () => {
const { item, label, value, direction } = this.props;
const { events: { onClick } } = this.chicklets;
if (onClick) {
const data = item || { label, value, direction };
onClick(data);
}
}
renderLabel = () => {
const { label, value, labelHandler } = this.props;
let formatedLabel = labelHandler({ label, value });
if (this.chicklets.prefix) {
// NOTE: dangerouslySetInnerHTML throws an error with spaces inside span
formatedLabel = <span dangerouslySetInnerHTML={{ __html: `${this.chicklets.prefix} ${labelHandler({ label, value })}` }} />;
}
return formatedLabel;
}
renderItemWithIcon = () => {
const {
hasMainSelector,
isLoading,
autocompleteVisible,
} = this.props;
const { buttons: { clearInput: { visible } } } = this.chicklets;
const { theme } = this.props;
if (visible) {
return (
<div
ref={ref => this.rootElement = ref}
onClick={this.handleRemove}
className={
classNames({
'u-iconx-inner-text': !hasMainSelector && autocompleteVisible,
'u-iconx-inner-text-below-selector': hasMainSelector && autocompleteVisible,
'u-margin-right-medium': isLoading,
[theme['u-iconx-inner-text']]: !hasMainSelector && autocompleteVisible,
[theme['u-iconx-inner-text-below-selector']]: hasMainSelector && autocompleteVisible,
[theme['u-margin-right-medium']]: isLoading,
})
}
/>
);
}
return null;
}
renderArrow() {
const { direction } = this.state;
const { theme } = this.props;
return (
<span
className={
classNames({
'c-kd-item-selected__arrow_up': direction === ASC,
'c-kd-item-selected__arrow_down': direction === DESC,
[theme['c-kd-item-selected__arrow_up']]: direction === ASC,
[theme['c-kd-item-selected__arrow_down']]: direction === DESC,
})}
onClick={this.toggleItemDirection}
/>
);
}
renderRemove = () => {
const { theme, category = 'default' } = this.props;
return (
<span
className={
classNames(
'o-remove',
`o-remove--${category}`,
theme['o-remove'],
theme[`o-remove--${category}`],
)
}
onClick={this.handleRemove}
/>
);
}
renderItem = () => {
const { draggable, chicklets, theme, category = 'default' } = this.props;
return (
<div
ref={ref => this.rootElement = ref}
onClick={this.handleOnClick}
className={
classNames(
`c-kd-item-selected c-kd-item-selected--${category}`,
{ 'c-kd-item-selected__fullwidth': draggable || chicklets.fullwidth },
theme['c-kd-item-selected'],
theme[`c-kd-item-selected--${category}`],
{ [theme['c-kd-item-selected__fullwidth']]: draggable || chicklets.fullwidth },
)
}
>
{chicklets.buttons.ascDesc.visible && this.renderArrow()}
{chicklets.buttons.remove.visible && this.renderRemove()}
{this.renderInfoButton()}
<span className={classNames('c-kd-item-selected-text', theme['c-kd-item-selected-text'])}>
{this.renderLabel()}
</span>
</div>
);
}
render() {
return this.props.isChickletNone ? this.renderItemWithIcon() : this.renderItem();
}
}
KdItemSelected.propTypes = propTypes;
KdItemSelected.defaultProps = defaultProps;
export default KdItemSelected;