Skip to content

Commit

Permalink
fix: Fixing word break for large description option answers (M2-8267) (
Browse files Browse the repository at this point in the history
…#562)

* fix: fixing word break for large description option answers

* fix: fixing long words issue breaking the layout

* fix: fixing long words issue breaking the layout

* fix: corrects wrongly generated line breaks detected in qa

* fix: update word break and hyphenation styles in SelectBaseText component to prevent word break

* fix: creates a hook to wrap words larger than 15 characters

* fix: removing unused index on loop

* fix: add space after customWrap words

* revert RegularGrid changes

---------

Co-authored-by: Ramir Mesquita <[email protected]>
Co-authored-by: Carlos Chacon <[email protected]>
  • Loading branch information
3 people authored Jan 23, 2025
1 parent d2c4648 commit b7a1f5c
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 3 deletions.
17 changes: 14 additions & 3 deletions src/shared/ui/Items/SelectBase/SelectBaseText.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Theme } from '~/shared/constants';
import Text from '~/shared/ui/Text';
import { useCustomWordWrap } from '~/shared/utils/hooks/useCustomWordWrap';

type Props = {
text: string;
};

export const SelectBaseText = (props: Props) => {
const { processedWords } = useCustomWordWrap(props.text);

return (
<Text
variant="body1"
Expand All @@ -15,10 +18,10 @@ export const SelectBaseText = (props: Props) => {
lineHeight="28px"
testid="select-text"
sx={{
wordBreak: 'none',
cursor: 'pointer',
lineBreak: 'anywhere',
lineBreak: 'normal',
display: '-webkit-box',
overflow: 'hidden',

// Using kebab-case (i.e. `-webkit-some-things`) would cause warnings
// in the JS console about kebab-case being not supported for CSS
Expand All @@ -27,7 +30,15 @@ export const SelectBaseText = (props: Props) => {
webkitBoxOrient: 'vertical',
}}
>
{props.text}
{processedWords.map(({ word, needsWrap, ref }, index) => {
return needsWrap ? (
<span ref={ref} style={{ wordBreak: 'break-word' }} key={index}>
{`${word} `}
</span>
) : (
`${word} `
);
})}
</Text>
);
};
76 changes: 76 additions & 0 deletions src/shared/utils/hooks/useCustomWordWrap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useEffect, useRef, useState } from 'react';

export const useCustomWordWrap = (text: string) => {
const textAsArray = text.split(' ');
const mustBreakWord = useRef<HTMLElement>(null);
const originalWord = useRef<string>('');
const [resize, setResize] = useState(0);
const debounceTimeout = useRef<NodeJS.Timeout>();

useEffect(() => {
const handleResize = () => {
if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current);
}

debounceTimeout.current = setTimeout(() => {
setResize((prev) => prev + 1);
}, 300);
};

window.addEventListener('resize', handleResize);

return () => {
window.removeEventListener('resize', handleResize);
if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current);
}
};
}, []);

useEffect(() => {
if (mustBreakWord.current) {
if (!originalWord.current && mustBreakWord.current.textContent) {
originalWord.current = mustBreakWord.current.textContent;
}

if (originalWord.current) {
const characters = originalWord.current.split('');
mustBreakWord.current.innerHTML = characters
.map((letter) => `<span>${letter}</span>`)
.join('');
}

const mustBreakWordCharacters = Array.from(mustBreakWord.current.children);
for (let i = 0; i < mustBreakWordCharacters.length; i++) {
const currentCharacter = mustBreakWordCharacters[i] as HTMLElement;
const previousCharacter = i > 0 ? (mustBreakWordCharacters[i - 1] as HTMLElement) : null;

if (
previousCharacter &&
!previousCharacter.innerText.includes('-') &&
currentCharacter.offsetTop > previousCharacter?.offsetTop
) {
(mustBreakWordCharacters[i - 3] as HTMLElement).innerText += '-\n';
}
}
}
}, [resize]);

const processedWords = textAsArray.map((word: string) => {
if (word.length > 15)
return {
word,
needsWrap: true,
ref: mustBreakWord,
};

return {
word,
needsWrap: false,
ref: null,
};
});

return { processedWords };
};

0 comments on commit b7a1f5c

Please sign in to comment.