@ui5/webcomponents-react
Version:
React Wrapper for UI5 Web Components and additional components
137 lines (136 loc) • 5.54 kB
JavaScript
'use client';
import IconMode from '@ui5/webcomponents/dist/types/IconMode.js';
import ListItemType from '@ui5/webcomponents/dist/types/ListItemType.js';
import WrappingType from '@ui5/webcomponents/dist/types/WrappingType.js';
import ValueState from '@ui5/webcomponents-base/dist/types/ValueState.js';
import iconArrowRight from '@ui5/webcomponents-icons/dist/slim-arrow-right.js';
import { useI18nBundle, useStylesheet } from '@ui5/webcomponents-react-base';
import { clsx } from 'clsx';
import { Children, forwardRef, useContext, useEffect, useRef, useState } from 'react';
import { FlexBoxAlignItems } from '../../enums/FlexBoxAlignItems.js';
import { FlexBoxDirection } from '../../enums/FlexBoxDirection.js';
import { COUNTER, HAS_DETAILS } from '../../i18n/i18n-defaults.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 { getIconNameForType, getValueStateMap, resolveTitleTextStr } from '../MessageView/utils.js';
import { classNames, styleData } from './MessageItem.module.css.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);
const i18nBundle = useI18nBundle('@ui5/webcomponents-react');
const titleTextStr = resolveTitleTextStr(titleText);
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,
titleTextStr
});
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(([titleTextSpanEntry]) => {
const child = titleTextSpanEntry.target.children[0];
const target = titleTextSpanEntry.target;
const isTargetOverflowing = target.scrollWidth > target.clientWidth;
let isChildOverflowing = false;
if (!isTargetOverflowing) {
const firstChild = child?.shadowRoot?.firstChild;
if (firstChild) {
isChildOverflowing = firstChild.scrollWidth > firstChild.clientWidth;
}
}
setIsTitleTextIsOverflowing(isTargetOverflowing || isChildOverflowing);
});
if (!hasChildren && titleTextRef.current) {
titleTextObserver.observe(titleTextRef.current);
}
return () => {
titleTextObserver.disconnect();
};
}, [hasChildren]);
return /*#__PURE__*/_jsx(ListItemCustom, {
onClick: handleListItemClick,
onKeyDown: handleKeyDown,
"data-title": titleTextStr,
"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,
mode: IconMode.Decorative
})
}), /*#__PURE__*/_jsxs(FlexBox, {
direction: FlexBoxDirection.Column,
className: classNames.titleContainer,
children: [titleText && /*#__PURE__*/_jsx("span", {
className: classNames.title,
ref: titleTextRef,
children: titleText
}), titleText && subtitleText && /*#__PURE__*/_jsx(Label, {
className: classNames.subtitle,
wrappingType: WrappingType.None,
children: subtitleText
})]
}), counter != null && /*#__PURE__*/_jsx("span", {
className: classNames.counter,
"aria-label": `. ${i18nBundle.getText(COUNTER)} ${counter}`,
children: counter
}), hasDetails && /*#__PURE__*/_jsx(Icon, {
className: classNames.navigation,
name: iconArrowRight,
mode: IconMode.Decorative
}), hasDetails && /*#__PURE__*/_jsxs("span", {
className: classNames.pseudoInvisibleText,
children: [". ", i18nBundle.getText(HAS_DETAILS)]
}), type !== ValueState.None && type !== ValueState.Information && /*#__PURE__*/_jsxs("span", {
className: classNames.pseudoInvisibleText,
children: [". ", getValueStateMap(i18nBundle)[type]]
})]
})
});
});
MessageItem.displayName = 'MessageItem';
export { MessageItem };