Skip to content

Commit 1bd5250

Browse files
committed
fix(MessageViewItem): enable details view if titleText is overflowing (#6015)
Fixes #5990
1 parent 36a7e2f commit 1bd5250

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

packages/main/src/components/MessageView/MessageItem.tsx

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import iconArrowRight from '@ui5/webcomponents-icons/dist/slim-arrow-right.js';
44
import { useStylesheet } from '@ui5/webcomponents-react-base';
55
import { clsx } from 'clsx';
66
import type { ReactNode } from 'react';
7-
import { forwardRef, useContext } from 'react';
7+
import { Children, forwardRef, useContext, useEffect, useRef, useState } from 'react';
88
import { FlexBoxAlignItems, FlexBoxDirection, ListItemType, ValueState } from '../../enums/index.js';
99
import { MessageViewContext } from '../../internal/MessageViewContext.js';
1010
import type { CommonProps } from '../../types/index.js';
@@ -57,6 +57,9 @@ export interface MessageItemPropTypes extends CommonProps {
5757
*/
5858
const MessageItem = forwardRef<CustomListItemDomRef, MessageItemPropTypes>((props, ref) => {
5959
const { titleText, subtitleText, counter, type = ValueState.Error, children, className, ...rest } = props;
60+
const [isTitleTextOverflowing, setIsTitleTextIsOverflowing] = useState(false);
61+
const titleTextRef = useRef<HTMLSpanElement>(null);
62+
const hasDetails = !!(children || isTitleTextOverflowing);
6063

6164
useStylesheet(styleData, MessageItem.displayName);
6265

@@ -69,10 +72,10 @@ const MessageItem = forwardRef<CustomListItemDomRef, MessageItemPropTypes>((prop
6972
subtitleText && classNames.withSubtitle
7073
);
7174

72-
const messageClasses = clsx(classNames.message, children && classNames.withChildren);
75+
const messageClasses = clsx(classNames.message, hasDetails && classNames.withChildren);
7376

7477
const handleListItemClick = (e) => {
75-
if (children) {
78+
if (hasDetails) {
7679
selectMessage(props);
7780
if (typeof rest.onClick === 'function') {
7881
rest.onClick(e);
@@ -88,13 +91,31 @@ const MessageItem = forwardRef<CustomListItemDomRef, MessageItemPropTypes>((prop
8891
handleListItemClick(e);
8992
}
9093
};
94+
95+
const hasChildren = Children.count(children);
96+
useEffect(() => {
97+
const titleTextObserver = new ResizeObserver(([titleTextSpan]) => {
98+
if (titleTextSpan.target.scrollWidth > titleTextSpan.target.clientWidth) {
99+
setIsTitleTextIsOverflowing(true);
100+
} else {
101+
setIsTitleTextIsOverflowing(false);
102+
}
103+
});
104+
if (!hasChildren && titleTextRef.current) {
105+
titleTextObserver.observe(titleTextRef.current);
106+
}
107+
return () => {
108+
titleTextObserver.disconnect();
109+
};
110+
}, [hasChildren]);
111+
91112
return (
92113
<CustomListItem
93114
onClick={handleListItemClick}
94115
onKeyDown={handleKeyDown}
95116
data-title={titleText}
96117
data-type={type}
97-
type={children ? ListItemType.Active : ListItemType.Inactive}
118+
type={hasDetails ? ListItemType.Active : ListItemType.Inactive}
98119
{...rest}
99120
className={listItemClasses}
100121
ref={ref}
@@ -107,11 +128,15 @@ const MessageItem = forwardRef<CustomListItemDomRef, MessageItemPropTypes>((prop
107128
direction={FlexBoxDirection.Column}
108129
style={{ flex: 'auto', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}
109130
>
110-
{titleText && <span className={classNames.title}>{titleText}</span>}
111-
{subtitleText && <Label className={classNames.subtitle}>{subtitleText}</Label>}
131+
{titleText && (
132+
<span className={classNames.title} ref={titleTextRef}>
133+
{titleText}
134+
</span>
135+
)}
136+
{titleText && subtitleText && <Label className={classNames.subtitle}>{subtitleText}</Label>}
112137
</FlexBox>
113138
{counter != null && <span className={classNames.counter}>{counter}</span>}
114-
{children && <Icon className={classNames.navigation} name={iconArrowRight} />}
139+
{hasDetails && <Icon className={classNames.navigation} name={iconArrowRight} />}
115140
</FlexBox>
116141
</CustomListItem>
117142
);

packages/main/src/components/MessageView/MessageView.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ function MyComponent() {
5353
const [isOnDetailsPage, setIsOnDetailsPage] = useState(false);
5454
return (
5555
<Dialog
56+
resizable
5657
style={{ width: '500px' }}
5758
className="modal-without-padding"
5859
header={

packages/main/src/components/MessageView/MessageView.stories.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,13 @@ const meta = {
7777
type={ValueState.Warning}
7878
counter={3}
7979
/>,
80-
<MessageItem key={4} titleText={'Empty Message Type'} groupName={'Products'} />,
80+
<MessageItem
81+
key={4}
82+
titleText={
83+
'Long Empty Message Type (no title, no subtitle, no children/details) - The details view is only available if the `titleText` is not fully visible. It is NOT recommended to use long titles!'
84+
}
85+
groupName={'Products'}
86+
/>,
8187
<MessageItem
8288
key={5}
8389
titleText={'Information Message Type without subtitle'}
@@ -119,6 +125,7 @@ export const MessageViewInDialog: Story = {
119125
</Button>
120126
<Dialog
121127
ref={dialogRef}
128+
resizable
122129
style={{ width: '500px' }}
123130
className="contentPartNoPadding headerPartNoPadding"
124131
header={

0 commit comments

Comments
 (0)