diff --git a/src/components/DisplayNames/displayNamesPropTypes.js b/src/components/DisplayNames/displayNamesPropTypes.js
new file mode 100644
index 000000000000..5a94673a9bfa
--- /dev/null
+++ b/src/components/DisplayNames/displayNamesPropTypes.js
@@ -0,0 +1,33 @@
+import PropTypes from 'prop-types';
+
+const propTypes = {
+ // The full title of the DisplayNames component (not split up)
+ fullTitle: PropTypes.string,
+
+ // Array of objects that map display names to their corresponding tooltip
+ displayNamesWithTooltips: PropTypes.arrayOf(PropTypes.shape({
+ // The name to display in bold
+ displayName: PropTypes.string,
+
+ // The tooltip to show when the associated name is hovered
+ tooltip: PropTypes.string,
+ })),
+
+ // Number of lines before wrapping
+ numberOfLines: PropTypes.number,
+
+ // Is tooltip needed?
+ // When true, triggers complex title rendering
+ tooltipEnabled: PropTypes.bool,
+
+ // Arbitrary styles of the displayName text
+ textStyles: PropTypes.arrayOf(PropTypes.any),
+};
+
+const defaultProps = {
+ numberOfLines: 1,
+ tooltipEnabled: false,
+ titleStyles: [],
+};
+
+export {propTypes, defaultProps};
diff --git a/src/pages/home/sidebar/OptionRowTitle/index.js b/src/components/DisplayNames/index.js
similarity index 67%
rename from src/pages/home/sidebar/OptionRowTitle/index.js
rename to src/components/DisplayNames/index.js
index 9f887f2a65d2..72f89e6f1e22 100644
--- a/src/pages/home/sidebar/OptionRowTitle/index.js
+++ b/src/components/DisplayNames/index.js
@@ -1,15 +1,11 @@
import _ from 'underscore';
import React, {Fragment, PureComponent} from 'react';
-import {
- Text,
- View,
-} from 'react-native';
-import {propTypes, defaultProps} from './OptionRowTitleProps';
-import styles from '../../../../styles/styles';
-import Tooltip from '../../../../components/Tooltip';
-import hasEllipsis from '../../../../libs/hasEllipsis';
+import {Text, View} from 'react-native';
+import {propTypes, defaultProps} from './displayNamesPropTypes';
+import styles from '../../styles/styles';
+import Tooltip from '../Tooltip';
-class OptionRowTitle extends PureComponent {
+class DisplayNames extends PureComponent {
constructor(props) {
super(props);
this.containerRef = null;
@@ -23,7 +19,10 @@ class OptionRowTitle extends PureComponent {
componentDidMount() {
this.setState({
- isEllipsisActive: this.containerRef && hasEllipsis(this.containerRef),
+ isEllipsisActive: this.containerRef
+ && this.containerRef.offsetWidth
+ && this.containerRef.scrollWidth
+ && this.containerRef.offsetWidth < this.containerRef.scrollWidth,
});
}
@@ -31,7 +30,6 @@ class OptionRowTitle extends PureComponent {
* Set the container layout for post calculations
*
* @param {*} {nativeEvent}
- * @memberof OptionRowTitle
*/
setContainerLayout({nativeEvent}) {
this.containerLayout = nativeEvent.layout;
@@ -44,11 +42,10 @@ class OptionRowTitle extends PureComponent {
* So we shift it by calculating it as follows:
* 1. We get the container layout and take the Child inline text node.
* 2. Now we get the tooltip original position.
- * 3. If inline node's right edge is overflowing the containe's right edge, we set the tooltip to the center
+ * 3. If inline node's right edge is overflowing the container's right edge, we set the tooltip to the center
* of the distance between the left edge of the inline node and right edge of the container.
* @param {Number} index Used to get the Ref to the node at the current index.
* @returns {Number} Distance to shift the tooltip horizontally
- * @memberof OptionRowTitle
*/
getTooltipShiftX(index) {
// Only shift when containerLayout or Refs to text node is available .
@@ -70,43 +67,48 @@ class OptionRowTitle extends PureComponent {
render() {
- const {
- option, style, tooltipEnabled, numberOfLines,
- } = this.props;
-
- if (!tooltipEnabled) {
- return {option.text};
+ if (!this.props.tooltipEnabled) {
+ // No need for any complex text-splitting, just return a simple text component
+ return (
+
+ {this.props.fullTitle}
+
+ );
}
+
return (
- // Tokenization of string only support 1 numberofLines on Web
+ // Tokenization of string only support 1 numberOfLines on Web
this.containerRef = el}
>
- {_.map(option.participantsList, (participant, index) => (
+ {_.map(this.props.displayNamesToTooltips, ({displayName, tooltip}, index) => (
this.getTooltipShiftX(index)}
>
{/* // We need to get the refs to all the names which will be used to correct
the horizontal position of the tooltip */}
this.childRefs[index] = el}>
- {participant.displayName}
+ {displayName}
- {index < option.participantsList.length - 1 && , }
+ {index < this.props.displayNamesToTooltips.length - 1 && , }
))}
- {option.participantsList.length > 1 && this.state.isEllipsisActive
+ {this.props.displayNamesToTooltips.length > 1 && this.state.isEllipsisActive
&& (
-
-
+
+
{/* There is some Gap for real ellipsis so we are adding 4 `.` to cover */}
....
@@ -116,8 +118,8 @@ class OptionRowTitle extends PureComponent {
);
}
}
-OptionRowTitle.propTypes = propTypes;
-OptionRowTitle.defaultProps = defaultProps;
-OptionRowTitle.displayName = 'OptionRowTitle';
+DisplayNames.propTypes = propTypes;
+DisplayNames.defaultProps = defaultProps;
+DisplayNames.displayName = 'DisplayNames';
-export default OptionRowTitle;
+export default DisplayNames;
diff --git a/src/components/DisplayNames/index.native.js b/src/components/DisplayNames/index.native.js
new file mode 100644
index 000000000000..8a882f8eb576
--- /dev/null
+++ b/src/components/DisplayNames/index.native.js
@@ -0,0 +1,20 @@
+import React from 'react';
+import {Text} from 'react-native';
+import {propTypes, defaultProps} from './displayNamesPropTypes';
+
+// As we don't have to show tooltips of the Native platform so we simply render the full display names list.
+const DisplayNames = ({
+ fullTitle,
+ numberOfLines,
+ textStyles,
+}) => (
+
+ {fullTitle}
+
+);
+
+DisplayNames.propTypes = propTypes;
+DisplayNames.defaultProps = defaultProps;
+DisplayNames.displayName = 'DisplayNames';
+
+export default DisplayNames;
diff --git a/src/libs/hasEllipsis/index.js b/src/libs/hasEllipsis/index.js
deleted file mode 100644
index d18af237be35..000000000000
--- a/src/libs/hasEllipsis/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * Does an elment have ellipsis
- *
- * @param {HTMLElement} el Element to check
- * @returns {Boolean}
- */
-function hasEllipsis(el) {
- return el.offsetWidth < el.scrollWidth;
-}
-
-export default hasEllipsis;
diff --git a/src/libs/hasEllipsis/index.native.js b/src/libs/hasEllipsis/index.native.js
deleted file mode 100644
index 2d1ec238274a..000000000000
--- a/src/libs/hasEllipsis/index.native.js
+++ /dev/null
@@ -1 +0,0 @@
-export default () => {};
diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js
index 40e07a82daef..d94eab3d18b6 100644
--- a/src/pages/home/HeaderView.js
+++ b/src/pages/home/HeaderView.js
@@ -1,3 +1,4 @@
+import _ from 'underscore';
import React from 'react';
import {View, Pressable} from 'react-native';
import PropTypes from 'prop-types';
@@ -15,7 +16,7 @@ import MultipleAvatars from '../../components/MultipleAvatars';
import Navigation from '../../libs/Navigation/Navigation';
import ROUTES from '../../ROUTES';
import {getReportParticipantsTitle} from '../../libs/reportUtils';
-import OptionRowTitle from './sidebar/OptionRowTitle';
+import DisplayNames from '../../components/DisplayNames';
import {getPersonalDetailsForLogins} from '../../libs/OptionsListUtils';
import {participantPropTypes} from './sidebar/optionPropTypes';
import VideoChatButtonAndMenu from '../../components/VideoChatButtonAndMenu';
@@ -53,11 +54,10 @@ const defaultProps = {
const HeaderView = (props) => {
const participants = lodashGet(props.report, 'participants', []);
- const reportOption = {
- text: lodashGet(props.report, 'reportName', ''),
- tooltipText: getReportParticipantsTitle(participants),
- participantsList: getPersonalDetailsForLogins(participants, props.personalDetails),
- };
+ const displayNamesWithTooltips = _.map(
+ getPersonalDetailsForLogins(participants, props.personalDetails),
+ ({displayName, login}) => ({displayName, tooltip: login}),
+ );
return (
@@ -92,11 +92,12 @@ const HeaderView = (props) => {
secondAvatarStyle={[styles.secondAvatarHovered]}
/>
-
diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js
index 3cc279702809..060f99c8770a 100644
--- a/src/pages/home/report/ReportActionItem.js
+++ b/src/pages/home/report/ReportActionItem.js
@@ -110,7 +110,7 @@ class ReportActionItem extends Component {
)}
>
diff --git a/src/pages/home/sidebar/OptionRow.js b/src/pages/home/sidebar/OptionRow.js
index 860b23a45090..5212a2584476 100644
--- a/src/pages/home/sidebar/OptionRow.js
+++ b/src/pages/home/sidebar/OptionRow.js
@@ -14,7 +14,7 @@ import {Pencil, PinCircle, Checkmark} from '../../../components/Icon/Expensicons
import MultipleAvatars from '../../../components/MultipleAvatars';
import themeColors from '../../../styles/themes/default';
import Hoverable from '../../../components/Hoverable';
-import OptionRowTitle from './OptionRowTitle';
+import DisplayNames from '../../../components/DisplayNames';
import IOUBadge from '../../../components/IOUBadge';
import colors from '../../../styles/colors';
@@ -109,6 +109,11 @@ const OptionRow = ({
? hoverStyle.backgroundColor
: backgroundColor;
const focusedBackgroundColor = styles.sidebarLinkActive.backgroundColor;
+ const displayNamesWithTooltips = _.map(
+ option.participantsList,
+ ({displayName, login}) => ({displayName, tooltip: login}),
+ );
+
return (
{hovered => (
@@ -152,14 +157,13 @@ const OptionRow = ({
)
}
-
-
{option.alternateText ? (
(
-
- {option.text}
-
-);
-
-OptionRowTitle.propTypes = propTypes;
-OptionRowTitle.defaultProps = defaultProps;
-OptionRowTitle.displayName = 'OptionRowTitle';
-
-export default OptionRowTitle;
diff --git a/src/styles/styles.js b/src/styles/styles.js
index fae27fd6d72c..dd3ca22b7749 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -14,6 +14,7 @@ import whiteSpace from './utilities/whiteSpace';
import wordBreak from './utilities/wordBreak';
import textInputAlignSelf from './utilities/textInputAlignSelf';
import CONST from '../CONST';
+import positioning from './utilities/positioning';
const styles = {
// Add all of our utility and helper styles
@@ -22,6 +23,7 @@ const styles = {
...flex,
...display,
...overflow,
+ ...positioning,
...wordBreak,
...whiteSpace,
@@ -601,11 +603,7 @@ const styles = {
flexShrink: 0,
},
- optionDisplayNameTooltipWrapper: {
- position: 'relative',
- },
-
- optionDisplayNameTooltipEllipsis: {
+ displayNameTooltipEllipsis: {
position: 'absolute',
opacity: 0,
right: 0,
diff --git a/src/styles/utilities/positioning.js b/src/styles/utilities/positioning.js
index 9514b8f55091..f73954241960 100644
--- a/src/styles/utilities/positioning.js
+++ b/src/styles/utilities/positioning.js
@@ -3,6 +3,9 @@
* Everything is a multiple of 4 to coincide with the spacing utilities.
*/
export default {
+ pRelative: {
+ position: 'relative',
+ },
tn4: {
top: -16,
},