UNPKG

@ui5/webcomponents-react

Version:

React Wrapper for UI5 Web Components and additional components

117 lines (116 loc) 4.25 kB
'use client'; import ListItemType from '@ui5/webcomponents/dist/types/ListItemType.js'; import ValueState from '@ui5/webcomponents-base/dist/types/ValueState.js'; import iconArrowRight from '@ui5/webcomponents-icons/dist/slim-arrow-right.js'; import { useStylesheet } from '@ui5/webcomponents-react-base'; import { clsx } from 'clsx'; import { Children, forwardRef, useContext, useEffect, useRef, useState } from 'react'; import { FlexBoxAlignItems, FlexBoxDirection } from '../../enums/index.js'; import { MessageViewContext } from '../../internal/MessageViewContext.js'; import { Icon } from '../../webComponents/Icon/index.js'; import { Label } from '../../webComponents/Label/index.js'; import { ListItemCustom } from '../../webComponents/ListItemCustom/index.js'; import { FlexBox } from '../FlexBox/index.js'; import { classNames, styleData } from './MessageItem.module.css.js'; import { getIconNameForType } from './utils.js'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; /** * A component used to hold different types of system messages inside the `MessageView` component. */ const MessageItem = /*#__PURE__*/forwardRef((props, ref) => { const { titleText, subtitleText, counter, type = ValueState.Negative, children, className, ...rest } = props; const [isTitleTextOverflowing, setIsTitleTextIsOverflowing] = useState(false); const titleTextRef = useRef(null); const hasDetails = !!(children || isTitleTextOverflowing); useStylesheet(styleData, MessageItem.displayName); const { selectMessage } = useContext(MessageViewContext); const listItemClasses = clsx(classNames.listItem, Reflect.get(classNames, `type${type}`), className, subtitleText && classNames.withSubtitle); const messageClasses = clsx(classNames.message, hasDetails && classNames.withChildren); const handleListItemClick = e => { if (hasDetails) { selectMessage(props); if (typeof rest.onClick === 'function') { rest.onClick(e); } } }; const handleKeyDown = e => { if (typeof rest.onKeyDown === 'function') { rest.onKeyDown(e); } if (e.code === 'Enter') { handleListItemClick(e); } }; const hasChildren = Children.count(children); useEffect(() => { const titleTextObserver = new ResizeObserver(([titleTextSpan]) => { if (titleTextSpan.target.scrollWidth > titleTextSpan.target.clientWidth) { setIsTitleTextIsOverflowing(true); } else { setIsTitleTextIsOverflowing(false); } }); if (!hasChildren && titleTextRef.current) { titleTextObserver.observe(titleTextRef.current); } return () => { titleTextObserver.disconnect(); }; }, [hasChildren]); return /*#__PURE__*/_jsx(ListItemCustom, { onClick: handleListItemClick, onKeyDown: handleKeyDown, "data-title": titleText, "data-type": type, type: hasDetails ? ListItemType.Active : ListItemType.Inactive, ...rest, className: listItemClasses, ref: ref, children: /*#__PURE__*/_jsxs(FlexBox, { alignItems: FlexBoxAlignItems.Center, className: messageClasses, children: [/*#__PURE__*/_jsx("div", { className: classNames.iconContainer, children: /*#__PURE__*/_jsx(Icon, { name: getIconNameForType(type), className: classNames.icon }) }), /*#__PURE__*/_jsxs(FlexBox, { direction: FlexBoxDirection.Column, style: { flex: 'auto', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }, children: [titleText && /*#__PURE__*/_jsx("span", { className: classNames.title, ref: titleTextRef, children: titleText }), titleText && subtitleText && /*#__PURE__*/_jsx(Label, { className: classNames.subtitle, children: subtitleText })] }), counter != null && /*#__PURE__*/_jsx("span", { className: classNames.counter, children: counter }), hasDetails && /*#__PURE__*/_jsx(Icon, { className: classNames.navigation, name: iconArrowRight })] }) }); }); MessageItem.displayName = 'MessageItem'; export { MessageItem };