feat: add language switch and localize nav links
This commit is contained in:
parent
2490529f59
commit
5f5e77b4f8
5 changed files with 165 additions and 17 deletions
|
|
@ -1,7 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { t } from '$lib/translations';
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
import logo from '$lib/assets/logo.webp';
|
import logo from '$lib/assets/logo.webp';
|
||||||
|
import LanguageSwitch from './LanguageSwitch.svelte';
|
||||||
import MediaQuery from './MediaQuery.svelte';
|
import MediaQuery from './MediaQuery.svelte';
|
||||||
|
|
||||||
let isOpen = $state(false);
|
let isOpen = $state(false);
|
||||||
|
|
@ -33,9 +35,11 @@
|
||||||
<span></span>
|
<span></span>
|
||||||
|
|
||||||
<ul id="menu">
|
<ul id="menu">
|
||||||
<a href={resolve('/about')}><li>About</li></a>
|
<a href={resolve('/about')}><li>{$t('header.aboutNav')}</li></a>
|
||||||
<a href={resolve('/viewer')}><li>Viewer</li></a>
|
<a href={resolve('/viewer')}><li>{$t('header.viewerNav')}</li></a>
|
||||||
<a href={resolve('/donate')}><li>Donate</li></a>
|
<a href={resolve('/donate')}><li>{$t('header.donateNav')}</li></a>
|
||||||
|
|
||||||
|
<li><LanguageSwitch /></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -188,7 +192,7 @@
|
||||||
background-color: var(--color-primary) !important;
|
background-color: var(--color-primary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1339px) {
|
@media (max-width: 1458px) {
|
||||||
#menuToggle span {
|
#menuToggle span {
|
||||||
background-color: var(--color-primary);
|
background-color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
145
src/lib/components/LanguageSwitch.svelte
Normal file
145
src/lib/components/LanguageSwitch.svelte
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
<script>
|
||||||
|
import { locale, SUPPORTED_LOCALES } from '$lib/translations';
|
||||||
|
|
||||||
|
const isEnglish = $derived($locale === SUPPORTED_LOCALES.EN_US);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switches the current locale to the opposite language (EN_US <-> PT_BR).
|
||||||
|
* Prevents the default link behavior (e.g., page jump).
|
||||||
|
*/
|
||||||
|
const onSwitchToOppositeLang = () => {
|
||||||
|
$locale =
|
||||||
|
$locale === SUPPORTED_LOCALES.EN_US
|
||||||
|
? SUPPORTED_LOCALES.PT_BR
|
||||||
|
: SUPPORTED_LOCALES.EN_US;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<div class="switch">
|
||||||
|
<input
|
||||||
|
id="language-toggle"
|
||||||
|
class="check-toggle check-toggle-round-flat"
|
||||||
|
type="checkbox"
|
||||||
|
onclick={onSwitchToOppositeLang}
|
||||||
|
checked={isEnglish}
|
||||||
|
onkeydown={(e) => {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
|
onSwitchToOppositeLang();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<label for="language-toggle"></label>
|
||||||
|
<span class="off">EN</span>
|
||||||
|
<span class="on">PT</span>
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.switch {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 700;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch > span {
|
||||||
|
position: absolute;
|
||||||
|
top: 7px;
|
||||||
|
pointer-events: none;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 12px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
|
||||||
|
width: 50%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.check-toggle-round-flat:checked ~ .off {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.check-toggle-round-flat:checked ~ .on {
|
||||||
|
color: var(--color-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch > span.on {
|
||||||
|
left: 0;
|
||||||
|
padding-left: 2px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch > span.off {
|
||||||
|
right: 0;
|
||||||
|
padding-right: 4px;
|
||||||
|
color: var(--color-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-toggle {
|
||||||
|
position: absolute;
|
||||||
|
margin-left: -9999px;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.check-toggle + label {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.check-toggle-round-flat + label {
|
||||||
|
padding: 2px;
|
||||||
|
width: 97px;
|
||||||
|
height: 35px;
|
||||||
|
background-color: white;
|
||||||
|
-webkit-border-radius: 60px;
|
||||||
|
-moz-border-radius: 60px;
|
||||||
|
-ms-border-radius: 60px;
|
||||||
|
-o-border-radius: 60px;
|
||||||
|
border-radius: 60px;
|
||||||
|
}
|
||||||
|
input.check-toggle-round-flat + label:before,
|
||||||
|
input.check-toggle-round-flat + label:after {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
input.check-toggle-round-flat + label:before {
|
||||||
|
top: 2px;
|
||||||
|
left: 2px;
|
||||||
|
bottom: 2px;
|
||||||
|
right: 2px;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
-moz-border-radius: 60px;
|
||||||
|
-ms-border-radius: 60px;
|
||||||
|
-o-border-radius: 60px;
|
||||||
|
border-radius: 60px;
|
||||||
|
}
|
||||||
|
input.check-toggle-round-flat + label:after {
|
||||||
|
top: 4px;
|
||||||
|
left: 4px;
|
||||||
|
bottom: 4px;
|
||||||
|
width: 48px;
|
||||||
|
background-color: var(--color-primary);
|
||||||
|
-webkit-border-radius: 52px;
|
||||||
|
-moz-border-radius: 52px;
|
||||||
|
-ms-border-radius: 52px;
|
||||||
|
-o-border-radius: 52px;
|
||||||
|
border-radius: 52px;
|
||||||
|
-webkit-transition: margin 0.2s;
|
||||||
|
-moz-transition: margin 0.2s;
|
||||||
|
-o-transition: margin 0.2s;
|
||||||
|
transition: margin 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.check-toggle-round-flat:checked + label:after {
|
||||||
|
margin-left: 42px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { PUBLIC_IMAGE_BASE_URL } from '$env/static/public';
|
import { PUBLIC_IMAGE_BASE_URL } from '$env/static/public';
|
||||||
|
import { t } from '$lib/translations';
|
||||||
import { isMobile } from '$lib/utils/isMobile';
|
import { isMobile } from '$lib/utils/isMobile';
|
||||||
|
|
||||||
const backgroundImage = isMobile()
|
const backgroundImage = isMobile()
|
||||||
|
|
@ -13,10 +14,10 @@
|
||||||
style={`background: url(${backgroundImage}) center/cover no-repeat`}
|
style={`background: url(${backgroundImage}) center/cover no-repeat`}
|
||||||
>
|
>
|
||||||
<div class="overlay">
|
<div class="overlay">
|
||||||
<h1>Preview your embroidery designs instantly — no software needed</h1>
|
<h1>{$t('hero.title')}</h1>
|
||||||
<p>Fast, private & no signup required</p>
|
<p>{$t('hero.description')}</p>
|
||||||
|
|
||||||
<a class="organic-btn" href={resolve('/viewer')}>Try Your Design</a>
|
<a class="organic-btn" href={resolve('/viewer')}>{$t('hero.cta')}</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"languageSwitch": "🇧🇷",
|
"homeNav": "Home",
|
||||||
"homeNav": "🏠 Home",
|
"aboutNav": "About",
|
||||||
"aboutNav": "ℹ About",
|
"viewerNav": "Viewer",
|
||||||
"viewerNav": "🧵 Viewer",
|
"donateNav": "Donate"
|
||||||
"donateNav": "💖 Donate"
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"languageSwitch": "🇺🇸",
|
"homeNav": "Página Inicial",
|
||||||
"homeNav": "🏠 Página Inicial",
|
"aboutNav": "Sobre",
|
||||||
"aboutNav": "ℹ Sobre",
|
"viewerNav": "Visualizador",
|
||||||
"viewerNav": "🧵 Visualizador",
|
"donateNav": "Doe"
|
||||||
"donateNav": "💖 Doe"
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue