web/LanguageDropdown: proper component style

you can't toggle the "select" element programmatically, so i had to come up with a workaround. it works and looks beautifully!

also fixed buggy overflow in SettingsToggle component.
This commit is contained in:
wukko 2024-07-08 00:18:25 +06:00
parent 35a8628cc1
commit bad7e3307d
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
4 changed files with 115 additions and 16 deletions

View file

@ -78,5 +78,7 @@
"language": "language", "language": "language",
"language.auto.title": "use default browser language", "language.auto.title": "use default browser language",
"language.auto.description": "automatically picks the best language for you. if preferred browser language isn't available, english is used instead." "language.auto.description": "automatically picks the best language for you. if preferred browser language isn't available, english is used instead.",
"language.preferred.title": "preferred language",
"language.preferred.description": "language used for interface and content."
} }

View file

@ -50,6 +50,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
overflow: hidden;
} }
.toggle-container { .toggle-container {
@ -63,5 +64,6 @@
transform: none; transform: none;
padding: calc(var(--switcher-padding) * 2) 16px; padding: calc(var(--switcher-padding) * 2) 16px;
border-radius: var(--border-radius); border-radius: var(--border-radius);
overflow: scroll;
} }
</style> </style>

View file

@ -4,6 +4,8 @@
import languages from "$i18n/languages.json"; import languages from "$i18n/languages.json";
import IconSelector from "@tabler/icons-svelte/IconSelector.svelte";
$: currentSetting = $settings.appearance.language; $: currentSetting = $settings.appearance.language;
const updateLocale = (lang: string) => { const updateLocale = (lang: string) => {
@ -11,18 +13,111 @@
appearance: { appearance: {
language: lang as keyof typeof languages, language: lang as keyof typeof languages,
}, },
}) });
} };
</script> </script>
<div class="language-selector-parent">
<div id="language-selector" class="selector button">
<div class="selector-info">
<h4 class="selector-title">
{$t("settings.language.preferred.title")}
</h4>
<div class="right-side">
<span class="selector-current" aria-hidden="true">
{$t(`languages.${currentSetting}`)}
</span>
<IconSelector />
</div>
</div>
<select <select
id="setting-dropdown-appearance-language" id="setting-dropdown-appearance-language"
bind:value={$locale} bind:value={$locale}
on:change={() => updateLocale($locale)} on:change={() => updateLocale($locale)}
> >
{#each $locales as value} {#each $locales as value}
<option value={value} selected={currentSetting === value}> <option {value} selected={currentSetting === value}>
{$t(`languages.${value}`)} {$t(`languages.${value}`)}
</option> </option>
{/each} {/each}
</select> </select>
</div>
<div class="subtext toggle-description">
{$t("settings.language.preferred.description")}
</div>
</div>
<style>
.language-selector-parent {
display: flex;
flex-direction: column;
gap: 10px;
overflow: hidden;
}
#language-selector {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
position: relative;
padding: calc(var(--switcher-padding) * 2) 16px;
pointer-events: all;
overflow: scroll;
}
.selector-info {
height: 100%;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--padding);
min-height: 26px;
z-index: 2;
pointer-events: none;
}
.right-side {
display: flex;
align-items: center;
justify-content: flex-end;
float: right;
gap: calc(var(--padding) / 2);
}
.selector-current {
font-size: 14px;
font-weight: 500;
}
.right-side :global(svg) {
stroke-width: 1.5px;
height: 20px;
width: 20px;
stroke: var(--secondary);
}
.selector select {
position: absolute;
appearance: initial;
width: 100%;
height: 100%;
font-size: 0;
background: none;
border: none;
left: 0;
border-radius: var(--border-radius);
cursor: pointer;
}
@media (hover: hover) {
.selector:hover {
background-color: var(--button-hover);
}
}
</style>

View file

@ -187,7 +187,7 @@
pointer-events: none; pointer-events: none;
} }
:global(button) { :global(button, .button) {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -208,7 +208,7 @@
z-index: 1; z-index: 1;
} }
:global(button:active) { :global(button:active, .button:active) {
background-color: var(--button-hover); background-color: var(--button-hover);
} }