You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/web/routes/blocks/_lib/BootUix.svelte

106 lines
3.1 KiB

<script lang="ts">
/**
* The UIX boot chain for the blocks section, in one place: the shell uses it
* for the documentation pages, and each block's `preview` route uses it too
* — a preview is a REAL page (its own document, its own viewport scroll), so
* it boots the framework itself instead of inheriting the section chrome.
*
* The axes arrive as props so the preview can be driven from its URL:
* `?mode=dark&dir=rtl&lang=en` is what the demo's iframe passes.
*/
import './reset.css';
import { onDestroy } from 'svelte';
import { createActiveUix, setActiveUix } from '$active-uix';
import { standardPrefsDimensions } from '$prefs';
import { Soma } from '$soma/core/soma.svelte';
import { siumLangs } from '$sium/langs/langs';
import { secsLangs } from '$libs/secs';
import { blocksLangs } from './blocks-langs';
import { ActiveEidos } from '$uix/eidos';
import { semaPacks } from './sema-packs';
import type { Snippet } from 'svelte';
export type BootLanguage = 'es' | 'en' | 'fr' | 'de';
export type BootDensity = 'compact' | 'comfortable' | 'spacious';
let {
mode = 'light',
language = 'es',
dir = 'ltr',
density = 'comfortable',
children
}: {
mode?: 'light' | 'dark';
language?: BootLanguage;
dir?: 'ltr' | 'rtl';
density?: BootDensity;
children: Snippet;
} = $props();
const DENSITY_SCALES: Record<BootDensity, { space: number; control: number }> = {
compact: { space: 0.85, control: 0.9 },
comfortable: { space: 1, control: 1 },
spacious: { space: 1.15, control: 1.1 }
};
const prefsSchema = standardPrefsDimensions({
languages: ['es', 'en', 'fr', 'de'] as const,
locales: ['es-ES', 'en-US', 'en-GB', 'de-DE'] as const,
currencies: ['EUR', 'USD', 'GBP', 'JPY'] as const,
defaults: { language: 'es', locale: 'es-ES', currency: 'EUR' }
});
const uix = createActiveUix({
langs: {
schema: { sium: siumLangs, secs: secsLangs, blocks: blocksLangs },
defaultLocale: 'es' as const
},
// The blocks tier is shown, not shipped: this is the gallery of a SEMANTIC
// framework, so the perceptual channels are on. Without this the engine
// still stamps `data-event-*` correctly and nothing is ever audible —
// which is how the section shipped from F0.
events: { sound: true, haptic: true, components: semaPacks },
prefs: { schema: prefsSchema }
});
setActiveUix(uix);
Soma.create();
const modeListeners = new Set<(value: 'light' | 'dark') => void>();
const activeEidos = ActiveEidos.create({
applyDom: true,
theme: 'base',
modeSource: {
get: () => mode,
onChange(handler) {
modeListeners.add(handler);
return () => modeListeners.delete(handler);
}
}
});
$effect(() => {
const current = mode;
for (const listener of modeListeners) listener(current);
});
$effect(() => {
uix.prefs.setIntent('language', language);
uix.prefs.setIntent('direction', dir);
});
$effect(() => {
const d = DENSITY_SCALES[density];
uix.dom.writeStyle(
'uix-blocks-display',
`:root{--density-space-scale:${d.space};--density-control-scale:${d.control};}`
);
});
onDestroy(() => {
activeEidos.dispose();
uix.dispose();
});
</script>
{@render children()}

Powered by TurnKey Linux.