mirror of
https://github.com/Lapikud/lapikud.github.io.git
synced 2026-08-08 16:29:14 +00:00
more components
This commit is contained in:
46
src/components/Image.svelte
Normal file
46
src/components/Image.svelte
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<!--
|
||||||
|
Multi-purpose image/SVG component with optional link wrapper,
|
||||||
|
hover effects, size variants, and object-fit options.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export let src = "";
|
||||||
|
export let alt = "";
|
||||||
|
export let href = null; // optional link URL
|
||||||
|
export let target = "_blank";
|
||||||
|
export let rel = "noopener noreferrer";
|
||||||
|
export let objectFit = "contain"; // 'contain' | 'cover' | 'fill' | 'none' | 'scale-down'
|
||||||
|
export let hover = false;
|
||||||
|
export let className = "";
|
||||||
|
|
||||||
|
$: objectFitClass = {
|
||||||
|
contain: "object-contain",
|
||||||
|
cover: "object-cover",
|
||||||
|
fill: "object-fill",
|
||||||
|
none: "object-none",
|
||||||
|
"scale-down": "object-scale-down"
|
||||||
|
}[objectFit];
|
||||||
|
|
||||||
|
$: hoverClasses = hover ? "transition-all duration-200 hover:scale-105 hover:opacity-90" : "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if href}
|
||||||
|
<a
|
||||||
|
{href}
|
||||||
|
{target}
|
||||||
|
{rel}
|
||||||
|
class="inline-block leading-none"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
{src}
|
||||||
|
{alt}
|
||||||
|
class="block h-auto max-w-full {objectFitClass} {hoverClasses} {className}"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<img
|
||||||
|
{src}
|
||||||
|
{alt}
|
||||||
|
class="block h-auto max-w-full {objectFitClass} {hoverClasses} {className}"
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
18
src/components/layout/FullWidthBanner.svelte
Normal file
18
src/components/layout/FullWidthBanner.svelte
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!--
|
||||||
|
Full-width colored section with configurable background and padding.
|
||||||
|
Content is projected via the default slot.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export let background = "var(--orange)";
|
||||||
|
export let paddingX = "var(--site-padding)";
|
||||||
|
export let paddingY = "var(--space-4)";
|
||||||
|
export let className = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="w-screen relative left-1/2 right-1/2 -ml-[50vw] -mr-[50vw] flex justify-center {className}"
|
||||||
|
style="background: {background}; padding: {paddingY} {paddingX};"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
@@ -5,13 +5,11 @@ const savedLang = typeof window !== 'undefined'
|
|||||||
? localStorage.getItem('language') || 'est'
|
? localStorage.getItem('language') || 'est'
|
||||||
: 'est';
|
: 'est';
|
||||||
|
|
||||||
// Store for current language
|
|
||||||
export const currentLang = writable(savedLang);
|
export const currentLang = writable(savedLang);
|
||||||
|
|
||||||
// Store for translations
|
// Store for translations
|
||||||
export const text = writable({});
|
export const text = writable({});
|
||||||
|
|
||||||
// Load translations for a specific language
|
|
||||||
async function loadTranslations(lang) {
|
async function loadTranslations(lang) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/locales/${lang}.json`);
|
const response = await fetch(`/locales/${lang}.json`);
|
||||||
@@ -22,10 +20,8 @@ async function loadTranslations(lang) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize translations
|
|
||||||
loadTranslations(savedLang);
|
loadTranslations(savedLang);
|
||||||
|
|
||||||
// Function to switch language
|
|
||||||
export function switchLang(lang) {
|
export function switchLang(lang) {
|
||||||
currentLang.set(lang);
|
currentLang.set(lang);
|
||||||
loadTranslations(lang);
|
loadTranslations(lang);
|
||||||
|
|||||||
Reference in New Issue
Block a user