-
-
Notifications
You must be signed in to change notification settings - Fork 480
Refactor: Form elements #1315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Refactor: Form elements #1315
Changes from 4 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
6d0a131
Refactor text/select/switch elements
arielj fc1a366
Fix overflow text behind icon
arielj 0b1676b
Refactor ToggleSwitch
arielj e024765
SelectField and TextInputField + refactor
arielj 06b267d
Merge branch 'main' into refactor/form-elements
arielj 5106087
Fix size of recently played to show
arielj 621a6dd
Replace another input with the new TextInputField component
arielj cb7b475
Make form elements more generic, don't hardcode setting class
arielj 67d7655
Remove unused css
arielj 50bb3ce
Merge branch 'main' into refactor/form-elements
arielj 766fcbf
Extract TextInputWithIconField component, fix RTL
arielj aa6f82f
Use same folder icon everywhere
arielj eb282ac
Fix checked toggle state
arielj 5dacf3a
Handle toggled state with css selector instead of class
arielj 0e84b65
Remove debugger code
arielj f8710ea
Fix width of range field in accessiblity screen
arielj ba34130
Fix margins of Fields after refactor
arielj 0c04cb8
Merge branch 'main' into refactor/form-elements
arielj 65c74dc
Fix missing ID after merge
arielj File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,13 @@ | ||
import { IpcRenderer } from 'electron' | ||
import React from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
import { SelectField } from '../SelectField' | ||
|
||
const { ipcRenderer } = window.require('electron') as { | ||
ipcRenderer: IpcRenderer | ||
} | ||
|
||
const storage: Storage = window.localStorage | ||
|
||
export enum FlagPosition { | ||
NONE = 'none', | ||
|
@@ -7,85 +16,94 @@ export enum FlagPosition { | |
} | ||
|
||
interface Props { | ||
className?: string | ||
currentLanguage?: string | ||
flagPossition?: FlagPosition | ||
handleLanguageChange: (language: string) => void | ||
showWeblateLink?: boolean | ||
} | ||
|
||
const languageLabels: { [key: string]: string } = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. moved these 2 constants outside the component so they are not initialized in every call to the function |
||
bg: 'български', | ||
ca: 'Català', | ||
cs: 'Čeština', | ||
de: 'Deutsch', | ||
el: 'Greek', | ||
en: 'English', | ||
es: 'Español', | ||
et: 'Eesti keel', | ||
fa: 'فارسی', | ||
fi: 'Suomen kieli', | ||
fr: 'Français', | ||
gl: 'Galego', | ||
hu: 'Magyar', | ||
hr: 'Hrvatski', | ||
ja: '日本語', | ||
ko: '한국어', | ||
id: 'Bahasa Indonesia', | ||
it: 'Italiano', | ||
ml: 'മലയാളം', | ||
nl: 'Nederlands', | ||
pl: 'Polski', | ||
pt: 'Português', | ||
pt_BR: 'Português (Brasil)', | ||
ru: 'Русский', | ||
sv: 'Svenska', | ||
ta: 'தமிழ்', | ||
tr: 'Türkçe', | ||
uk: 'украї́нська мо́ва', | ||
vi: 'tiếng Việt', | ||
zh_Hans: '简化字', | ||
zh_Hant: '漢語' | ||
} | ||
|
||
const languageFlags: { [key: string]: string } = { | ||
// Catalan isn't a sovereign state (yet). So it hasn't a flag in the unicode standard. | ||
bg: '🇧🇬', | ||
ca: '🇪🇸', | ||
cs: '🇨🇿', | ||
de: '🇩🇪', | ||
el: '🇬🇷', | ||
en: '🇬🇧', | ||
es: '🇪🇸', | ||
et: '🇪🇪', | ||
fa: '🇮🇷', | ||
fi: '🇫🇮', | ||
fr: '🇫🇷', | ||
gl: '🇪🇸', | ||
hu: '🇭🇺', | ||
hr: '🇭🇷', | ||
ja: '🇯🇵', | ||
ko: '🇰🇷', | ||
id: '🇮🇩', | ||
it: '🇮🇹', | ||
ml: '🇮🇳', | ||
nl: '🇳🇱', | ||
pl: '🇵🇱', | ||
pt: '🇵🇹', | ||
pt_BR: '🇧🇷', | ||
ru: '🇷🇺', | ||
sv: '🇸🇪', | ||
ta: '🇮🇳', | ||
tr: '🇹🇷', | ||
uk: '🇺🇦', | ||
vi: '🇻🇳', | ||
zh_Hans: '🇨🇳', | ||
zh_Hant: '🇨🇳' | ||
} | ||
|
||
export default function LanguageSelector({ | ||
handleLanguageChange, | ||
currentLanguage = 'en', | ||
className = 'settingSelect', | ||
flagPossition = FlagPosition.NONE | ||
flagPossition = FlagPosition.NONE, | ||
showWeblateLink = false | ||
}: Props) { | ||
const languageLabels: { [key: string]: string } = { | ||
bg: 'български', | ||
ca: 'Català', | ||
cs: 'Čeština', | ||
de: 'Deutsch', | ||
el: 'Greek', | ||
en: 'English', | ||
es: 'Español', | ||
et: 'Eesti keel', | ||
fa: 'فارسی', | ||
fi: 'Suomen kieli', | ||
fr: 'Français', | ||
gl: 'Galego', | ||
hu: 'Magyar', | ||
hr: 'Hrvatski', | ||
ja: '日本語', | ||
ko: '한국어', | ||
id: 'Bahasa Indonesia', | ||
it: 'Italiano', | ||
ml: 'മലയാളം', | ||
nl: 'Nederlands', | ||
pl: 'Polski', | ||
pt: 'Português', | ||
pt_BR: 'Português (Brasil)', | ||
ru: 'Русский', | ||
sv: 'Svenska', | ||
ta: 'தமிழ்', | ||
tr: 'Türkçe', | ||
uk: 'украї́нська мо́ва', | ||
vi: 'tiếng Việt', | ||
zh_Hans: '简化字', | ||
zh_Hant: '漢語' | ||
const { t, i18n } = useTranslation() | ||
const currentLanguage = i18n.language || 'en' | ||
|
||
const handleChangeLanguage = (language: string) => { | ||
ipcRenderer.send('changeLanguage', language) | ||
storage.setItem('language', language) | ||
i18n.changeLanguage(language) | ||
} | ||
|
||
const languageFlags: { [key: string]: string } = { | ||
// Catalan isn't a sovereign state (yet). So it hasn't a flag in the unicode standard. | ||
bg: '🇧🇬', | ||
ca: '🇪🇸', | ||
cs: '🇨🇿', | ||
de: '🇩🇪', | ||
el: '🇬🇷', | ||
en: '🇬🇧', | ||
es: '🇪🇸', | ||
et: '🇪🇪', | ||
fa: '🇮🇷', | ||
fi: '🇫🇮', | ||
fr: '🇫🇷', | ||
gl: '🇪🇸', | ||
hu: '🇭🇺', | ||
hr: '🇭🇷', | ||
ja: '🇯🇵', | ||
ko: '🇰🇷', | ||
id: '🇮🇩', | ||
it: '🇮🇹', | ||
ml: '🇮🇳', | ||
nl: '🇳🇱', | ||
pl: '🇵🇱', | ||
pt: '🇵🇹', | ||
pt_BR: '🇧🇷', | ||
ru: '🇷🇺', | ||
sv: '🇸🇪', | ||
ta: '🇮🇳', | ||
tr: '🇹🇷', | ||
uk: '🇺🇦', | ||
vi: '🇻🇳', | ||
zh_Hans: '🇨🇳', | ||
zh_Hant: '🇨🇳' | ||
function handleWeblate() { | ||
return ipcRenderer.send('openWeblate') | ||
} | ||
|
||
const renderOption = (lang: string) => { | ||
|
@@ -100,14 +118,32 @@ export default function LanguageSelector({ | |
</option> | ||
) | ||
} | ||
|
||
let afterSelect = null | ||
if (showWeblateLink) { | ||
afterSelect = ( | ||
<a | ||
data-testid="buttonWeblate" | ||
onClick={handleWeblate} | ||
className="smallLink" | ||
> | ||
{t('other.weblate', 'Help Improve this translation.')} | ||
</a> | ||
) | ||
} | ||
|
||
return ( | ||
<select | ||
data-testid="languageSelector" | ||
onChange={(event) => handleLanguageChange(event.target.value)} | ||
className={`${className} is-drop-down`} | ||
value={currentLanguage} | ||
> | ||
{Object.keys(languageLabels).map((lang) => renderOption(lang))} | ||
</select> | ||
<> | ||
<SelectField | ||
htmlId="languageSelector" | ||
onChange={(event) => handleChangeLanguage(event.target.value)} | ||
value={currentLanguage} | ||
label={t('setting.language', 'Choose App Language')} | ||
extraClass="languageSelector" | ||
afterSelect={afterSelect} | ||
> | ||
{Object.keys(languageLabels).map((lang) => renderOption(lang))} | ||
</SelectField> | ||
</> | ||
) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
.selectWrapper { | ||
display: grid; | ||
grid-template-areas: 'label' 'select'; | ||
} | ||
|
||
.selectWrapper select { | ||
grid-area: select; | ||
width: 100%; | ||
height: 40px; | ||
background: var(--input-background); | ||
border-radius: 10px; | ||
font-family: var(--content-font-family), 'Noto Color Emoji'; | ||
font-weight: normal; | ||
font-size: 16px; | ||
line-height: 19px; | ||
color: var(--text-secondary); | ||
text-indent: 22px; | ||
border: none; | ||
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); | ||
cursor: pointer; | ||
background-image: linear-gradient( | ||
45deg, | ||
transparent 50%, | ||
var(--text-secondary) 50% | ||
), | ||
linear-gradient(135deg, var(--text-secondary) 50%, transparent 50%), | ||
linear-gradient(to right, #ccc, #ccc); | ||
background-position: calc(100% - 20px) calc(50% + 1px), | ||
calc(100% - 15px) calc(50% + 1px), calc(100% - 40px) 50%; | ||
background-size: 5px 5px, 5px 5px, 1px 70%; | ||
background-repeat: no-repeat; | ||
margin: 0; | ||
-webkit-box-sizing: border-box; | ||
-moz-box-sizing: border-box; | ||
box-sizing: border-box; | ||
-webkit-appearance: none; | ||
-moz-appearance: none; | ||
min-width: 100px; | ||
} | ||
|
||
.selectWrapper label { | ||
justify-self: flex-start; | ||
grid-area: label; | ||
align-self: center; | ||
} | ||
|
||
.selectWrapper select:disabled { | ||
cursor: not-allowed; | ||
} | ||
|
||
.selectWrapper.small select { | ||
width: clamp(150px, 10rem, 372px); | ||
} | ||
|
||
.selectWrapper.smaller select { | ||
width: 66px; | ||
text-indent: 11px; | ||
} | ||
|
||
.selectWrapper.small, | ||
.selectWrapper.smaller { | ||
grid-template-areas: 'select label'; | ||
grid-template-columns: min-content 1fr; | ||
} | ||
|
||
.selectWrapper.small label, | ||
.selectWrapper.smaller label { | ||
margin: 0px 1rem; | ||
} | ||
|
||
.selectWrapper select > option { | ||
background: var(--navbar-background); | ||
height: 40px; | ||
color: var(--text-secondary); | ||
text-indent: 22px; | ||
font-size: 16px; | ||
border-radius: 10px; | ||
} | ||
|
||
.selectWrapper.rightButtons { | ||
grid-template: 'label label' 'select buttons'; | ||
grid-template-columns: auto min-content; | ||
grid-column-gap: 0.5rem; | ||
} | ||
|
||
.selectWrapper.rightButtons label { | ||
grid-area: label; | ||
} | ||
|
||
.selectWrapper.rightButtons .rightButtons { | ||
grid-area: buttons; | ||
align-self: center; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing, not really related with the PR.
Have you noticed that we are using two different folder icons? one on the settings and another on the InstallModal.
I think we should pick one, maybe the one that we are using on the InstallModal looks a bit better imo.
But we can do that in another task if you think this could increase the scope of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I didn't know the reason so I just skipped that, I agree that a single icon in all palces would look better
I'm also thinking about adding another component
PathInputField
that would take care of the input with the folder icon, we use that in a lot of places, I think it's a good opportunity to simplify thatThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extracted a TextInputWithIconField component instead, maybe we can extract a PathInputField in the future, but not all path inputs behave the same so decided to go with a more generic input with icon