Skip to content

Commit ebabe0d

Browse files
committed
feat(i18n): add missing translations in german
1 parent 838866a commit ebabe0d

File tree

15 files changed

+295
-109
lines changed

15 files changed

+295
-109
lines changed

eslint.config.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,20 @@ export default [
7171
'warn',
7272
{ allowConstantExport: true },
7373
],
74-
/* no-irregular-whitespace
75-
- ignore to allow prettier of the text layout. April 10th 2025.
74+
/* no-irregular-whitespace
75+
- ignore to allow prettier of the text layout. April 10th 2025.
7676
7777
NOTE: Should be removable after https://github.com/Mikadv/carbon-react-starter/issues/32
7878
*/
7979
'no-irregular-whitespace': ['error', { skipJSXText: true }],
8080
// Allow optional chaining
8181
'import/namespace': 'off',
82+
/* Disable import plugin rules that have parse errors with i18next packages */
83+
'import/default': 'off',
84+
'import/no-named-as-default': 'off',
85+
'import/no-named-as-default-member': 'off',
86+
/* Ignore unresolved imports for build artifacts */
87+
'import/no-unresolved': ['error', { ignore: ['^\\.\\./dist/'] }],
8288
},
8389
},
8490
];

src/components/commonHeader/CommonHeader.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
*/
77

88
import { AspectRatio, Column, Grid, Heading } from '@carbon/react';
9+
import { useTranslation } from 'react-i18next';
910

