UNPKG

@chayns-components/core

Version:

A set of beautiful React components for developing your own applications with chayns.

182 lines 6.65 kB
import { AnimatePresence } from 'motion/react'; import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { useUuid } from '../../../hooks/uuid'; import { AccordionContext } from '../../accordion/Accordion'; import AreaContextProvider, { AreaContext } from '../../area-provider/AreaContextProvider'; import { ListContext } from '../List'; import ListItemBody from './list-item-body/ListItemBody'; import ListItemHead from './list-item-head/ListItemHead'; import { StyledListItemTooltip, StyledMotionListItem } from './ListItem.styles'; import Tooltip from '../../tooltip/Tooltip'; const ListItem = _ref => { let { careOfLocationId, children, cornerImage, hoverItem, icons, imageBackground, images, isDefaultOpen, isOpen, isTitleGreyed, leftElements, onClick, onClose, onLongPress, onOpen, rightElements, shouldShowTooltipOnTitleOverflow = false, shouldForceBackground = false, shouldForceBottomLine = false, shouldForceHover = false, shouldHideBottomLine = false, shouldOpenImageOnClick = false, shouldHideImageOrIconBackground, shouldHideIndicator = false, shouldPreventLayoutAnimation = false, shouldRenderClosed = false, shouldShowRoundImageOrIcon, shouldShowSeparatorBelow = false, subtitle, title, titleElement } = _ref; const { incrementExpandableItemCount, isAnyItemExpandable, isWrapped, openItemUuid, updateOpenItemUuid } = useContext(ListContext); const { isWrapped: isParentAccordionWrapped } = useContext(AccordionContext); const areaProvider = useContext(AreaContext); const isInitialRenderRef = useRef(true); const listItemRef = useRef(null); const uuid = useUuid(); const isExpandable = children !== undefined; const isItemOpen = isOpen ?? openItemUuid === uuid; const onCloseRef = useRef(onClose); const onOpenRef = useRef(onOpen); const [shouldEnableTooltip, setShouldEnableTooltip] = useState(false); const shouldDisablePadding = useMemo(() => areaProvider.shouldDisableListItemPadding ?? false, [areaProvider.shouldDisableListItemPadding]); useEffect(() => { onCloseRef.current = onClose; onOpenRef.current = onOpen; }, [isOpen, onClose, onOpen]); useEffect(() => { if (isInitialRenderRef.current) { isInitialRenderRef.current = false; } else if (isItemOpen) { if (typeof onOpenRef.current === 'function') { onOpenRef.current(); } } else if (typeof onCloseRef.current === 'function') { onCloseRef.current(); } }, [isItemOpen]); const handleHeadClick = useCallback(event => { if (isExpandable) { updateOpenItemUuid(uuid); } if (typeof onClick === 'function') { onClick(event); } }, [isExpandable, onClick, updateOpenItemUuid, uuid]); useEffect(() => { if (isExpandable && !shouldHideIndicator) { // The incrementExpandableItemCount function returns an cleanup // function to decrement expandableItemCount if component unmounts return incrementExpandableItemCount(); } return undefined; }, [incrementExpandableItemCount, isExpandable, shouldHideIndicator]); useEffect(() => { if (isDefaultOpen) { updateOpenItemUuid(uuid, { shouldOnlyOpen: true }); } }, [isDefaultOpen, updateOpenItemUuid, uuid]); const isClickable = typeof onClick === 'function' || isExpandable; const handleTitleWidthChange = titleWidth => { if (listItemRef.current) { const { offsetWidth } = listItemRef.current; if (offsetWidth - 18 < titleWidth) { setShouldEnableTooltip(true); } else { setShouldEnableTooltip(false); } } }; const headContent = useMemo(() => /*#__PURE__*/React.createElement(ListItemHead, { hoverItem: hoverItem, careOfLocationId: careOfLocationId, cornerImage: cornerImage, icons: icons, imageBackground: imageBackground, images: images, isAnyItemExpandable: isAnyItemExpandable, isExpandable: isExpandable, onTitleWidthChange: handleTitleWidthChange, isOpen: isItemOpen, isTitleGreyed: isTitleGreyed, leftElements: leftElements, onClick: isClickable ? handleHeadClick : undefined, onLongPress: onLongPress, shouldForceHover: shouldForceHover, rightElements: rightElements, shouldHideImageOrIconBackground: shouldHideImageOrIconBackground, shouldHideIndicator: shouldHideIndicator, shouldOpenImageOnClick: shouldOpenImageOnClick, shouldShowRoundImageOrIcon: shouldShowRoundImageOrIcon, subtitle: subtitle, title: title, titleElement: titleElement }), [careOfLocationId, cornerImage, handleHeadClick, hoverItem, icons, imageBackground, images, isAnyItemExpandable, isClickable, isExpandable, isItemOpen, isTitleGreyed, leftElements, onLongPress, rightElements, shouldForceHover, shouldHideImageOrIconBackground, shouldHideIndicator, shouldOpenImageOnClick, shouldShowRoundImageOrIcon, subtitle, title, titleElement]); return /*#__PURE__*/React.createElement(StyledMotionListItem, { animate: { height: 'auto', opacity: 1 }, className: "beta-chayns-list-item", exit: { height: 0, opacity: 0 }, initial: { height: 0, opacity: 0 }, key: `list-item-${uuid}`, ref: listItemRef, layout: shouldPreventLayoutAnimation ? undefined : 'position', $isClickable: isClickable, $isInAccordion: typeof isParentAccordionWrapped === 'boolean' && !shouldDisablePadding, $isOpen: isItemOpen, $isWrapped: isWrapped, $shouldForceBackground: shouldForceBackground, $shouldForceBottomLine: shouldForceBottomLine, $shouldHideBottomLine: shouldHideBottomLine, $shouldHideIndicator: shouldHideIndicator, $shouldShowSeparatorBelow: shouldShowSeparatorBelow }, shouldShowTooltipOnTitleOverflow && shouldEnableTooltip ? /*#__PURE__*/React.createElement(Tooltip, { shouldUseFullWidth: true, item: /*#__PURE__*/React.createElement(StyledListItemTooltip, { key: `list-item-tooltip-${uuid}` }, title) }, headContent) : headContent, /*#__PURE__*/React.createElement(AnimatePresence, { initial: false }, isExpandable && (isItemOpen || shouldRenderClosed) && /*#__PURE__*/React.createElement(ListItemBody, { id: uuid, key: `listItemBody-${uuid}`, shouldHideBody: shouldRenderClosed && !isItemOpen }, /*#__PURE__*/React.createElement(AreaContextProvider, null, children)))); }; ListItem.displayName = 'ListItem'; export default ListItem; //# sourceMappingURL=ListItem.js.map