@ui5/webcomponents-react
Version:
React Wrapper for UI5 Web Components and additional components
117 lines (116 loc) • 4.25 kB
JavaScript
'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 };