Skip to content

Commit

Permalink
feat: new way to create multiline overflowable text
Browse files Browse the repository at this point in the history
Signed-off-by: LE SAULNIER Kevin <kevin.lesaulnier@rte-france.com>
  • Loading branch information
LE SAULNIER Kevin committed May 15, 2024
1 parent f74143c commit 15bdb22
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
8 changes: 8 additions & 0 deletions demo/src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,14 @@ const AppContent = ({ language, onLanguageClick }) => {
border: '1px solid black',
}}
/>
<OverflowableText
text={overflowableText}
numberOfLinesToDisplay={2}
style={{
width: '200px',
border: '1px solid black',
}}
/>
</div>
<hr />
<div
Expand Down
48 changes: 41 additions & 7 deletions src/components/OverflowableText/overflowable-text.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { Box, Tooltip } from '@mui/material';
import PropTypes from 'prop-types';
import { styled } from '@mui/system';
Expand All @@ -23,20 +23,48 @@ const overflowStyle = {
},
};

const multilineOverflowStyle = (numberOfLinesToDisplay) => ({
overflow: 'hidden',
display: '-webkit-box',
WebkitLineClamp: numberOfLinesToDisplay /* number of lines to show */,
lineClamp: numberOfLinesToDisplay,
WebkitBoxOrient: 'vertical',
});

export const OverflowableText = styled(
({ text, tooltipStyle, tooltipSx, className, children, ...props }) => {
({
text,
maxLineCount, // overflowable text can be displayed on several lines if this is set to a number > 1
tooltipStyle,
tooltipSx,
className,
children,
...props
}) => {
const element = useRef();

const isMultiLine = useMemo(
() => maxLineCount && maxLineCount > 1,
[maxLineCount]
);

const [overflowed, setOverflowed] = useState(false);

const checkOverflow = useCallback(() => {
if (!element.current) {
return;
}
setOverflowed(
element.current.scrollWidth > element.current.clientWidth
);
}, [setOverflowed, element]);

if (isMultiLine) {
setOverflowed(
element.current.scrollHeight > element.current.clientHeight
);
} else {
setOverflowed(
element.current.scrollWidth > element.current.clientWidth
);
}
}, [isMultiLine, setOverflowed, element]);

useLayoutEffect(() => {
checkOverflow();
Expand All @@ -45,6 +73,8 @@ export const OverflowableText = styled(
text,
element.current?.scrollWidth,
element.current?.clientWidth,
element.current?.scrollHeight,
element.current?.clientHeight,
]);

const defaultTooltipSx = !tooltipStyle ? overflowStyle.tooltip : false;
Expand All @@ -71,7 +101,11 @@ export const OverflowableText = styled(
ref={element}
children={children || text}
className={className}
sx={overflowStyle.overflow}
sx={
isMultiLine
? multilineOverflowStyle(maxLineCount)
: overflowStyle.overflow
}
/>
</Tooltip>
);
Expand Down
1 change: 1 addition & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ export const FlatParameters: FunctionComponent<FlatParametersProps>;
interface OverflowableTextProps {
sx?: SxProps;
text?: string | ReactElement;
maxLineCount?: number;
}

export const OverflowableText: FunctionComponent<OverflowableTextProps>;
Expand Down

0 comments on commit 15bdb22

Please sign in to comment.