fix: add tooltip and responsive wrapping for long language names (#3611) - #3657
fix: add tooltip and responsive wrapping for long language names (#3611)#3657Rkarama26 wants to merge 4 commits into
Conversation
…gee#3611) - Add tooltip on hover for full language name - Expand dropdown width for better readability - Use ellipsis on large screens, wrapping on small screens Fixes tolgee#3611
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughMenu PaperProps styling switched from inline style to MUI sx (width: 250). Language items now import and use Tooltip, wrap item content in a full-width span, remove per-MenuItem key, and apply responsive sx on ListItemText to control ellipsis and wrapping. ChangesLanguage Selector Dropdown UI
Possibly related PRs
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx (1)
86-97: 💤 Low valueConsider using MUI theme breakpoints instead of hardcoded pixel values.
The media query uses a hardcoded
600pxbreakpoint. For better maintainability and consistency with MUI's responsive design system, consider using theme breakpoints.♻️ Example using MUI theme breakpoints
<ListItemText primary={lang.name} - sx={{ + sx={(theme) => ({ '& .MuiListItemText-primary': { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', - '@media (max-width: 600px)': { + [theme.breakpoints.down('sm')]: { whiteSpace: 'normal', textOverflow: 'unset', overflow: 'visible', }, }, - }} + })} />This uses MUI's standard
smbreakpoint (typically 600px by default) but makes it more maintainable if theme breakpoints are ever customized.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx` around lines 86 - 97, Replace the hardcoded media query in the sx block inside getLanguagesContent (the styling for '& .MuiListItemText-primary') with MUI theme breakpoints; instead of '@media (max-width: 600px)' use the theme API (e.g. theme.breakpoints.down('sm')) by turning the sx entry into a callback (sx: (theme) => ({ ... [theme.breakpoints.down('sm')]: { whiteSpace: 'normal', textOverflow: 'unset', overflow: 'visible' } })) so the responsive rules follow the theme breakpoints.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx`:
- Around line 76-100: The Tooltip placed directly on the MenuItem won't show
when the MenuItem is disabled; wrap the MenuItem in a real DOM element (e.g., a
span with style display: 'inline-block') and move the Tooltip to wrap that span
so hover events fire on the wrapper while keeping the disabled prop on MenuItem;
update the JSX around Tooltip/MenuItem in getLanguagesContent (the MenuItem
using value={lang.tag}, onClick={handleLanguageChange(lang.tag)},
disabled={disabledLanguages?.includes(lang.id)} and the Checkbox/ListItemText
children) to render Tooltip->span->MenuItem instead.
---
Nitpick comments:
In `@webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx`:
- Around line 86-97: Replace the hardcoded media query in the sx block inside
getLanguagesContent (the styling for '& .MuiListItemText-primary') with MUI
theme breakpoints; instead of '@media (max-width: 600px)' use the theme API
(e.g. theme.breakpoints.down('sm')) by turning the sx entry into a callback (sx:
(theme) => ({ ... [theme.breakpoints.down('sm')]: { whiteSpace: 'normal',
textOverflow: 'unset', overflow: 'visible' } })) so the responsive rules follow
the theme breakpoints.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b09ee30f-42fb-4572-9673-3a1e98624bf9
📒 Files selected for processing (2)
webapp/src/component/common/form/LanguagesSelect/LanguagesSelect.tsxwebapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx
- Use MUI theme breakpoints instead of hardcoded 600px - Wrap MenuItem in span to fix Tooltip on disabled items
|
As seen above some backend tests are failing, |
bdshadow
left a comment
There was a problem hiding this comment.
@Rkarama26 thank you for the pull request
Failing backend tests - are just flaky; we're working on improving them.
However, there are some other real concerns about the changes. Please check the individual code comments.
Also, it would be great to show the tooltip only when the language name doesn't fit the width, and not show it for short names. Probably you can achieve this by deferring the measurement to onMouseEnter - compute scrollWidth > clientWidth lazily and toggle the tooltip open.
| style: { | ||
| width: 250, | ||
| }, | ||
| sx: (theme) => ({ |
There was a problem hiding this comment.
a theme variable is unused here, so sx can be a plain object sx: { minWidth: 200, maxWidth: 300 }
| <ListItemText primary={lang.name} /> | ||
| </MenuItem> | ||
| <Tooltip key={lang.tag} title={lang.name} placement="right"> | ||
| <span style={{ display: 'inline-block', width: '100%' }}> |
There was a problem hiding this comment.
Keyboard arrow navigation and selected highlighting is broken here. Please, try to open the dropdown, use arrow keys, press Enter to select language).
Probably keeping <MenuItem> as the direct child of the Select and rendering the <Tooltip> around the inner content (<ListItemText>) will solve it (i haven't checked it myself though)
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx (1)
75-103:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMissing
keyprop on mapped list elements.The
<span>is the root element returned from.map()but lacks akeyprop. React requires a unique key on each element in a list for correct reconciliation. This will cause console warnings and may lead to incorrect UI updates when the languages list changes.🐛 Proposed fix
- const languageItems = languages.map((lang) => ( - <span style={{ display: 'inline-block', width: '100%' }}> + const languageItems = languages.map((lang) => ( + <span key={lang.tag} style={{ display: 'inline-block', width: '100%' }}> <MenuItem🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx` around lines 75 - 103, The mapped list root element returned in languageItems (languages.map) is a <span> without a key, causing React warnings; add a unique key prop to the root element (the <span>) using a stable identifier such as lang.id (or lang.tag as a fallback) so each item has a consistent key during reconciliation; ensure the key is placed on the outermost element returned by the map.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@webapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx`:
- Around line 75-103: The mapped list root element returned in languageItems
(languages.map) is a <span> without a key, causing React warnings; add a unique
key prop to the root element (the <span>) using a stable identifier such as
lang.id (or lang.tag as a fallback) so each item has a consistent key during
reconciliation; ensure the key is placed on the outermost element returned by
the map.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c6cd5570-d8c8-4f51-b033-7fbfaa9a42c3
📒 Files selected for processing (2)
webapp/src/component/common/form/LanguagesSelect/LanguagesSelect.tsxwebapp/src/component/common/form/LanguagesSelect/getLanguagesContent.tsx
✅ Files skipped from review due to trivial changes (1)
- webapp/src/component/common/form/LanguagesSelect/LanguagesSelect.tsx
…rs (#3811) ## Problem On the project dashboard, a language with a long name (e.g. "Arabic (Palestinian Territories) | العربية (الأراضي الفلسطينية)") shrinks the translation status progress bar to a sliver — for **every** language row, since all rows share one grid. ## Cause `LanguageStats` lays rows out with: ```css grid-template-columns: auto auto auto 10fr auto auto; ``` The `auto` name column grows to the name's full single-line (max-content) width — the text never wraps — and the `10fr` bar column only receives leftover space, which can drop to zero. ## Fix ```css grid-template-columns: fit-content(40%) auto auto minmax(120px, 1fr) auto auto; ``` - short names keep hugging their content, so the bar keeps nearly all its current width in the common case - long names cap at 40% of the container and truncate with an ellipsis; the full name is shown in a tooltip on hover (same pattern as #3657 uses for the `LanguagesSelect` dropdown), keeping every row single-line - the bar column has a 120px floor and — because grid tracks are shared across rows — all bars stay equal width and aligned, so they remain visually comparable - language tags get the same ellipsis treatment, so an overlong custom tag cannot clip the Base chip or bleed under the bar - drive-by: removed a stray debug `className="test"` and redundant null-handling on the already-asserted `language` ## Verification Measured a standalone replica of the grid in a headless browser at 700px and 450px container widths, covering short-names-only, mixed long/short names, and an overlong unbreakable custom tag: bars are equal width across rows in all cases, names/tags truncate on a single line, nothing overlaps the bar, no horizontal overflow. Related: #3657 addresses long language names in the `LanguagesSelect` dropdown — different component, same truncation pattern.
## [3.214.1](v3.214.0...v3.214.1) (2026-07-23) ### Bug Fixes * exclude soft-deleted keys from the keys/info endpoint ([#3818](#3818)) ([dd24ad1](dd24ad1)), closes [#3817](#3817) [#3486](#3486) * hard-delete of a project with a default namespace fails on FK constraint ([#3810](#3810)) ([769ae0f](769ae0f)), closes [#3783](#3783) * prevent long language names from shrinking dashboard progress bars ([#3811](#3811)) ([0d09306](0d09306)), closes [#3657](#3657) [#3657](#3657) * purge trashed keys that have translation suggestions ([#3800](#3800)) ([e0f4888](e0f4888)) * serialize cached enums by name instead of ordinal ([#3807](#3807)) ([323d271](323d271))
browser-chrome, brave
Fixes #3611
Summary by CodeRabbit