Dynamically truncate the Account's name/username in hidden content
This commit is contained in:
parent
1a4cc5bdc9
commit
7e17772c14
5 changed files with 38 additions and 15 deletions
|
@ -4,7 +4,7 @@ import { Link } from 'react-router-dom';
|
|||
import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper';
|
||||
import VerificationBadge from 'soapbox/components/verification_badge';
|
||||
import ActionButton from 'soapbox/features/ui/components/action_button';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppSelector, useOnScreen } from 'soapbox/hooks';
|
||||
import { getAcct } from 'soapbox/utils/accounts';
|
||||
import { displayFqn } from 'soapbox/utils/state';
|
||||
|
||||
|
@ -52,8 +52,9 @@ const Account = ({
|
|||
timestampUrl,
|
||||
withRelationship = true,
|
||||
}: IAccount) => {
|
||||
const overflowRef = React.useRef(null);
|
||||
const actionRef = React.useRef(null);
|
||||
const overflowRef = React.useRef<HTMLDivElement>(null);
|
||||
const actionRef = React.useRef<HTMLDivElement>(null);
|
||||
const isOnScreen = useOnScreen(overflowRef);
|
||||
|
||||
const [style, setStyle] = React.useState<React.CSSProperties>({ visibility: 'hidden' });
|
||||
|
||||
|
@ -93,18 +94,19 @@ const Account = ({
|
|||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
const style: React.CSSProperties = {};
|
||||
if (isOnScreen) {
|
||||
const style: React.CSSProperties = {};
|
||||
const actionWidth = actionRef.current?.clientWidth;
|
||||
|
||||
const actionWidth = actionRef.current?.clientWidth;
|
||||
if (overflowRef.current) {
|
||||
style.maxWidth = overflowRef.current.clientWidth - 30 - avatarSize - actionWidth;
|
||||
} else {
|
||||
style.visibility = 'hidden';
|
||||
}
|
||||
|
||||
if (overflowRef.current) {
|
||||
style.maxWidth = overflowRef.current.clientWidth - 30 - avatarSize - actionWidth;
|
||||
} else {
|
||||
style.visibility = 'hidden';
|
||||
setStyle(style);
|
||||
}
|
||||
|
||||
setStyle(style);
|
||||
}, [overflowRef, actionRef]);
|
||||
}, [isOnScreen, overflowRef, actionRef]);
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
|
@ -161,8 +163,8 @@ const Account = ({
|
|||
</LinkEl>
|
||||
</ProfilePopper>
|
||||
|
||||
<HStack alignItems='center' space={1}>
|
||||
<Text theme='muted' size='sm'>@{username}</Text>
|
||||
<HStack alignItems='center' space={1} style={style}>
|
||||
<Text theme='muted' size='sm' truncate>@{username}</Text>
|
||||
|
||||
{(timestamp) ? (
|
||||
<>
|
||||
|
|
|
@ -29,6 +29,7 @@ interface IHStack {
|
|||
justifyContent?: 'between' | 'center',
|
||||
space?: 0.5 | 1 | 1.5 | 2 | 3 | 4 | 6,
|
||||
grow?: boolean,
|
||||
style?: React.CSSProperties
|
||||
}
|
||||
|
||||
const HStack: React.FC<IHStack> = (props) => {
|
||||
|
|
|
@ -116,7 +116,7 @@ const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children }) => {
|
|||
const itemProps = menuItem.action ? { onSelect: menuItem.action } : { to: menuItem.to, as: Link };
|
||||
|
||||
return (
|
||||
<Comp key={idx} {...itemProps}>
|
||||
<Comp key={idx} {...itemProps} className='truncate'>
|
||||
{menuItem.text}
|
||||
</Comp>
|
||||
);
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export { useAppSelector } from './useAppSelector';
|
||||
export { useOnScreen } from './useOnScreen';
|
||||
|
|
19
app/soapbox/hooks/useOnScreen.ts
Normal file
19
app/soapbox/hooks/useOnScreen.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import * as React from 'react';
|
||||
|
||||
export const useOnScreen = (ref: React.MutableRefObject<HTMLElement>) => {
|
||||
const [isIntersecting, setIntersecting] = React.useState(false);
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => setIntersecting(entry.isIntersecting),
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
observer.observe(ref.current);
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return isIntersecting;
|
||||
};
|
Loading…
Reference in a new issue