feat: improve mui styles as figma - sponsor services#239
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
✅ Files skipped from review due to trivial changes (4)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughEnhances UI components and i18n: CompanyInputV2 gets translated create-option flows and improved filtering; AuthButton becomes an anchored account menu; NavBar forwards profile fields; CartButton shows a cart icon; table cells and action columns receive standardized sizing and styling; a dropdown divider margin is removed. ChangesUI Component Enhancement & i18n Integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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: 7
🤖 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 `@src/components/inputs/company-input-v2.js`:
- Line 134: The InputLabelProps is forcing shrink:false whenever disableShrink
is true, which causes label overlap when a value is present; update the
InputLabelProps usage in company-input-v2.js (the line that sets
InputLabelProps={...}) to conditionally set shrink: false only when
disableShrink is true AND there is no value (e.g., InputLabelProps={
disableShrink ? { shrink: !value } : undefined } or equivalent using the
component's value/inputValue variable) so the label will still shrink when a
value exists.
In `@src/components/mui/AuthButton/index.js`:
- Around line 58-74: The IconButton used as the user menu trigger (IconButton
with AccountCircleIcon, ref anchorRef, onClick openMenu, state menuOpen) lacks
an accessible name; add an appropriate aria-label (e.g., "Open user menu" or
"User account") to the IconButton so screen readers can identify the control,
keeping existing aria-controls/aria-expanded/aria-haspopup props intact and
using a concise, localized label matching the button's purpose.
- Around line 128-155: The Settings and Profile MenuItem entries in AuthButton
only call closeMenu and lack callbacks, so they close the menu but perform no
action; add two optional props (e.g., onSettings and onProfile) to the
AuthButton component signature and propTypes/TS types, then wire them into the
respective MenuItem onClick handlers (call closeMenu() and then call
props.onSettings() or props.onProfile() if provided) so clicking those items
triggers the supplied callbacks; update any places that render AuthButton to
pass handlers where needed and ensure default behavior remains safe when
callbacks are undefined.
In `@src/components/mui/NavBar/index.js`:
- Line 47: The NavBar is passing a dead prop picture={profilePic} into
AuthButton; either remove this unused prop from NavBar (and from NavBar's
props/destructuring and any related propTypes/TS types) or restore support by
updating AuthButton to accept a picture prop and render the profile image.
Locate the picture usage in the NavBar JSX (picture={profilePic}), remove that
attribute and clean up NavBar's profilePic handling, or alternatively add a
picture parameter to AuthButton (and its render logic) to preserve the profile
image flow.
In `@src/components/mui/table/mui-table.js`:
- Around line 189-190: The archive action column is constrained by tableLayout:
"fixed" plus hard 80px width/minWidth/maxWidth on the TableCell, causing
translated "archive/unarchive" labels to clip; update the TableCell used when
onArchive is present (and the other action cells referenced around lines with
onArchive/onDelete) to remove the maxWidth constraint and give a larger,
flexible size (e.g., set width:auto and a more generous minWidth like 120px) or
drop tableLayout: "fixed" for action columns so the content can expand; change
the TableCell props in the mui table component (the TableCell instances rendered
when onArchive and similar action flags are truthy) accordingly and apply the
same fix to the other action column occurrences noted in the comment.
- Around line 225-231: The IconButton elements (e.g., the one with
data-testid="action-edit" that calls onEdit(row) and the similar delete button)
have undersized click targets due to size="small" plus sx={{ padding: 0 }};
update these buttons to provide an accessible hit target by removing the zero
padding and/or the small size and instead apply a minimum padding (e.g., theme
spacing >= 1 or 8px) or use size="medium" so the clickable area meets touch
target guidelines; keep the same icons and handlers (EditIcon, onEdit(row),
delete handler) and adjust the sx styling for both the edit and delete
IconButton instances mentioned in the diff.
In `@src/i18n/i18n.js`:
- Line 2: The import uses a deep path ("i18n-react/dist/i18n-react") which is
fragile; replace the deep import with the package entrypoint by changing the
import of T (import T from "i18n-react/dist/i18n-react") to import from
"i18n-react" instead, and run a repo-wide search/replace for the same deep path
to update the ~45 other files (e.g., occurrences in CartButton, AuthButton,
company-input-v2) so all modules import from "i18n-react" consistently; after
updating, run the build/linter/tests to verify no remaining deep-path
references.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: a41a8060-8748-482a-8236-846183def046
📒 Files selected for processing (9)
src/components/inputs/company-input-v2.jssrc/components/mui/AuthButton/index.jssrc/components/mui/AuthButton/styles.module.scsssrc/components/mui/CartButton/index.jssrc/components/mui/NavBar/index.jssrc/components/mui/formik-inputs/mui-formik-dropdown-checkbox.jssrc/components/mui/table/mui-table.jssrc/i18n/en.jsonsrc/i18n/i18n.js
| error={error} | ||
| margin="normal" | ||
| InputLabelProps={{ shrink: disableShrink }} | ||
| InputLabelProps={disableShrink ? { shrink: false } : undefined} |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
MUI Autocomplete v6 InputLabelProps shrink false value overlap behavior
💡 Result:
In MUI (Material-UI) v6, the Autocomplete component renders its input via the renderInput prop, typically a TextField. The TextField's label shrink behavior is controlled by the InputLabelProps={{ shrink: false }} passed to the TextField inside renderInput.[1][2][3] Setting shrink: false forces the InputLabel to remain in its expanded (non-shrunk) position inside the input field, regardless of whether the Autocomplete has a value, is focused, or has an inputValue.[4][5][6] This can cause the label text to visually overlap with the selected value or input text, as the label does not move to the top border position.[7][8][9][10] This overlap occurs because: - Normally, the label automatically shrinks (via data-shrink="true") when there is a value, focus, or certain input states, positioning it above the input border.[5] - With shrink: false, it stays overlaid on the input content.[11] - In Autocomplete, the internal inputValue may initially be empty even with a value prop, exacerbating animation/jump issues, though recent v6 fixes (e.g., #45734, #46047) address shrink animation regressions for controlled values and multiple mode with empty arrays.[12][13][14][15][16] Example causing overlap: <Autocomplete value={someValue} renderInput={(params) => ( <TextField {...params} label="Label" InputLabelProps={{ shrink: false }} // Forces non-shrunk state /> )} /> The label will overlap the displayed getOptionLabel(someValue) or input text.[8][17] To avoid overlap while keeping the label expanded initially: - Use dynamic shrink: InputLabelProps={{ shrink: !!value || focused }} with state for focus.[18] - Or let MUI auto-handle shrink (omit shrink: false), accepting automatic shrinking on value/focus.[5] - CSS hacks like adjusting top exist but are brittle.[7] Official docs note shrink state isn't always perfect (e.g., number/date inputs), recommending manual shrink override only when needed.[5]
Citations:
- 1: https://v6.mui.com/material-ui/api/autocomplete
- 2: https://v6.mui.com/material-ui/api/autocomplete/
- 3: https://mui.com/api/autocomplete/
- 4: https://mui.com/material-ui/api/input-label/
- 5: https://v6.mui.com/material-ui/react-text-field
- 6: https://v6.mui.com/material-ui/api/input-label
- 7: Autocomplete + textfield leads to the label overlapping mui/material-ui#44798
- 8: [autocomplete] Label of the TextField shrinks when there is an option selected while the label of a normal filled TextField doesn't mui/material-ui#36548
- 9: TextField with select: Label overlaps selected value mui/material-ui#13013
- 10: Label overlapping input mui/material-ui#13186
- 11: Label won't 🐛 shrink in text field mui/material-ui#23173
- 12: https://github.com/mui/material-ui/blob/v6.4.2/CHANGELOG.md
- 13: [material-ui][Autocomplete] Prevent shrink animation in controlled Autocomplete when initial
valueis provided (@imadx) mui/material-ui#45735 - 14: [autocomplete] Prevent shrink animation in controlled Autocomplete when initial
valueis provided mui/material-ui#45734 - 15: [autocomplete] Fix label shrink issue when
renderValueis used with empty array in multiple mode mui/material-ui#46047 - 16: [autocomplete] Label is shrinked when providing an empty array as a
valueto Autocomplete when usingmultipleandrenderValuemui/material-ui#46037 - 17: https://mui.com/material-ui/react-autocomplete/
- 18: https://stackoverflow.com/questions/72796172/material-ui-autocomplete-with-inputlabelprops-shrink-true-in-custom-theme
🏁 Script executed:
cat -n src/components/inputs/company-input-v2.js | sed -n '125,145p'Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 910
🏁 Script executed:
cat -n src/components/inputs/company-input-v2.js | sed -n '1,50p'Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 2284
🏁 Script executed:
cat -n src/components/inputs/company-input-v2.js | sed -n '110,140p'Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 1195
🏁 Script executed:
cat -n src/components/inputs/company-input-v2.js | sed -n '60,85p'Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 1131
Prevent label overlap when disableShrink is enabled.
Passing { shrink: false } unconditionally overrides MUI Autocomplete's label management. When a value is present and disableShrink is true, the label stays in its resting position and overlaps the displayed text. Apply shrink: false only when there is no value:
Suggested fix
- InputLabelProps={disableShrink ? { shrink: false } : undefined}
+ InputLabelProps={disableShrink && !value ? { shrink: false } : undefined}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| InputLabelProps={disableShrink ? { shrink: false } : undefined} | |
| InputLabelProps={disableShrink && !value ? { shrink: false } : undefined} |
🤖 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 `@src/components/inputs/company-input-v2.js` at line 134, The InputLabelProps
is forcing shrink:false whenever disableShrink is true, which causes label
overlap when a value is present; update the InputLabelProps usage in
company-input-v2.js (the line that sets InputLabelProps={...}) to conditionally
set shrink: false only when disableShrink is true AND there is no value (e.g.,
InputLabelProps={ disableShrink ? { shrink: !value } : undefined } or equivalent
using the component's value/inputValue variable) so the label will still shrink
when a value exists.
| <IconButton | ||
| aria-controls={menuOpen ? "user-menu" : undefined} | ||
| aria-expanded={menuOpen ? "true" : undefined} | ||
| aria-haspopup="true" | ||
| onClick={openMenu} | ||
| size="medium" | ||
| data-testid="user-menu-button" | ||
| sx={{ | ||
| color: theme.palette.text.primary, | ||
| p: 0, | ||
| width: 28, | ||
| height: 28 | ||
| }} | ||
| ref={anchorRef} | ||
| > | ||
| <AccountCircleIcon sx={{fontSize: 28}}/> | ||
| </IconButton> |
There was a problem hiding this comment.
IconButton is missing aria-label — screen readers cannot identify it.
The button contains only an icon with no text. Without an aria-label, assistive technologies announce it as an unlabeled button.
♿ Proposed fix
<IconButton
aria-controls={menuOpen ? "user-menu" : undefined}
aria-expanded={menuOpen ? "true" : undefined}
aria-haspopup="true"
+ aria-label="Open user menu"
onClick={openMenu}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <IconButton | |
| aria-controls={menuOpen ? "user-menu" : undefined} | |
| aria-expanded={menuOpen ? "true" : undefined} | |
| aria-haspopup="true" | |
| onClick={openMenu} | |
| size="medium" | |
| data-testid="user-menu-button" | |
| sx={{ | |
| color: theme.palette.text.primary, | |
| p: 0, | |
| width: 28, | |
| height: 28 | |
| }} | |
| ref={anchorRef} | |
| > | |
| <AccountCircleIcon sx={{fontSize: 28}}/> | |
| </IconButton> | |
| <IconButton | |
| aria-controls={menuOpen ? "user-menu" : undefined} | |
| aria-expanded={menuOpen ? "true" : undefined} | |
| aria-haspopup="true" | |
| aria-label="Open user menu" | |
| onClick={openMenu} | |
| size="medium" | |
| data-testid="user-menu-button" | |
| sx={{ | |
| color: theme.palette.text.primary, | |
| p: 0, | |
| width: 28, | |
| height: 28 | |
| }} | |
| ref={anchorRef} | |
| > | |
| <AccountCircleIcon sx={{fontSize: 28}}/> | |
| </IconButton> |
🤖 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 `@src/components/mui/AuthButton/index.js` around lines 58 - 74, The IconButton
used as the user menu trigger (IconButton with AccountCircleIcon, ref anchorRef,
onClick openMenu, state menuOpen) lacks an accessible name; add an appropriate
aria-label (e.g., "Open user menu" or "User account") to the IconButton so
screen readers can identify the control, keeping existing
aria-controls/aria-expanded/aria-haspopup props intact and using a concise,
localized label matching the button's purpose.
| <MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}> | ||
| <ListItemIcon sx={{minWidth: 32, color: menuIconColor}}> | ||
| <SettingsIcon sx={{fontSize: 24}}/> | ||
| </ListItemIcon> | ||
| <ListItemText | ||
| primary={T.translate("general.settings")} | ||
| primaryTypographyProps={{ | ||
| sx: { | ||
| fontSize: menuFontSize, | ||
| color: theme.palette.text.primary | ||
| } | ||
| }} | ||
| /> | ||
| </MenuItem> | ||
| <MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}> | ||
| <ListItemIcon sx={{minWidth: 32, color: menuIconColor}}> | ||
| <PersonIcon sx={{fontSize: 24}}/> | ||
| </ListItemIcon> | ||
| <ListItemText | ||
| primary={T.translate("general.profile")} | ||
| primaryTypographyProps={{ | ||
| sx: { | ||
| fontSize: menuFontSize, | ||
| color: theme.palette.text.primary | ||
| } | ||
| }} | ||
| /> | ||
| </MenuItem> |
There was a problem hiding this comment.
Settings and Profile menu items are non-functional — missing callback props.
Both MenuItem elements only call closeMenu(). There is no onSettings or onProfile (or equivalent) prop on AuthButton, so clicking either item closes the dropdown and does nothing else. These appear as functional options to the user but have no effect.
Add callback props and wire them up:
🐛 Proposed fix
const AuthButton = ({
isLoggedUser,
doLogin,
initLogOut,
profileEmail,
- profileName
+ profileName,
+ onSettings,
+ onProfile
}) => {- <MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}>
+ <MenuItem onClick={() => { closeMenu(); onSettings?.(); }} sx={{py: 1.5, px: 3, gap: 1.5}}>
...
</MenuItem>
- <MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}>
+ <MenuItem onClick={() => { closeMenu(); onProfile?.(); }} sx={{py: 1.5, px: 3, gap: 1.5}}>🤖 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 `@src/components/mui/AuthButton/index.js` around lines 128 - 155, The Settings
and Profile MenuItem entries in AuthButton only call closeMenu and lack
callbacks, so they close the menu but perform no action; add two optional props
(e.g., onSettings and onProfile) to the AuthButton component signature and
propTypes/TS types, then wire them into the respective MenuItem onClick handlers
(call closeMenu() and then call props.onSettings() or props.onProfile() if
provided) so clicking those items triggers the supplied callbacks; update any
places that render AuthButton to pass handlers where needed and ensure default
behavior remains safe when callbacks are undefined.
| @@ -37,6 +45,8 @@ const NavBar = ({title, profilePic, isLoggedUser, onClickLogin, initLogOut}) => | |||
| <AuthButton | |||
| isLoggedUser={isLoggedUser} | |||
| picture={profilePic} | |||
There was a problem hiding this comment.
Dead prop: picture is no longer consumed by AuthButton.
AuthButton was refactored to remove the picture prop entirely. Passing picture={profilePic} here has no effect and will confuse future maintainers. Additionally, callers of NavBar who previously relied on profilePic to render a profile image will silently lose that visual without any indication.
Either remove the prop pass-through or preserve the profile picture in the new AuthButton design.
🛠️ Minimal cleanup (if picture display is not being restored)
<AuthButton
isLoggedUser={isLoggedUser}
- picture={profilePic}
profileEmail={profileEmail}
profileName={profileName}
doLogin={onClickLogin}
initLogOut={initLogOut}
/>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| picture={profilePic} | |
| <AuthButton | |
| isLoggedUser={isLoggedUser} | |
| profileEmail={profileEmail} | |
| profileName={profileName} | |
| doLogin={onClickLogin} | |
| initLogOut={initLogOut} | |
| /> |
🤖 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 `@src/components/mui/NavBar/index.js` at line 47, The NavBar is passing a dead
prop picture={profilePic} into AuthButton; either remove this unused prop from
NavBar (and from NavBar's props/destructuring and any related propTypes/TS
types) or restore support by updating AuthButton to accept a picture prop and
render the profile image. Locate the picture usage in the NavBar JSX
(picture={profilePic}), remove that attribute and clean up NavBar's profilePic
handling, or alternatively add a picture parameter to AuthButton (and its render
logic) to preserve the profile image flow.
| {onArchive && <TableCell sx={{width: 80, minWidth: 80, maxWidth: 80}}/>} | ||
| {onDelete && <TableCell sx={{width: 40, minWidth: 40, maxWidth: 40}}/>} |
There was a problem hiding this comment.
Archive action column is too constrained for translated labels.
With tableLayout: "fixed" plus width/minWidth/maxWidth: 80, the archive/unarchive text is prone to clipping in non-English locales. This is an i18n UX break on a primary action.
Suggested fix
- {onArchive && <TableCell sx={{width: 80, minWidth: 80, maxWidth: 80}}/>}
+ {onArchive && <TableCell sx={{minWidth: 120}}/>}
...
- sx={getCellSx(row, {width: 80, minWidth: 80, maxWidth: 80})}
+ sx={getCellSx(row, {minWidth: 120})}
...
<Button
variant="text"
color="inherit"
size="small"
onClick={() => onArchive(row)}
data-testid="action-archive"
sx={{
fontSize: "1.3rem",
fontWeight: "normal",
lineHeight: "2.2rem",
padding: 0,
+ whiteSpace: "nowrap",
color: "rgba(0,0,0,0.56)"
}}
>Also applies to: 238-258
🤖 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 `@src/components/mui/table/mui-table.js` around lines 189 - 190, The archive
action column is constrained by tableLayout: "fixed" plus hard 80px
width/minWidth/maxWidth on the TableCell, causing translated "archive/unarchive"
labels to clip; update the TableCell used when onArchive is present (and the
other action cells referenced around lines with onArchive/onDelete) to remove
the maxWidth constraint and give a larger, flexible size (e.g., set width:auto
and a more generous minWidth like 120px) or drop tableLayout: "fixed" for action
columns so the content can expand; change the TableCell props in the mui table
component (the TableCell instances rendered when onArchive and similar action
flags are truthy) accordingly and apply the same fix to the other action column
occurrences noted in the comment.
| @@ -1,5 +1,5 @@ | |||
| import {getCurrentUserLanguage} from "../utils/methods"; | |||
| import T from "i18n-react"; | |||
| import T from "i18n-react/dist/i18n-react"; | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect i18n-react package.json main/module/exports fields and dist folder contents
fd package.json --search-path node_modules/i18n-react --max-depth 1 --exec cat {}
echo "---dist contents---"
fd . --search-path node_modules/i18n-react/dist --max-depth 1Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 349
🌐 Web query:
i18n-react npm package official import documentation
💡 Result:
For the npm package commonly referred to as “i18n-react” in the React/i18next ecosystem, the official docs correspond to react-i18next. Official import / usage docs (react-i18next) 1) Install - Install react-i18next and i18next with npm. [1][2] 2) Import and initialize i18next + react-i18next (hooks version) - The docs show importing the i18n instance from i18next and initReactI18next from react-i18next, then calling i18n.use(initReactI18next). [3][2] Example (as shown in the docs): - import i18n from "i18next"; - import { initReactI18next } from "react-i18next"; - i18n.use(initReactI18next).init({... }); [3][2] 3) Import the initialized i18n module once at app startup - The docs explicitly say to create a file (e.g., i18n.js) that exports the initialized i18n instance, and then import it in your React entry point (e.g., index.js) so the configuration runs. [3][4] 4) Import i18next instance (t function) outside React components - The docs show that if you need to call t or use the i18next instance outside a React component, you can import the exported i18n/i18next instance (e.g., import i18next from './i18n') and call i18next.t(...). [3][4] Important note about naming - react-i18next’s docs state the documentation is published on react.i18next.com and the general i18next docs are on i18next.com. [5] If you meant a different package literally named “i18n-react” (not react-i18next), tell me the exact npm package name/link and I’ll pull the official import documentation for that specific package.
Citations:
- 1: https://www.npmjs.com/package/react-i18next
- 2: https://react.i18next.com/getting-started
- 3: https://react.i18next.com/guides/quick-start
- 4: https://react.i18next.com/latest
- 5: https://github.com/i18next/react-i18next
🏁 Script executed:
# Search for all imports of i18n-react in the repository
rg "from\s+['\"]i18n-react" --type js --type jsx --type ts --type tsx
# Also check what's currently in src/i18n/i18n.js at line 2
echo "=== Current import in i18n.js ==="
head -5 src/i18n/i18n.jsRepository: OpenStackweb/openstack-uicore-foundation
Length of output: 355
🌐 Web query:
i18n-react npm package
💡 Result:
No npm package named "i18n-react" exists based on searches across npm, GitHub, and general web results[1][2][3]. The query likely refers to the popular react-i18next package, which provides internationalization (i18n) for React apps using the i18next ecosystem[1][3][4][5]. react-i18next is the official React integration for i18next, supporting features like hooks, plurals, interpolation, and SSR[1][4][6][5]. As of 2026-05-08, it has ~11.9M weekly downloads, 379 versions (latest in v17.x from Mar-Apr 2026), MIT license, and requires React >=16.8.0, i18next >=26.0.1[3]. Install: npm i react-i18next i18next[3][4]. Official docs: https://react.i18next.com/[4][6][5]. GitHub: https://github.com/i18next/react-i18next (9.9k stars)[1][7]. Other similar packages include react-intl (2.9M weekly downloads, latest v10.1.5 May 2026)[8] and react-i18nify (20.9k downloads)[9], but react-i18next dominates for i18n in React[3].
Citations:
- 1: https://redirect.github.com/i18next/react-i18next
- 2: https://www.npmjs.com/package/react-i18next/v/14.0.1
- 3: https://www.npmjs.com/package/react-i18next
- 4: https://react.i18next.com/getting-started
- 5: https://react.i18next.com/
- 6: https://react.i18next.com/guides/quick-start
- 7: https://github.com/i18next/react-i18next
- 8: https://www.npmjs.com/package/react-intl
- 9: https://www.npmjs.com/package/react-i18nify
🏁 Script executed:
# Find all files importing from i18n-react (including variations)
rg "i18n-react" --type js --type ts
# Also check if package.json or lock files mention i18n-react
rg "i18n-react" package.json yarn.lock package-lock.json 2>/dev/null || echo "No lock files found with i18n-react"Repository: OpenStackweb/openstack-uicore-foundation
Length of output: 7041
Use the standard i18n-react import instead of the internal /dist/ path.
The codebase currently imports from i18n-react/dist/i18n-react (a deep UMD build path), but many other files successfully import from just i18n-react. The deep import bypasses the package's module resolution and is fragile—any restructuring of the dist folder in a future release will silently break all affected files without a version conflict.
Update this file and the 45+ others throughout the codebase that use the deep path to import from i18n-react directly. This affects src/i18n/i18n.js, src/components/mui/CartButton/index.js, src/components/mui/AuthButton/index.js, src/components/inputs/company-input-v2.js, and many others.
🤖 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 `@src/i18n/i18n.js` at line 2, The import uses a deep path
("i18n-react/dist/i18n-react") which is fragile; replace the deep import with
the package entrypoint by changing the import of T (import T from
"i18n-react/dist/i18n-react") to import from "i18n-react" instead, and run a
repo-wide search/replace for the same deep path to update the ~45 other files
(e.g., occurrences in CartButton, AuthButton, company-input-v2) so all modules
import from "i18n-react" consistently; after updating, run the
build/linter/tests to verify no remaining deep-path references.
d40c7ff to
ec87087
Compare
| {canDelete(row) && ( | ||
| <IconButton | ||
| size="large" | ||
| size="small" |
There was a problem hiding this comment.
are you sure this is the size that we want ? I think this is too small compared to the figma, please check this works for both admin and sponsor services, we may need to adjust this on CustomTheme
| const libTexts = resources[language] || resources['en']; | ||
| T.setTexts(merge({}, libTexts, customTexts)); | ||
| const defaultTexts = resources['en'] || {}; | ||
| const localizedTexts = resources[language] || {}; |
There was a problem hiding this comment.
This change doesn't make sense, so if locale language is ES then it will merge english and then spanish, what is the purpose of that ? I think it was fine as it was before
ec87087 to
fe70291
Compare
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)
src/components/mui/table/mui-table.js (1)
227-227:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winIconButton click targets may still be undersized for accessibility.
While changing from
size="small"tosize="large"improves the situation, combiningsize="large"withsx={{ padding: 0 }}still reduces the clickable hit area below the button's natural 48px size. The actual clickable area depends on the icon size (~36-40px for "large" icons), which may not meet WCAG's 44×44px touch target guideline.The previous review suggested using
sx={{ p: 0.5 }}to maintain an accessible hit area while keeping the visual size controlled.♻️ Proposed fix for accessible hit targets
<IconButton size="large" onClick={() => onEdit(row)} - sx={{ padding: 0 }} + sx={{ p: 0.5 }} data-testid="action-edit" > <IconButton size="large" onClick={() => handleDelete(row)} data-testid="action-delete" - sx={{ padding: 0 }} + sx={{ p: 0.5 }} >Also applies to: 273-273
🤖 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 `@src/components/mui/table/mui-table.js` at line 227, The IconButton instances currently set size="large" but override padding with sx={{ padding: 0 }}, reducing the clickable hit area; update those IconButton props (the JSX elements named IconButton) to use sx={{ p: 0.5 }} instead of sx={{ padding: 0 }} so the visual layout stays tight while restoring an accessible hit target (~44px); make the same change for both occurrences of IconButton in this file (the second occurrence noted in the review).
♻️ Duplicate comments (2)
src/components/mui/table/mui-table.js (2)
189-190:⚠️ Potential issue | 🟠 Major | ⚡ Quick winArchive action column is still too constrained for translated labels.
This issue was previously flagged. With
tableLayout: "fixed"pluswidth/minWidth/maxWidth: 80px, the archive/unarchive text is prone to clipping in non-English locales. The 80px constraint is insufficient for translated button labels.Please refer to the previous review comment for the suggested fix (remove
maxWidth, increaseminWidthto 120, addwhiteSpace: "nowrap").Also applies to: 238-258
🤖 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 `@src/components/mui/table/mui-table.js` around lines 189 - 190, The archive action column is too narrow and clips translated labels because tableLayout: "fixed" plus width/minWidth/maxWidth: 80 restricts the cell; update the TableCell used for the archive/unarchive action (the JSX that checks onArchive) to remove maxWidth, set minWidth to 120, and add whiteSpace: "nowrap" in the sx props (keep width or remove it as you prefer), and make the same change for the equivalent TableCell occurrences that handle archive/delete actions later in the file (the other TableCell JSX guarded by onArchive/onDelete).
150-150:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
tableLayout: "fixed"forces exact column widths and will clip translated content.Setting
tableLayout: "fixed"prevents the browser from auto-sizing columns to fit content. Combined with the hardwidth/minWidth/maxWidthconstraints on action columns (especially the 80px archive column), this will cause translated text to overflow or clip in non-English locales.Consider removing
tableLayout: "fixed"or usingminWidthwithoutmaxWidthfor action columns to allow content-based expansion.♻️ Proposed fix to allow flexible column sizing
- <Table sx={{tableLayout: "fixed"}}> + <Table>🤖 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 `@src/components/mui/table/mui-table.js` at line 150, The Table component sets sx={{tableLayout: "fixed"}} which forces exact column widths and causes translated text to clip; remove or change that style on the <Table> element (the Table with sx prop) so the browser can auto-size columns, and adjust the action column definitions (the archive/action column that currently uses hard width/minWidth/maxWidth ~80px) to use minWidth (or a larger flexible width) instead of a fixed maxWidth so action cells can expand for long translations; update the Table JSX (Table sx prop) and the action column config (archive/action column width props) accordingly.
🧹 Nitpick comments (3)
src/components/mui/table/mui-table.js (3)
244-253: 💤 Low valueInconsistent sizing:
size="large"is overridden by custom styling.The Button has
size="large"but then overrides bothpadding: 0andfontSize: "1.3rem", which negates the effect of the size prop. Consider either:
- Removing
size="large"and relying on the custom sx styling, or- Removing the custom
fontSizeandpaddingto letsize="large"control the appearanceThe current combination is confusing for maintenance.
🤖 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 `@src/components/mui/table/mui-table.js` around lines 244 - 253, Button has size="large" but its sx overrides (fontSize: "1.3rem", padding: 0) negate the prop; either remove size="large" from the Button or remove/adjust the sx overrides so size controls spacing/typography — update the Button instance that calls onArchive(row) (data-testid="action-archive") to be consistent: if you want custom look, delete the size prop; if you want MUI sizing, delete fontSize and padding from sx (or map them to theme scale values) so size="large" applies correctly.
188-191: 💤 Low valueConsider removing
maxWidthconstraints on action columns for layout flexibility.The action columns (edit, archive, delete, select) use identical
width,minWidth, andmaxWidthvalues, creating a completely rigid layout. While 40px works for icon-only columns with "large" icons, removingmaxWidthwould provide flexibility if icon sizes or padding change in the future.For the archive column with text content, this is critical (flagged separately). For icon-only columns, it's a defensive improvement.
♻️ Proposed refactor for icon action columns
- {onEdit && <TableCell sx={{width: 40, minWidth: 40, maxWidth: 40}}/>} + {onEdit && <TableCell sx={{minWidth: 40}}/>} - {onDelete && <TableCell sx={{width: 40, minWidth: 40, maxWidth: 40}}/>} + {onDelete && <TableCell sx={{minWidth: 40}}/>} - {onSelect && <TableCell sx={{width: 40, minWidth: 40, maxWidth: 40}}/>} + {onSelect && <TableCell sx={{minWidth: 40}}/>}And apply similar changes to the corresponding body cells.
Also applies to: 222-283
🤖 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 `@src/components/mui/table/mui-table.js` around lines 188 - 191, The action-column TableCell definitions using onEdit, onArchive, onDelete, and onSelect are overly rigid because they set width, minWidth, and maxWidth; remove the maxWidth property from those header TableCell sx objects and the corresponding body cell sx usages so the columns can grow if icon/padding/content changes (keep width and minWidth for baseline sizing but drop maxWidth for flexibility); update the TableCell instances tied to the onEdit/onArchive/onDelete/onSelect branches in mui-table.js and ensure the archive column with text likewise no longer has a maxWidth constraint.
140-140: 💤 Low valueRedundant
fontWeight: "normal"declarations.Both line 140 (inline style on span) and line 211 (via
getCellSx) setfontWeight: "normal". The inline style on line 140 is unnecessary since the TableCell already receivesfontWeight: "normal"throughgetCellSx.♻️ Simplify by removing redundant inline style
- return <span style={{ fontWeight: "normal" }}>{row[col.columnKey]}</span>; + return row[col.columnKey];Also applies to: 207-212
🤖 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 `@src/components/mui/table/mui-table.js` at line 140, Remove the redundant inline style on the span that renders cell content: the fontWeight: "normal" applied inline to <span> containing {row[col.columnKey]} is unnecessary because getCellSx already applies fontWeight: "normal" to the TableCell; update the cell renderer (the code that returns the span) to omit the inline style and rely on getCellSx (and similarly remove any other inline fontWeight occurrences around lines 207–212) so styling is centralized in getCellSx.
🤖 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 `@src/components/mui/table/mui-table.js`:
- Line 227: The IconButton instances currently set size="large" but override
padding with sx={{ padding: 0 }}, reducing the clickable hit area; update those
IconButton props (the JSX elements named IconButton) to use sx={{ p: 0.5 }}
instead of sx={{ padding: 0 }} so the visual layout stays tight while restoring
an accessible hit target (~44px); make the same change for both occurrences of
IconButton in this file (the second occurrence noted in the review).
---
Duplicate comments:
In `@src/components/mui/table/mui-table.js`:
- Around line 189-190: The archive action column is too narrow and clips
translated labels because tableLayout: "fixed" plus width/minWidth/maxWidth: 80
restricts the cell; update the TableCell used for the archive/unarchive action
(the JSX that checks onArchive) to remove maxWidth, set minWidth to 120, and add
whiteSpace: "nowrap" in the sx props (keep width or remove it as you prefer),
and make the same change for the equivalent TableCell occurrences that handle
archive/delete actions later in the file (the other TableCell JSX guarded by
onArchive/onDelete).
- Line 150: The Table component sets sx={{tableLayout: "fixed"}} which forces
exact column widths and causes translated text to clip; remove or change that
style on the <Table> element (the Table with sx prop) so the browser can
auto-size columns, and adjust the action column definitions (the archive/action
column that currently uses hard width/minWidth/maxWidth ~80px) to use minWidth
(or a larger flexible width) instead of a fixed maxWidth so action cells can
expand for long translations; update the Table JSX (Table sx prop) and the
action column config (archive/action column width props) accordingly.
---
Nitpick comments:
In `@src/components/mui/table/mui-table.js`:
- Around line 244-253: Button has size="large" but its sx overrides (fontSize:
"1.3rem", padding: 0) negate the prop; either remove size="large" from the
Button or remove/adjust the sx overrides so size controls spacing/typography —
update the Button instance that calls onArchive(row)
(data-testid="action-archive") to be consistent: if you want custom look, delete
the size prop; if you want MUI sizing, delete fontSize and padding from sx (or
map them to theme scale values) so size="large" applies correctly.
- Around line 188-191: The action-column TableCell definitions using onEdit,
onArchive, onDelete, and onSelect are overly rigid because they set width,
minWidth, and maxWidth; remove the maxWidth property from those header TableCell
sx objects and the corresponding body cell sx usages so the columns can grow if
icon/padding/content changes (keep width and minWidth for baseline sizing but
drop maxWidth for flexibility); update the TableCell instances tied to the
onEdit/onArchive/onDelete/onSelect branches in mui-table.js and ensure the
archive column with text likewise no longer has a maxWidth constraint.
- Line 140: Remove the redundant inline style on the span that renders cell
content: the fontWeight: "normal" applied inline to <span> containing
{row[col.columnKey]} is unnecessary because getCellSx already applies
fontWeight: "normal" to the TableCell; update the cell renderer (the code that
returns the span) to omit the inline style and rely on getCellSx (and similarly
remove any other inline fontWeight occurrences around lines 207–212) so styling
is centralized in getCellSx.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 49f7cd17-118c-4561-a423-603b87af4341
📒 Files selected for processing (10)
src/components/inputs/company-input-v2.jssrc/components/mui/AuthButton/index.jssrc/components/mui/AuthButton/styles.module.scsssrc/components/mui/CartButton/index.jssrc/components/mui/NavBar/index.jssrc/components/mui/__tests__/auth-button.test.jssrc/components/mui/formik-inputs/mui-formik-dropdown-checkbox.jssrc/components/mui/table/mui-table.jssrc/i18n/en.jsonsrc/i18n/i18n.js
✅ Files skipped from review due to trivial changes (2)
- src/components/mui/formik-inputs/mui-formik-dropdown-checkbox.js
- src/i18n/en.json
🚧 Files skipped from review as they are similar to previous changes (6)
- src/components/mui/AuthButton/styles.module.scss
- src/components/mui/NavBar/index.js
- src/components/mui/CartButton/index.js
- src/components/mui/AuthButton/index.js
- src/i18n/i18n.js
- src/components/inputs/company-input-v2.js
fe70291 to
89f1ada
Compare
89f1ada to
d69505e
Compare
ref: https://app.clickup.com/t/86b8tt7c7
Summary by CodeRabbit
New Features
UI/UX Improvements
Localization
Tests