1011
export const CommonHeader = ({ title, paragraphs }) => {
12+
const { t } = useTranslation();
1113
return (
1214
<Grid as="header" className="cs--common-header">
1315
<Column sm={4} md={8} lg={8}>
@@ -23,7 +25,7 @@ export const CommonHeader = ({ title, paragraphs }) => {
2325
<img
2426
src="/icon.dark.svg?version=0.1.0"
2527
className="cs--common-header__logo"
26-
alt="fed-at-ibm logo"
28+
alt={t('commonHeader.logoAlt', 'fed-at-ibm logo')}
2729
/>
2830
</AspectRatio>
2931
</Column>

src/components/footer/Footer.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
*/
77

88
import { AspectRatio, Column } from '@carbon/react';
9+
import { useTranslation } from 'react-i18next';
910

1011
export const Footer = () => {
12+
const { t } = useTranslation();
13+
1114
return (
1215
<Column as="footer" sm={4} md={8} lg={8} className="cs--footer">
1316
<AspectRatio ratio="16x9">
14-
<p>Footer</p>
15-
<p>Copyright IBM 2025</p>
17+
<p>{t('footer.title', 'Footer')}</p>
18+
<p>{t('footer.copyright', 'Copyright IBM 2025')}</p>
1619
</AspectRatio>
1720
</Column>
1821
);

src/components/nav/Nav.jsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ import {
2828
UserAvatar,
2929
} from '@carbon/icons-react';
3030
import { Link as RouterLink, useLocation } from 'react-router';
31+
import { useTranslation } from 'react-i18next';
3132
import ProfilePanel from '../profilePanel/ProfilePanel';
3233

3334
import { routesInHeader, routesInSideNav } from '../../routes/config';
3435
import { NavHeaderItems } from './NavHeaderItems';
3536
import { NavSideItems } from './NavSideItems';
3637

3738
export const Nav = () => {
39+
const { t } = useTranslation();
3840
const location = useLocation();
3941
const [isSideNavExpanded, setIsSideNavExpanded] = useState(false);
4042
const [isProfileOpen, setIsProfileOpen] = useState(false);
@@ -54,14 +56,18 @@ export const Nav = () => {
5456
<Header aria-label="fed-at-ibm">
5557
<SkipToContent />
5658
<HeaderMenuButton
57-
aria-label={isSideNavExpanded ? 'Close menu' : 'Open menu'}
59+
aria-label={
60+
isSideNavExpanded
61+
? t('nav.menu.close', 'Close menu')
62+
: t('nav.menu.open', 'Open menu')
63+
}
5864
onClick={toggleNav}
5965
isCollapsible={true}
6066
isActive={isSideNavExpanded}
6167
aria-expanded={isSideNavExpanded}
6268
/>
6369
<HeaderName as={RouterLink} to="/" prefix="Carbon">
64-
React starter template
70+
{t('nav.header.name', 'React starter template')}
6571
</HeaderName>
6672
{routesInHeader.length > 0 && (
6773
<HeaderNavigation aria-label="fed-at-ibm">
@@ -72,17 +78,20 @@ export const Nav = () => {
7278
</HeaderNavigation>
7379
)}
7480
<HeaderGlobalBar>
75-
<HeaderGlobalAction aria-label="Search">
81+
<HeaderGlobalAction aria-label={t('nav.actions.search', 'Search')}>
7682
<Search size={20} />
7783
</HeaderGlobalAction>
7884
<HeaderGlobalAction
79-
aria-label="User profile"
85+
aria-label={t('nav.actions.userProfile', 'User profile')}
8086
tooltipAlignment="end"
8187
onClick={handleProfileOpen}
8288
>
8389
<UserAvatar size={20} />
8490
</HeaderGlobalAction>
85-
<HeaderGlobalAction aria-label="App switcher" tooltipAlignment="end">
91+
<HeaderGlobalAction
92+
aria-label={t('nav.actions.appSwitcher', 'App switcher')}
93+
tooltipAlignment="end"
94+
>
8695
<SwitcherIcon size={20} />
8796
</HeaderGlobalAction>
8897
</HeaderGlobalBar>
@@ -92,7 +101,7 @@ export const Nav = () => {
92101
</HeaderPanel>
93102
</Header>
94103
<SideNav
95-
aria-label="Side navigation"
104+
aria-label={t('nav.sideNav.ariaLabel', 'Side navigation')}
96105
expanded={isSideNavExpanded}
97106
isPersistent={false}
98107
>
Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,43 @@
11
import { HeaderMenu, HeaderMenuItem } from '@carbon/react';
22
import { Link as RouterLink } from 'react-router';
3+
import { useTranslation } from 'react-i18next';
34

4-
export const NavHeaderItems = ({ routesInHeader, currentPath }) => (
5-
<>
6-
{routesInHeader.map(({ path, carbon }) =>
7-
!carbon.inSubMenu && carbon?.label ? (
8-
carbon.subMenu ? (
9-
<HeaderMenu
10-
aria-label={carbon.label}
11-
key={path}
12-
menuLinkName={carbon.label}
13-
>
14-
{carbon.subMenu.map((subRoute) => (
15-
<HeaderMenuItem
16-
as={RouterLink}
17-
to={subRoute.path}
18-
key={subRoute.path}
19-
isActive={subRoute.path === currentPath}
20-
>
21-
{subRoute.carbon.label}
22-
</HeaderMenuItem>
23-
))}
24-
</HeaderMenu>
25-
) : (
26-
<HeaderMenuItem
27-
as={RouterLink}
28-
key={path}
29-
to={path}
30-
isActive={path === currentPath}
31-
>
32-
{carbon?.label}
33-
</HeaderMenuItem>
34-
)
35-
) : null,
36-
)}
37-
</>
38-
);
5+
export const NavHeaderItems = ({ routesInHeader, currentPath }) => {
6+
const { t } = useTranslation();
7+
8+
return (
9+
<>
10+
{routesInHeader.map(({ path, carbon }) =>
11+
!carbon.inSubMenu && carbon?.label ? (
12+
carbon.subMenu ? (
13+
<HeaderMenu
14+
aria-label={t(carbon.labelKey, carbon.label)}
15+
key={path}
16+
menuLinkName={t(carbon.labelKey, carbon.label)}
17+
>
18+
{carbon.subMenu.map((subRoute) => (
19+
<HeaderMenuItem
20+
as={RouterLink}
21+
to={subRoute.path}
22+
key={subRoute.path}
23+
isActive={subRoute.path === currentPath}
24+
>
25+
{t(subRoute.carbon.labelKey, subRoute.carbon.label)}
26+
</HeaderMenuItem>
27+
))}
28+
</HeaderMenu>
29+
) : (
30+
<HeaderMenuItem
31+
as={RouterLink}
32+
key={path}
33+
to={path}
34+
isActive={path === currentPath}
35+
>
36+
{t(carbon.labelKey, carbon.label)}
37+
</HeaderMenuItem>
38+
)
39+
) : null,
40+
)}
41+
</>
42+
);
43+
};
Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { SideNavLink, SideNavMenu, SideNavMenuItem } from '@carbon/react';
22
import { Link as RouterLink } from 'react-router';
3+
import { useTranslation } from 'react-i18next';
34

45
const destinationProps = (path, carbon, currentPath) =>
56
path
@@ -11,39 +12,43 @@ const destinationProps = (path, carbon, currentPath) =>
1112
href: carbon.href,
1213
};
1314

14-
export const NavSideItems = ({ routesInSideNav, currentPath }) => (
15-
<>
16-
{routesInSideNav.map(({ path, carbon }) =>
17-
!carbon.inSubMenu && carbon?.label ? (
18-
carbon.subMenu ? (
19-
<SideNavMenu
20-
key={path ?? carbon.label}
21-
renderIcon={carbon.icon}
22-
title={carbon.label}
23-
>
24-
{carbon.subMenu.map((subRoute) => (
25-
<SideNavMenuItem
26-
key={subRoute.path ?? subRoute.carbon.label}
27-
{...destinationProps(
28-
subRoute.path,
29-
subRoute.carbon,
30-
currentPath,
31-
)}
32-
>
33-
{subRoute.carbon.label}
34-
</SideNavMenuItem>
35-
))}
36-
</SideNavMenu>
37-
) : (
38-
<SideNavLink
39-
key={path ?? carbon.label}
40-
renderIcon={carbon.icon}
41-
{...destinationProps(path, carbon, currentPath)}
42-
>
43-
{carbon.label}
44-
</SideNavLink>
45-
)
46-
) : null,
47-
)}
48-
</>
49-
);
15+
export const NavSideItems = ({ routesInSideNav, currentPath }) => {
16+
const { t } = useTranslation();
17+
18+
return (
19+
<>
20+
{routesInSideNav.map(({ path, carbon }) =>
21+
!carbon.inSubMenu && carbon?.label ? (
22+
carbon.subMenu ? (
23+
<SideNavMenu
24+
key={path ?? carbon.label}
25+
renderIcon={carbon.icon}
26+
title={t(carbon.labelKey, carbon.label)}
27+
>
28+
{carbon.subMenu.map((subRoute) => (
29+
<SideNavMenuItem
30+
key={subRoute.path ?? subRoute.carbon.label}
31+
{...destinationProps(
32+
subRoute.path,
33+
subRoute.carbon,
34+
currentPath,
35+
)}
36+
>
37+
{t(subRoute.carbon.labelKey, subRoute.carbon.label)}
38+
</SideNavMenuItem>
39+
))}
40+
</SideNavMenu>
41+
) : (
42+
<SideNavLink
43+
key={path ?? carbon.label}
44+
renderIcon={carbon.icon}
45+
{...destinationProps(path, carbon, currentPath)}
46+
>
47+
{t(carbon.labelKey, carbon.label)}
48+
</SideNavLink>
49+
)
50+
) : null,
51+
)}
52+
</>
53+
);
54+
};

src/components/profilePanel/ProfilePanel.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ import {
1515
ThemeMenuComplement,
1616
ThemeSwitcher,
1717
} from '@carbon-labs/react-theme-settings';
18+
import { useTranslation } from 'react-i18next';
1819
import { useThemeContext } from '../../context/ThemeContext';
1920

2021
export const ProfilePanel = ({ className }) => {
22+
const { t } = useTranslation();
2123
const {
2224
themeSetting,
2325
setThemeSetting,
@@ -55,7 +57,10 @@ export const ProfilePanel = ({ className }) => {
5557
></ThemeSwitcher>
5658
<ThemeMenuComplement
5759
id="theme-menu-complement"
58-
labelText="Complement menu theme"
60+
labelText={t(
61+
'profile.settings.complementMenuTheme',
62+
'Complement menu theme',
63+
)}
5964
checked={themeMenuCompliment}
6065
onChange={(value) => setThemeMenuCompliment(value)}
6166
/>

src/i18n.client.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ i18next
1717
.use(initReactI18next)
1818
// Load translation files dynamically
1919
.use(
20-
resourcesToBackend((language, namespace) => {
20+
resourcesToBackend((language) => {
2121
// Only load non-English translations from files
2222
// English is provided as defaultValue in components
2323
if (language === 'en') {

0 commit comments

Comments
 (0)