diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f5cd502f6..5c2c35ec6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -71,3 +71,35 @@ jobs:
env:
REACT_APP_API_DOMAIN: http://localhost:8080
run: yarn test
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Remove .yarnrc file to avoid conflicts
+ run: rm -rf .yarnrc
+
+ - name: Enable Corepack
+ run: corepack enable
+
+ - name: Prepare and activate Yarn version 1.22.22
+ run: corepack prepare yarn@1.22.22 --activate
+
+ - name: Verify Yarn version
+ run: yarn --version
+
+ - uses: actions/cache@v4
+ with:
+ path: |
+ ~/node_modules
+ key: ${{ runner.os }}-node-modules-${{ hashFiles('**/yarn.lock') }}
+
+ - name: Install dependencies with frozen lockfile
+ run: yarn install --frozen-lockfile
+
+ - name: Build web app
+ run: yarn build
diff --git a/src/shared/ui/Items/SelectBase/SelectBaseText.tsx b/src/shared/ui/Items/SelectBase/SelectBaseText.tsx
index 00c983805..513c28984 100644
--- a/src/shared/ui/Items/SelectBase/SelectBaseText.tsx
+++ b/src/shared/ui/Items/SelectBase/SelectBaseText.tsx
@@ -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 (
{
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
@@ -27,7 +30,15 @@ export const SelectBaseText = (props: Props) => {
webkitBoxOrient: 'vertical',
}}
>
- {props.text}
+ {processedWords.map(({ word, needsWrap, ref }, index) => {
+ return needsWrap ? (
+
+ {`${word} `}
+
+ ) : (
+ `${word} `
+ );
+ })}
);
};
diff --git a/src/shared/utils/hooks/useCustomWordWrap.ts b/src/shared/utils/hooks/useCustomWordWrap.ts
new file mode 100644
index 000000000..5244f2a89
--- /dev/null
+++ b/src/shared/utils/hooks/useCustomWordWrap.ts
@@ -0,0 +1,76 @@
+import { useEffect, useRef, useState } from 'react';
+
+export const useCustomWordWrap = (text: string) => {
+ const textAsArray = text.split(' ');
+ const mustBreakWord = useRef(null);
+ const originalWord = useRef('');
+ const [resize, setResize] = useState(0);
+ const debounceTimeout = useRef();
+
+ 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) => `${letter}`)
+ .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 };
+};