forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/Expensify/App into feat/#Ex…
…pensify#23132-display-status-lhn
- Loading branch information
Showing
17 changed files
with
265 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import PropTypes from 'prop-types'; | ||
import React, {useCallback} from 'react'; | ||
import styles from '../../styles/styles'; | ||
import Text from '../Text'; | ||
import UserDetailsTooltip from '../UserDetailsTooltip'; | ||
|
||
const propTypes = { | ||
index: PropTypes.number, | ||
|
||
/** The full title of the DisplayNames component (not split up) */ | ||
getTooltipShiftX: PropTypes.func, | ||
|
||
/** The Account ID for the tooltip */ | ||
accountID: PropTypes.number, | ||
|
||
/** The name to display in bold */ | ||
displayName: PropTypes.string, | ||
|
||
/** The login for the tooltip fallback */ | ||
login: PropTypes.string, | ||
|
||
/** The avatar for the tooltip fallback */ | ||
avatar: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), | ||
|
||
/** Arbitrary styles of the displayName text */ | ||
// eslint-disable-next-line react/forbid-prop-types | ||
textStyles: PropTypes.arrayOf(PropTypes.object), | ||
|
||
/** Refs to all the names which will be used to correct the horizontal position of the tooltip */ | ||
childRefs: PropTypes.shape({ | ||
// eslint-disable-next-line react/forbid-prop-types | ||
current: PropTypes.arrayOf(PropTypes.object), | ||
}), | ||
}; | ||
|
||
const defaultProps = { | ||
index: 0, | ||
getTooltipShiftX: () => {}, | ||
accountID: 0, | ||
displayName: '', | ||
login: '', | ||
avatar: '', | ||
textStyles: [], | ||
childRefs: {current: []}, | ||
}; | ||
|
||
function DisplayNamesTooltipItem({index, getTooltipShiftX, accountID, avatar, login, displayName, textStyles, childRefs}) { | ||
const tooltipIndexBridge = useCallback(() => getTooltipShiftX(index), [getTooltipShiftX, index]); | ||
|
||
return ( | ||
<UserDetailsTooltip | ||
key={index} | ||
accountID={accountID} | ||
fallbackUserDetails={{ | ||
avatar, | ||
login, | ||
displayName, | ||
}} | ||
shiftHorizontal={tooltipIndexBridge} | ||
> | ||
{/* We need to get the refs to all the names which will be used to correct the horizontal position of the tooltip */} | ||
<Text | ||
eslint-disable-next-line | ||
no-param-reassign | ||
// eslint-disable-next-line no-param-reassign | ||
ref={(el) => (childRefs.current[index] = el)} | ||
style={[...textStyles, styles.pre]} | ||
> | ||
{displayName} | ||
</Text> | ||
</UserDetailsTooltip> | ||
); | ||
} | ||
|
||
DisplayNamesTooltipItem.propTypes = propTypes; | ||
DisplayNamesTooltipItem.defaultProps = defaultProps; | ||
DisplayNamesTooltipItem.displayName = 'DisplayNamesTooltipItem'; | ||
|
||
export default DisplayNamesTooltipItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import React, {Fragment, useCallback, useEffect, useRef, useState} from 'react'; | ||
import {View} from 'react-native'; | ||
import _ from 'underscore'; | ||
import styles from '../../styles/styles'; | ||
import Text from '../Text'; | ||
import Tooltip from '../Tooltip'; | ||
import DisplayNamesTooltipItem from './DisplayNamesTooltipItem'; | ||
import {defaultProps, propTypes} from './displayNamesPropTypes'; | ||
|
||
function DisplayNamesWithToolTip(props) { | ||
const containerRef = useRef(null); | ||
const childRefs = useRef([]); | ||
const [isEllipsisActive, setIsEllipsisActive] = useState(false); | ||
|
||
useEffect(() => { | ||
setIsEllipsisActive( | ||
containerRef.current && containerRef.current.offsetWidth && containerRef.current.scrollWidth && containerRef.current.offsetWidth < containerRef.current.scrollWidth, | ||
); | ||
}, []); | ||
|
||
/** | ||
* We may need to shift the Tooltip horizontally as some of the inline text wraps well with ellipsis, | ||
* but their container node overflows the parent view which causes the tooltip to be misplaced. | ||
* | ||
* 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 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 | ||
*/ | ||
const getTooltipShiftX = useCallback((index) => { | ||
// Only shift the tooltip in case the containerLayout or Refs to the text node are available | ||
if (!containerRef || !childRefs.current[index]) { | ||
return; | ||
} | ||
const {width: containerWidth, left: containerLeft} = containerRef.current.getBoundingClientRect(); | ||
|
||
// We have to return the value as Number so we can't use `measureWindow` which takes a callback | ||
const {width: textNodeWidth, left: textNodeLeft} = childRefs.current[index].getBoundingClientRect(); | ||
const tooltipX = textNodeWidth / 2 + textNodeLeft; | ||
const containerRight = containerWidth + containerLeft; | ||
const textNodeRight = textNodeWidth + textNodeLeft; | ||
const newToolX = textNodeLeft + (containerRight - textNodeLeft) / 2; | ||
|
||
// When text right end is beyond the Container right end | ||
return textNodeRight > containerRight ? -(tooltipX - newToolX) : 0; | ||
}, []); | ||
|
||
return ( | ||
// Tokenization of string only support prop numberOfLines on Web | ||
<Text | ||
style={[...props.textStyles, styles.pRelative]} | ||
numberOfLines={props.numberOfLines || undefined} | ||
ref={(el) => (containerRef.current = el)} | ||
> | ||
{props.shouldUseFullTitle | ||
? props.fullTitle | ||
: _.map(props.displayNamesWithTooltips, ({displayName, accountID, avatar, login}, index) => ( | ||
<Fragment key={index}> | ||
<DisplayNamesTooltipItem | ||
index={index} | ||
getTooltipShiftX={getTooltipShiftX} | ||
accountID={accountID} | ||
displayName={displayName} | ||
login={login} | ||
avatar={avatar} | ||
textStyles={props.textStyles} | ||
childRefs={childRefs} | ||
addComma={index < props.displayNamesWithTooltips.length - 1} | ||
/> | ||
{index < props.displayNamesWithTooltips.length - 1 && <Text style={props.textStyles}>, </Text>} | ||
</Fragment> | ||
))} | ||
{Boolean(isEllipsisActive) && ( | ||
<View style={styles.displayNameTooltipEllipsis}> | ||
<Tooltip text={props.fullTitle}> | ||
{/* There is some Gap for real ellipsis so we are adding 4 `.` to cover */} | ||
<Text>....</Text> | ||
</Tooltip> | ||
</View> | ||
)} | ||
</Text> | ||
); | ||
} | ||
|
||
DisplayNamesWithToolTip.propTypes = propTypes; | ||
DisplayNamesWithToolTip.defaultProps = defaultProps; | ||
DisplayNamesWithToolTip.displayName = 'DisplayNamesWithTooltip'; | ||
|
||
export default DisplayNamesWithToolTip; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import styles from '../../styles/styles'; | ||
import Text from '../Text'; | ||
|
||
const propTypes = { | ||
/** The full title of the DisplayNames component (not split up) */ | ||
fullTitle: PropTypes.string, | ||
|
||
/** Arbitrary styles of the displayName text */ | ||
// eslint-disable-next-line react/forbid-prop-types | ||
textStyles: PropTypes.arrayOf(PropTypes.object), | ||
|
||
/** Number of lines before wrapping */ | ||
numberOfLines: PropTypes.number, | ||
}; | ||
|
||
const defaultProps = { | ||
fullTitle: '', | ||
textStyles: [], | ||
numberOfLines: 1, | ||
}; | ||
|
||
function DisplayNamesWithoutTooltip({textStyles, numberOfLines, fullTitle}) { | ||
return ( | ||
<Text | ||
style={[...textStyles, numberOfLines === 1 ? styles.pre : styles.preWrap]} | ||
numberOfLines={numberOfLines} | ||
> | ||
{fullTitle} | ||
</Text> | ||
); | ||
} | ||
|
||
DisplayNamesWithoutTooltip.propTypes = propTypes; | ||
DisplayNamesWithoutTooltip.defaultProps = defaultProps; | ||
DisplayNamesWithoutTooltip.displayName = 'DisplayNamesWithoutTooltip'; | ||
|
||
export default DisplayNamesWithoutTooltip; |
Oops, something went wrong.