Files
web-app-launcher/src/lib/components/widget/EmbedWidget.svelte
T
alexei.dolgolyov 477c0e4d52 feat(phase2): localization EN/RU + additional widget types
- Add svelte-i18n with 224 translation keys (English + Russian)
- Language switcher in header (EN/RU toggle, persists to localStorage)
- Extract all hardcoded strings from 37 component/page files
- Add 4 new widget types: Bookmark, Note (markdown), Embed (iframe), Status
- WidgetRenderer dispatches by type, WidgetGrid supports full-width widgets
- Type-specific config forms in board editor
- Install marked for markdown rendering
2026-03-24 23:18:05 +03:00

51 lines
1.2 KiB
Svelte

<script lang="ts">
interface EmbedConfig {
url: string;
height: number;
sandbox?: string;
}
interface Props {
config: EmbedConfig;
}
let { config }: Props = $props();
let loading = $state(true);
const iframeHeight = $derived(config.height || 300);
const sandboxValue = $derived(config.sandbox || 'allow-scripts allow-same-origin');
function handleLoad() {
loading = false;
}
</script>
<div class="flex flex-col rounded-xl border border-border bg-card">
<div class="relative" style="height: {iframeHeight}px;">
{#if loading}
<div class="absolute inset-0 flex items-center justify-center bg-muted/50">
<div class="flex items-center gap-2 text-sm text-muted-foreground">
<svg
class="h-4 w-4 animate-spin"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>
Loading...
</div>
</div>
{/if}
<iframe
src={config.url}
title="Embedded content"
sandbox={sandboxValue}
class="h-full w-full rounded-xl border-0"
onload={handleLoad}
></iframe>
</div>
</div>