From 9b809e4ecbc9f2120d3e51bf6cb812317135c864 Mon Sep 17 00:00:00 2001 From: dev Date: Mon, 25 May 2026 12:18:30 +0200 Subject: [PATCH] chore(eidos): drop \$app/environment imports (decouple from SvelteKit) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eidos es la capa visual y debe ser framework-agnostic. Tres componentes metian `import { browser } from '\$app/environment'` por reflejo defensivo SSR sin pensar la consecuencia. relative-time.svelte: - Drop completo del guard. El `\$effect` solo corre client-side en Svelte 5; el `if (!browser) return` era codigo muerto. s-text.svelte + s-text-virtual-list.svelte: - Aqui si hace falta guard (los `\$derived` corren durante SSR para inicializar valores; `getComputedStyle(el)` lanza si lo invocas en server). Pero reemplazo `browser` con `const isBrowser = typeof window !== 'undefined'` local — mismo comportamiento, cero coupling con SvelteKit. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../eidos/components/relative-time/relative-time.svelte | 3 +-- .../s-text-virtual-list/s-text-virtual-list.svelte | 9 ++++++--- src/uix/eidos/components/s-text/s-text.svelte | 6 ++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/uix/eidos/components/relative-time/relative-time.svelte b/src/uix/eidos/components/relative-time/relative-time.svelte index 0f8143935..3f87bca4f 100644 --- a/src/uix/eidos/components/relative-time/relative-time.svelte +++ b/src/uix/eidos/components/relative-time/relative-time.svelte @@ -15,7 +15,6 @@ * Pass `updateInterval={0}` to render once and stop. */ import { onDestroy } from 'svelte'; - import { browser } from '$app/environment'; import { getActiveUix } from '$active-uix'; import type { RelativeTimeInput, @@ -141,8 +140,8 @@ let timer: ReturnType | null = null; + // `$effect` only runs client-side in Svelte 5, no SSR guard needed. $effect(() => { - if (!browser) return; if (intervalMs <= 0) return; timer = setInterval(() => { tick += 1; diff --git a/src/uix/eidos/components/s-text-virtual-list/s-text-virtual-list.svelte b/src/uix/eidos/components/s-text-virtual-list/s-text-virtual-list.svelte index dd562f722..0142f69a1 100644 --- a/src/uix/eidos/components/s-text-virtual-list/s-text-virtual-list.svelte +++ b/src/uix/eidos/components/s-text-virtual-list/s-text-virtual-list.svelte @@ -13,12 +13,15 @@ * cheapest way to compute total height without mounting the rows. */ import './s-text-virtual-list.css'; - import { browser } from '$app/environment'; import { ActiveEidos } from '$uix/eidos'; import { prepare, layout } from '$uix/eidos/lib/canvas-text/layout'; import { useContainerWidth } from '$uix/eidos/lib/canvas-text/use-canvas.svelte'; import type { STextVirtualListProps } from './types'; + // SvelteKit-agnostic browser check — Eidos must not import from + // `$app/environment` (couples the visual layer to a specific framework). + const isBrowser = typeof window !== 'undefined'; + let { items = [], size = 'md', @@ -52,7 +55,7 @@ // Read computed style from the container — the recipe is responsible // for mapping our resolved tokens to actual px / family strings. const font = $derived.by(() => { - if (!browser || !containerEl) return '14px sans-serif'; + if (!isBrowser || !containerEl) return '14px sans-serif'; const cs = getComputedStyle(containerEl); const fontSize = cs.fontSize || '14px'; const fontFamily = cs.fontFamily || 'sans-serif'; @@ -62,7 +65,7 @@ const lineHeightPx = $derived.by(() => { if (lineHeightProp != null) return lineHeightProp; - if (!browser || !containerEl) return 21; + if (!isBrowser || !containerEl) return 21; const cs = getComputedStyle(containerEl); const lh = cs.lineHeight; if (lh && lh.endsWith('px')) return parseFloat(lh) || 21; diff --git a/src/uix/eidos/components/s-text/s-text.svelte b/src/uix/eidos/components/s-text/s-text.svelte index 6be99f917..16ead4001 100644 --- a/src/uix/eidos/components/s-text/s-text.svelte +++ b/src/uix/eidos/components/s-text/s-text.svelte @@ -19,7 +19,9 @@ * line counts. */ import './s-text.css'; - import { browser } from '$app/environment'; + // SvelteKit-agnostic browser check — Eidos must not import from + // `$app/environment` (couples the visual layer to a specific framework). + const isBrowser = typeof window !== 'undefined'; import { ActiveEidos } from '$uix/eidos'; import { getActiveUix } from '$active-uix'; import { useContainerWidth, useTextLayout } from '$uix/eidos/lib/canvas-text/use-canvas.svelte'; @@ -82,7 +84,7 @@ // Canvas measurement is opt-in: only when `text` AND we're in the // browser. SSR + `text === undefined` path stays a plain element // with CSS-only clamping. - const canvasActive = $derived(text != null && browser); + const canvasActive = $derived(text != null && isBrowser); let textEl = $state(null); const measure = useContainerWidth(() => (canvasActive ? textEl : null));