UNPKG

monday-ui-react-core

Version:

Official monday.com UI resources for application development in React.js

106 lines (96 loc) 2.72 kB
/* eslint-disable jsx-a11y/role-supports-aria-props,jsx-a11y/no-noninteractive-element-interactions */ import React, { useRef, forwardRef, useCallback } from "react"; import PropTypes from "prop-types"; import cx from "classnames"; import NOOP from "lodash/noop"; import useMergeRefs from "../../hooks/useMergeRefs"; import "./ListItem.scss"; import { SIZES } from "../../constants/sizes"; import { keyCodes } from "../../constants/KeyCodes"; const BEM_BASE_CLASS = "list-item"; function BEMHelper(state) { return `${BEM_BASE_CLASS}--${state}`; } const ListItem = forwardRef(({ className, id, onClick, selected, disabled, size, tabIndex, children }, ref) => { const componentRef = useRef(null); const mergedRef = useMergeRefs({ refs: [ref, componentRef] }); const componentOnClick = useCallback( event => { if (disabled) return; onClick(event, id); }, [disabled, onClick, id] ); const onKeyDown = useCallback( event => { if (disabled) return; const KEYS = [keyCodes.ENTER, keyCodes.SPACE]; if (KEYS.includes(event.key)) { onClick(event, id); } }, [disabled, onClick, id] ); return ( <div ref={mergedRef} className={cx("list-item", className, BEMHelper(size), { [BEMHelper("selected")]: selected && !disabled, [BEMHelper("disabled")]: disabled })} id={id} aria-disabled={disabled} onClick={componentOnClick} onKeyDown={onKeyDown} role="listitem" tabIndex={disabled ? "-1" : tabIndex} > {children} </div> ); }); ListItem.sizes = SIZES; ListItem.propTypes = { /** * A class name to be passed to the list item wrapper */ className: PropTypes.string, /** * An id to be passed to the list item wrapper */ id: PropTypes.string, /** * A callback function which is being called when the item is being clicked * It will be called with the following params * event (DomEvent) * id (the id which is being passed) * onClick(event, id) */ onClick: PropTypes.func, /** * disabled state - callback will not be called and navigation will be skipped */ disabled: PropTypes.bool, /** * Selected indication */ selected: PropTypes.bool, /** * The size of the list item */ size: PropTypes.oneOf([ListItem.sizes.SMALL, ListItem.sizes.MEDIUM, ListItem.sizes.LARGE]), /** Tabindex is used for keyboard navigation - if you want to skip "Tab navigation" please pass -1. */ tabIndex: PropTypes.number }; ListItem.defaultProps = { className: "", id: "", onClick: NOOP, disabled: false, selected: false, size: ListItem.sizes.SMALL, tabIndex: 0 }; export default ListItem;