demo(site-header): controles vivos de cada prop + ejes claro/oscuro y RTL

La demo cumplía B-9 (existe y está enlazada) pero se quedaba corta frente a
la ficha del plan («claro/oscuro, 375/1280, RTL») y a la doctrina de demos
como banco de pruebas: `offset`, `container` y `breakpoint` no tenían
control, y la dirección no era un eje de la página.

Ahora cada prop público se maneja en vivo con `ToggleGroup`/`Field` del
ecosistema (nada de nativos crudos) y la página entera cuelga de un `dir`
conmutable. El modo de color NO lleva control a propósito: esta sección sigue
el esquema del sistema operativo por diseño del layout, así que oscuro se
verifica emulando `prefers-color-scheme`.

Verificado en navegador: `container` lg→sm mueve la medida (1024→480px);
`breakpoint` discrimina de verdad (a 800px, con `md` se ve la nav y con
`lg` aparece el drawer); RTL espeja la barra entera (marca a la derecha,
acciones a la izquierda) y oscuro pinta el header sobre superficie oscura.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
alpha-0.1-sec-dom
dev 3 months ago
parent 3cfc030b3a
commit 016658a0c9

@ -17,16 +17,29 @@
import { Heading } from '$uix/eidos/components/heading';
import { Text } from '$uix/eidos/components/text';
import { Separator } from '$uix/eidos/components/separator';
import { ToggleGroup } from '$uix/eidos/components/toggle-group';
import { Field } from '$uix/eidos/components/field';
import * as Icon from '$uix/eidos/components/icon';
// Every public prop of the block gets a live control (demo doctrine); the
// colour mode is not one of them — this section follows the OS scheme by
// design (see the layout), so dark is verified by emulating the media query.
let sticky = $state(true);
let mobileOpen = $state(false);
let offset = $state(0);
let container = $state<'sm' | 'md' | 'lg' | 'xl' | 'full'>('lg');
let breakpoint = $state<'sm' | 'md' | 'lg'>('md');
let dir = $state<'ltr' | 'rtl'>('ltr');
const sections = ['Product', 'Solutions', 'Developers', 'Pricing', 'Company'];
</script>
<div {dir}>
<SiteHeader
{sticky}
{offset}
{container}
{breakpoint}
aria-label="Site"
bind:mobileOpen
style="background: var(--color-surface-default); border-block-end: var(--border-width) solid var(--color-border-subtle);"
@ -115,14 +128,70 @@
<code>data-stuck</code>, which is what this page uses to raise its own surface. The block
itself paints nothing.
</Text>
<Group gap={2}>
<Button size="sm" variant={sticky ? 'solid' : 'outline'} onclick={() => (sticky = true)}>
sticky
</Button>
<Button size="sm" variant={sticky ? 'outline' : 'solid'} onclick={() => (sticky = false)}>
static
</Button>
</Group>
<Stack gap={3}>
<Group gap={2} align="center" justify="start">
<Text size="sm" color="muted">sticky</Text>
<ToggleGroup
selectionMode="single"
size="sm"
attached
value={[sticky ? 'sticky' : 'static']}
onValueChange={(v) => (sticky = (v[0] ?? 'sticky') === 'sticky')}
aria-label="sticky"
>
<ToggleGroup.Item value="sticky">sticky</ToggleGroup.Item>
<ToggleGroup.Item value="static">static</ToggleGroup.Item>
</ToggleGroup>
<Text size="sm" color="muted">container</Text>
<ToggleGroup
selectionMode="single"
size="sm"
attached
value={[container]}
onValueChange={(v) => (container = (v[0] ?? container) as typeof container)}
aria-label="container"
>
{#each ['sm', 'md', 'lg', 'xl', 'full'] as value (value)}
<ToggleGroup.Item {value}>{value}</ToggleGroup.Item>
{/each}
</ToggleGroup>
</Group>
<Group gap={2} align="center" justify="start">
<Text size="sm" color="muted">breakpoint</Text>
<ToggleGroup
selectionMode="single"
size="sm"
attached
value={[breakpoint]}
onValueChange={(v) => (breakpoint = (v[0] ?? breakpoint) as typeof breakpoint)}
aria-label="breakpoint"
>
{#each ['sm', 'md', 'lg'] as value (value)}
<ToggleGroup.Item {value}>{value}</ToggleGroup.Item>
{/each}
</ToggleGroup>
<Text size="sm" color="muted">dir</Text>
<ToggleGroup
selectionMode="single"
size="sm"
attached
value={[dir]}
onValueChange={(v) => (dir = (v[0] ?? dir) as typeof dir)}
aria-label="direction"
>
<ToggleGroup.Item value="ltr">ltr</ToggleGroup.Item>
<ToggleGroup.Item value="rtl">rtl</ToggleGroup.Item>
</ToggleGroup>
<Field size="sm" style="inline-size: 10rem;">
<Field.Label>offset (px)</Field.Label>
<Field.Input type="number" value={String(offset)} oninput={(e) => (offset = Number((e.currentTarget as HTMLInputElement).value) || 0)} />
</Field>
</Group>
</Stack>
</Stack>
</Container>
</Section>
@ -145,3 +214,4 @@
</Container>
</Section>
{/each}
</div>

Loading…
Cancel
Save

Powered by TurnKey Linux.