Skip to content

Commit dba28ce

Browse files
authoredJul 5, 2024
fix(MessageViewItem): enable details view if titleText is overflowing (#6015)
Fixes #5990
1 parent 0e6a326 commit dba28ce

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed
 

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

+32-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import iconArrowRight from '@ui5/webcomponents-icons/dist/slim-arrow-right.js';
66
import { useStylesheet } from '@ui5/webcomponents-react-base';
77
import { clsx } from 'clsx';
88
import type { ReactNode } from 'react';
9-
import { forwardRef, useContext } from 'react';
9+
import { Children, forwardRef, useContext, useEffect, useRef, useState } from 'react';
1010
import { FlexBoxAlignItems, FlexBoxDirection } from '../../enums/index.js';
1111
import { MessageViewContext } from '../../internal/MessageViewContext.js';
1212
import type { CommonProps } from '../../types/index.js';
@@ -59,6 +59,9 @@ export interface MessageItemPropTypes extends CommonProps {
5959
*/
6060
const MessageItem = forwardRef<ListItemCustomDomRef, MessageItemPropTypes>((props, ref) => {
6161
const { titleText, subtitleText, counter, type = ValueState.Negative, children, className, ...rest } = props;
62+
const [isTitleTextOverflowing, setIsTitleTextIsOverflowing] = useState(false);
63+
const titleTextRef = useRef<HTMLSpanElement>(null);
64+
const hasDetails = !!(children || isTitleTextOverflowing);
6265

6366
useStylesheet(styleData, MessageItem.displayName);
6467

@@ -71,10 +74,10 @@ const MessageItem = forwardRef<ListItemCustomDomRef, MessageItemPropTypes>((prop
7174
subtitleText && classNames.withSubtitle
7275
);
7376

74-
const messageClasses = clsx(classNames.message, children && classNames.withChildren);
77+
const messageClasses = clsx(classNames.message, hasDetails && classNames.withChildren);
7578

7679
const handleListItemClick = (e) => {
77-
if (children) {
80+
if (hasDetails) {
7881
selectMessage(props);
7982
if (typeof rest.onClick === 'function') {
8083
rest.onClick(e);
@@ -90,13 +93,31 @@ const MessageItem = forwardRef<ListItemCustomDomRef, MessageItemPropTypes>((prop
9093
handleListItemClick(e);
9194
}
9295
};
96+
97+
const hasChildren = Children.count(children);
98+
useEffect(() => {
99+
const titleTextObserver = new ResizeObserver(([titleTextSpan]) => {
100+
if (titleTextSpan.target.scrollWidth > titleTextSpan.target.clientWidth) {
101+
setIsTitleTextIsOverflowing(true);
102+
} else {
103+
setIsTitleTextIsOverflowing(false);
104+
}
105+
});
106+
if (!hasChildren && titleTextRef.current) {
107+
titleTextObserver.observe(titleTextRef.current);
108+
}
109+
return () => {
110+
titleTextObserver.disconnect();
111+
};
112+
}, [hasChildren]);
113+
93114
return (
94115
<ListItemCustom
95116
onClick={handleListItemClick}
96117
onKeyDown={handleKeyDown}
97118
data-title={titleText}
98119
data-type={type}
99-
type={children ? ListItemType.Active : ListItemType.Inactive}
120+
type={hasDetails ? ListItemType.Active : ListItemType.Inactive}
100121
{...rest}
101122
className={listItemClasses}
102123
ref={ref}
@@ -109,11 +130,15 @@ const MessageItem = forwardRef<ListItemCustomDomRef, MessageItemPropTypes>((prop
109130
direction={FlexBoxDirection.Column}
110131
style={{ flex: 'auto', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}
111132
>
112-
{titleText && <span className={classNames.title}>{titleText}</span>}
113-
{subtitleText && <Label className={classNames.subtitle}>{subtitleText}</Label>}
133+
{titleText && (
134+
<span className={classNames.title} ref={titleTextRef}>
135+
{titleText}
136+
</span>
137+
)}
138+
{titleText && subtitleText && <Label className={classNames.subtitle}>{subtitleText}</Label>}
114139
</FlexBox>
115140
{counter != null && <span className={classNames.counter}>{counter}</span>}
116-
{children && <Icon className={classNames.navigation} name={iconArrowRight} />}
141+
{hasDetails && <Icon className={classNames.navigation} name={iconArrowRight} />}
117142
</FlexBox>
118143
</ListItemCustom>
119144
);

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

+1
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

+8-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,13 @@ const meta = {
8282
type={ValueState.Critical}
8383
counter={3}
8484
/>,
85-
<MessageItem key={4} titleText={'Empty Message Type'} groupName={'Products'} />,
85+
<MessageItem
86+
key={4}
87+
titleText={
88+
'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!'
89+
}
90+
groupName={'Products'}
91+
/>,
8692
<MessageItem
8793
key={5}
8894
titleText={'Information Message Type without subtitle'}
@@ -123,6 +129,7 @@ export const MessageViewInDialog: Story = {
123129
Open Dialog
124130
</Button>
125131
<Dialog
132+
resizable
126133
style={{ width: '500px' }}
127134
className="contentPartNoPadding headerPartNoPadding"
128135
open={open}

0 commit comments

Comments
 (0)