@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
182 lines • 6.65 kB
JavaScript
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