Skip to content

Commit

Permalink
feat: Added scrolling text animation for long headings.
Browse files Browse the repository at this point in the history
  • Loading branch information
vagarenko committed Jun 30, 2023
1 parent a1effb3 commit 2d6a994
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 17 deletions.
82 changes: 82 additions & 0 deletions pkg/webui/ui/src/components/ScrollingTextLine.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { useCallback, useRef, useState } from "react";
import { Box, Typography, TypographyProps, keyframes } from "@mui/material"

export type ScrollingTextLineProps = Omit<TypographyProps, 'children'> & {
children: string;
scrollPadding?: number;
scrollSpeed?: number;
}

export const ScrollingTextLine = React.forwardRef((
props: ScrollingTextLineProps,
forwardedRef: React.ForwardedRef<HTMLElement>
) => {
const {
children,
scrollPadding = 10,
scrollSpeed = 10,
...rest
} = props;
const containerElem = useRef<HTMLElement | null>();
const scrollingElem = useRef<HTMLElement | null>();

const [containerElemWidth, setContainerElemWidth] = useState<number | undefined>();
const [scrollingElemWidth, setScrollingElemWidth] = useState<number | undefined>();

const onMouseEnter = useCallback(() => {
setContainerElemWidth(containerElem.current?.getBoundingClientRect().width);
setScrollingElemWidth(scrollingElem.current?.getBoundingClientRect().width);
}, []);

const maxScrollDistance = (containerElemWidth
&& scrollingElemWidth
&& containerElemWidth < scrollingElemWidth)
? Math.round(containerElemWidth - scrollingElemWidth)
: undefined;

const animation = maxScrollDistance !== undefined
? keyframes`
from {
translate: ${scrollPadding}px;
}
to {
translate: ${maxScrollDistance - scrollPadding}px;
}
`
: undefined;

const duration = children.length / scrollSpeed;

return <Typography
textAlign='left'
textOverflow='ellipsis'
overflow='hidden'
whiteSpace='nowrap'
{...rest}
ref={(r) => {
if (typeof forwardedRef === 'function') {
forwardedRef(r);
} else if (forwardedRef !== null) {
forwardedRef.current = r;
}
containerElem.current = r;
}}
>
<Box
component='span'
sx={{
display: 'inline',
'&:hover': {
display: 'inline-block',
...(animation && {
animation: `${animation} ${duration}s infinite alternate linear`
})
},
}}
ref={scrollingElem}
onMouseEnter={onMouseEnter}
>
{children}
</Box>
</Typography>;
});
35 changes: 18 additions & 17 deletions pkg/webui/ui/src/components/targets-view/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from "react";
import { Box, BoxProps, Divider, IconButton, Paper, PaperProps, Tab, Tooltip, Typography } from "@mui/material"
import { Box, BoxProps, Divider, IconButton, Paper, PaperProps, Tab, Tooltip } from "@mui/material"
import { CloseLightIcon } from "../../icons/Icons";
import { SidePanelProvider, useSidePanelTabs } from "../result-view/SidePanel";
import { TabContext, TabList, TabPanel } from "@mui/lab";
import { ScrollingTextLine } from "../ScrollingTextLine";

export const cardWidth = 247;
export const projectCardMinHeight = 80;
Expand Down Expand Up @@ -67,34 +68,28 @@ export const CardTemplate = React.forwardRef((props: {
);

const header = props.header && (
<Tooltip title={props.headerTooltip}>
<Typography
<Tooltip title={props.headerTooltip} placement='bottom-start'>
<ScrollingTextLine
variant='h6'
textAlign='left'
textOverflow='ellipsis'
overflow='hidden'
flexGrow={1}
lineHeight='27px'
height='27px'
>
{props.header}
</Typography>
</ScrollingTextLine>
</Tooltip>
);

const subheader = props.subheader && (
<Tooltip title={props.subheaderTooltip}>
<Typography
<Tooltip title={props.subheaderTooltip} placement='bottom-start'>
<ScrollingTextLine
variant='subtitle1'
textAlign='left'
textOverflow='ellipsis'
overflow='hidden'
whiteSpace='nowrap'
fontSize='14px'
fontWeight={500}
lineHeight='19px'
width='max-content'
height='19px'
>
{props.subheader}
</Typography>
</ScrollingTextLine>
</Tooltip>
);

Expand Down Expand Up @@ -130,7 +125,13 @@ export const CardTemplate = React.forwardRef((props: {
>
<Box flex='0 0 auto' display='flex' gap='15px'>
{icon}
<Box flex='1 1 auto'>
<Box
flex='1 1 auto'
display='flex'
flexDirection='column'
overflow='hidden'
justifyContent='center'
>
{header}
{subheader}
</Box>
Expand Down

0 comments on commit 2d6a994

Please sign in to comment.