1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-18 20:59:44 +02:00

feat: use react-world-flags for language selector and unify flag styles

- Switched language selector flags to react-world-flags for reliable SVG rendering
- Added dedicated SCSS module for flag styling to ensure consistent size and alignment
- All flags are now perfectly centered and visually unified in the dropdown
- Removed old flag-icons integration and related styles
This commit is contained in:
symonbaikov 2025-06-05 18:35:55 +03:00
parent 49770ea9ec
commit e14795cd27
4 changed files with 66 additions and 5 deletions

View file

@ -75,6 +75,7 @@
"react-router-dom": "^6.30.1",
"react-textarea-autosize": "^8.5.9",
"react-time-ago": "^7.3.3",
"react-world-flags": "^1.6.0",
"redux": "^4.2.1",
"redux-logger": "^3.0.6",
"redux-orm": "^0.16.2",
@ -4734,11 +4735,19 @@
"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
"dev": true
},
"node_modules/@types/prop-types": {
"version": "15.7.14",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
"license": "MIT"
},
"node_modules/@types/react": {
"version": "19.1.6",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz",
"integrity": "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==",
"version": "18.3.23",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
"integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
}
},
@ -12531,6 +12540,20 @@
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-world-flags": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/react-world-flags/-/react-world-flags-1.6.0.tgz",
"integrity": "sha512-eutSeAy5YKoVh14js/JUCSlA6EBk1n4k+bDaV+NkNB50VhnG+f4QDTpYycnTUTsZ5cqw/saPmk0Z4Fa0VVZ1Iw==",
"license": "MIT",
"dependencies": {
"svg-country-flags": "^1.2.10",
"svgo": "^3.0.2",
"world-countries": "^5.0.0"
},
"peerDependencies": {
"react": ">=0.14"
}
},
"node_modules/read-package-up": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
@ -14169,6 +14192,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/svg-country-flags": {
"version": "1.2.10",
"resolved": "https://registry.npmjs.org/svg-country-flags/-/svg-country-flags-1.2.10.tgz",
"integrity": "sha512-xrqwo0TYf/h2cfPvGpjdSuSguUbri4vNNizBnwzoZnX0xGo3O5nGJMlbYEp7NOYcnPGBm6LE2axqDWSB847bLw==",
"license": "PD"
},
"node_modules/svg-parser": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
@ -15228,6 +15257,11 @@
"node": ">=0.10.0"
}
},
"node_modules/world-countries": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/world-countries/-/world-countries-5.1.0.tgz",
"integrity": "sha512-CXR6EBvTbArDlDDIWU3gfKb7Qk0ck2WNZ234b/A0vuecPzIfzzxH+O6Ejnvg1sT8XuiZjVlzOH0h08ZtaO7g0w=="
},
"node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",

View file

@ -146,6 +146,7 @@
"react-router-dom": "^6.30.1",
"react-textarea-autosize": "^8.5.9",
"react-time-ago": "^7.3.3",
"react-world-flags": "^1.6.0",
"redux": "^4.2.1",
"redux-logger": "^3.0.6",
"redux-orm": "^0.16.2",

View file

@ -7,6 +7,7 @@ import React, { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';
import { Button, Divider, Dropdown, Header, Tab } from 'semantic-ui-react';
import Flag from 'react-world-flags';
import { usePopupInClosableContext } from '../../../../hooks';
import locales from '../../../../locales';
@ -21,6 +22,7 @@ import selectors from '../../../../selectors';
import entryActions from '../../../../entry-actions';
import styles from './AccountPane.module.scss';
import localeFlagStyles from '../LocaleFlag.module.scss';
const AccountPane = React.memo(() => {
const user = useSelector(selectors.selectCurrentUser);
@ -70,8 +72,20 @@ const AccountPane = React.memo(() => {
},
...locales.map((locale) => ({
value: locale.language,
flag: locale.country,
text: locale.name,
text: (
<>
{locale.country && (
<span className={localeFlagStyles.localeFlagWrapper}>
<Flag
code={locale.country.toUpperCase()}
className={localeFlagStyles.localeFlag}
fallback={<span className={localeFlagStyles.localeFlag} />}
/>
</span>
)}
{locale.name}
</>
),
})),
]}
value={user.language || 'auto'}

View file

@ -0,0 +1,12 @@
.localeFlag {
width: 24px;
height: 16px;
margin-right: 8px;
border-radius: 2px;
object-fit: cover;
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: middle;
background: #f5f5f5; // fallback bg для прозрачных флагов
}