@zohodesk/dot
Version:
In this Library, we Provide Some Basic Components to Build Your Application
357 lines (343 loc) • 11.7 kB
JavaScript
import React from 'react';
import { defaultProps } from "./props/defaultProps";
import { propTypes } from "./props/propTypes";
import { Icon } from '@zohodesk/icons';
import Popup from '@zohodesk/components/lib/Popup/Popup';
import { Box, Container } from '@zohodesk/components/lib/Layout';
import DropDownHeading from '@zohodesk/components/lib/DropDown/DropDownHeading';
import TextBoxIcon from '@zohodesk/components/lib/TextBoxIcon/TextBoxIcon';
import Loader from '@zohodesk/svg/lib/Loader/Loader';
import EmptySearch from '@zohodesk/svg/lib/emptystate/version3/EmptySearch';
import CommonEmptyState from "../../../emptystate/CommonEmptyState/CommonEmptyState";
import StatusListItem from "../StatusListItem/StatusListItem";
import commonStyle from '@zohodesk/components/lib/common/common.module.css';
import ResponsiveDropBox from '@zohodesk/components/lib/ResponsiveDropBox/ResponsiveDropBox';
import { ResponsiveReceiver } from '@zohodesk/components/lib/Responsive/CustomResponsive';
import { getUniqueId } from '@zohodesk/components/lib/Provider/IdProvider';
import btnStyle from '@zohodesk/components/lib/semantic/Button/semanticButton.module.css';
import style from "./StatusDropdown.module.css";
export class StatusDropdown extends React.Component {
constructor(props) {
super(props);
this.state = {
searchString: '',
options: props.options
};
this.handleChange = this.handleChange.bind(this);
this.onSelect = this.onSelect.bind(this);
this.handleTogglePopup = this.handleTogglePopup.bind(this);
this.onSearchClear = this.onSearchClear.bind(this);
this.searchList = this.searchList.bind(this);
this.handleScroll = this.handleScroll.bind(this);
this.emptySearchSVG = this.emptySearchSVG.bind(this);
this.getAriaId = getUniqueId(this);
}
emptySearchSVG() {
return /*#__PURE__*/React.createElement(EmptySearch, {
size: "small"
});
}
handleTogglePopup(e) {
let {
togglePopup,
boxPosition,
onSelectLabel,
isPopupOpen,
onTogglePopup
} = this.props;
!isPopupOpen && onSelectLabel && onSelectLabel(e);
onTogglePopup && onTogglePopup(isPopupOpen);
togglePopup(e, boxPosition);
}
componentWillReceiveProps(nextProps) {
if (nextProps.options.length != this.props.options.length) {
this.setState({
options: nextProps.options
});
}
}
onSelect(element, e) {
let {
onClick,
togglePopup,
isPopupOpen,
onTogglePopup
} = this.props;
onClick && onClick(e, element);
onTogglePopup && onTogglePopup(isPopupOpen);
togglePopup(e);
}
componentDidUpdate(prevProps) {
if (!prevProps.isPopupOpen && this.props.isPopupOpen) {
this.onSearchClear();
}
}
searchList(value) {
let {
options,
keyName
} = this.props;
let foptions = options.filter(dept => dept[keyName].toLowerCase().indexOf(value.toLowerCase()) != -1);
return foptions;
}
handleChange(value, e) {
let foptions = this.searchList(value);
this.setState({
searchString: value,
options: foptions
});
}
onSearchClear() {
let foptions = this.searchList('');
this.setState({
searchString: '',
options: foptions
});
}
handleScroll(e) {
const {
getNextOptions
} = this.props;
if (e.target.scrollTop + e.target.offsetHeight > e.target.scrollHeight - 1) {
getNextOptions && getNextOptions(e);
}
}
responsiveFunc(_ref) {
let {
mediaQueryOR
} = _ref;
return {
tabletMode: mediaQueryOR([{
maxWidth: 700
}])
};
}
render() {
let {
options
} = this.state;
let {
value,
removeClose,
boxSize,
keyName,
idName,
title,
isSearch,
isArrow,
placeHolderText,
className,
right,
left,
top,
bottom,
isPopupOpen: isOpen,
isPopupReady,
position,
getTargetRef,
getContainerRef,
dataId,
searchBoxSize,
searchEmptyHint,
searchErrorText,
activeStyle,
showOnHover = false,
isDisabled,
showIconOnHover,
isReadOnly,
hoverStyle,
isEditable,
needTick,
dataTitle,
isDataLoaded,
children,
targetAlign,
needResponsive,
arrowIconPosition,
statusColor,
needExternalPopupState = false,
isPopupActive = false,
needMultiLineText,
isFetchingOptions,
getNextOptions,
isAbsolutePositioningNeeded,
isRestrictScroll,
positionsOffset,
targetOffset,
renderTargetElement,
renderFooterElement,
a11y = {}
} = this.props;
const {
tabIndex = 0,
ariaLabelledby,
ariaLabel
} = a11y;
let isPopupOpen = needExternalPopupState ? isPopupActive && isOpen : isOpen;
let {
searchString
} = this.state;
let containerClass = `${className ? className : ''} ${isPopupReady ? activeStyle ? activeStyle : '' : showIconOnHover ? style.hoverIcon : ''} ${isDisabled ? commonStyle.disabled : isReadOnly ? style.readOnly : !isEditable ? style.cursorDefault : !showOnHover ? `${style.cursor} ${hoverStyle ? hoverStyle : ''}` : `${hoverStyle ? hoverStyle : ''} ${style.cursorDefault}`}`;
let ariaTitleId = this.getAriaId();
return /*#__PURE__*/React.createElement("div", {
className: style.posRel,
onMouseEnter: showOnHover && !isDisabled && !isReadOnly && isEditable ? this.handleTogglePopup : undefined,
onMouseLeave: showOnHover && !isDisabled && !isReadOnly && isEditable ? this.handleTogglePopup : undefined
}, renderTargetElement ? renderTargetElement({
handleTogglePopup: this.handleTogglePopup,
isPopupOpen,
getTargetRef
}) : /*#__PURE__*/React.createElement(Container, {
tagName: "button",
alignBox: "row",
className: `${style.container} ${containerClass} ${btnStyle.buttonReset}`,
onClick: !showOnHover && !isDisabled && !isReadOnly && isEditable ? this.handleTogglePopup : null,
eleRef: getTargetRef,
align: targetAlign,
isCover: false,
dataId: dataId,
disabled: isDisabled || isReadOnly ? true : false,
"aria-haspopup": isSearch ? 'listbox' : 'menu',
"aria-expanded": isPopupReady && isEditable ? true : false,
tabIndex: tabIndex,
"aria-labelledby": ariaLabelledby,
"aria-label": ariaLabel,
"aria-disabled": isDisabled || isReadOnly
}, children ? children : /*#__PURE__*/React.createElement(Box, {
className: `${style.value} toggleDropText`,
shrink: true,
tagName: "span",
"data-title": dataTitle,
dataId: `${dataId}_value`
}, value), isEditable ? /*#__PURE__*/React.createElement(Icon, {
"aria-hidden": true,
size: "7",
name: "ZD-down",
iconClass: `${'toggleDropIcon'} ${style.arrow} ${style[`${arrowIconPosition}_arrow`]}`,
dataId: "statusdownarrow"
}) : null), isPopupOpen && isEditable ? /*#__PURE__*/React.createElement(ResponsiveReceiver, {
query: this.responsiveFunc,
responsiveId: "Helmet"
}, _ref2 => {
let {
tabletMode
} = _ref2;
return /*#__PURE__*/React.createElement(ResponsiveDropBox, {
boxPosition: position,
isActive: isPopupReady,
onClick: removeClose,
size: boxSize,
right: right,
left: left,
top: top,
bottom: bottom,
isArrow: isArrow,
isAnimate: true,
getRef: getContainerRef,
customClass: {
customDropBoxWrap: style.dropBoxContainer
},
needResponsive: needResponsive,
isResponsivePadding: true,
needFocusScope: true,
onClose: this.handleTogglePopup,
dataId: `${dataId}_dropbox`,
isAbsolutePositioningNeeded: isAbsolutePositioningNeeded,
isRestrictScroll: isRestrictScroll,
positionsOffset: positionsOffset,
targetOffset: targetOffset,
customProps: {
focusScopeProps: {
loadNextOptions: getNextOptions,
searchValue: searchString,
isFetchingOptions: isFetchingOptions
}
}
}, /*#__PURE__*/React.createElement(React.Fragment, null, isSearch ? /*#__PURE__*/React.createElement(Box, {
className: style.search
}, /*#__PURE__*/React.createElement(TextBoxIcon, {
placeHolder: placeHolderText,
onChange: this.handleChange,
value: searchString,
onClear: this.onSearchClear,
size: searchBoxSize,
customProps: {
TextBoxProps: {
'data-a11y-autofocus': true
}
},
a11y: {
ariaHaspopup: isSearch ? 'listbox' : 'menu',
ariaExpanded: isPopupReady,
role: 'combobox',
ariaActivedescendant: isPopupReady ? value : '',
ariaOwns: ariaTitleId
},
dataId: `${dataId}_search`
})) : null, title && options.length != 0 && /*#__PURE__*/React.createElement(Box, {
className: style.title
}, /*#__PURE__*/React.createElement(DropDownHeading, {
htmlId: ariaTitleId,
text: title,
a11y: {
role: 'heading'
}
})), /*#__PURE__*/React.createElement(Box, {
scroll: "vertical",
flexible: true,
shrink: true,
dataId: `${dataId}_list`,
preventParentScroll: "vertical",
className: `${tabletMode ? style.responsivemaxHgt : style.maxHgt}`,
onScroll: this.handleScroll,
role: isSearch ? 'listbox' : 'menu',
tabindex: "-1",
isScrollAttribute: true
}, options.length != 0 && isDataLoaded ? /*#__PURE__*/React.createElement(React.Fragment, null, options.map((item, i) => {
const listItemText = item[keyName];
const isActive = value === listItemText;
return /*#__PURE__*/React.createElement(StatusListItem, {
key: i,
dataId: `dataid_${i}`,
value: listItemText,
id: item[idName],
active: isActive,
onClick: this.onSelect.bind(this, item),
index: i,
needTick: needTick,
needBorder: false,
bulletColor: item[statusColor],
title: listItemText,
needMultiLineText: needMultiLineText,
autoHover: true,
a11y: {
role: isSearch ? 'option' : 'menuitem',
ariaSelected: isActive,
ariaLabel: listItemText
}
});
}), isFetchingOptions && /*#__PURE__*/React.createElement(Container, {
isCover: false,
align: "both"
}, /*#__PURE__*/React.createElement(Loader, null))) : isDataLoaded ? /*#__PURE__*/React.createElement(CommonEmptyState, {
className: style.svgWrapper,
title: searchErrorText || 'No results',
description: searchEmptyHint,
size: "small",
getEmptyState: this.emptySearchSVG
}) : /*#__PURE__*/React.createElement("div", {
className: style.loader
}, /*#__PURE__*/React.createElement(Loader, null))), renderFooterElement ? renderFooterElement : null));
}) : null);
}
} // if (__DOCS__) {
// StatusDropdown.docs = {
// componentGroup: 'Molecule'
// };
// }
StatusDropdown.defaultProps = defaultProps;
StatusDropdown.propTypes = propTypes;
const StatusDropdown_Component = Popup(StatusDropdown);
StatusDropdown_Component.defaultProps = StatusDropdown.defaultProps;
StatusDropdown_Component.propTypes = StatusDropdown.propTypes;
export default StatusDropdown_Component;