blocks(app-shell): «no compone ningún block todavía» no era una razón, era una casilla vacía

El shell declara la excepción B-10 —los shells componen otros blocks por
diseño— y no compone ninguno. Eso estaba escrito como si fuera una tarea
pendiente. No lo es, y ahora dice por qué.

El candidato obvio es `site-header`, y es la pieza equivocada aquí por tres
cosas que están en su propio API: es `Sticky` por defecto (una barra de
aplicación bajo `scroll="main"` NO debe pegarse — nada se desplaza por debajo
de ella), envuelve su contenido en un `Container` MEDIDA (una barra de app va de
borde a borde de su inset), y su forma es marca · nav · acciones + drawer
móvil, o sea una SEGUNDA navegación dentro de un shell cuya navegación es el
raíl. Es el cromo de un SITIO; esto es una aplicación.

Lo que sí falta, y queda registrado como gap: lo que una barra de aplicación
sostiene de verdad —disparador del raíl, rastro, buscador, avisos, menú de
usuario— no tiene pieza en el tier. `user-menu` (F3.6) y `notifications` (F3.7)
están planificados y sin construir, y el shell los compondrá POR esta misma
excepción el día que aterricen. Hasta entonces la barra es el snippet del app,
montada con canon (`Sidebar.Trigger` + `Breadcrumb` + `Toolbar` + `Button`), que
es lo que enseña la demo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alpha-0.1-background
dev 2 months ago
parent db7bcc3a55
commit e5f30a501d

@ -203,14 +203,15 @@ lo logra. Una receta que no se ha visto en el navegador NO entra en esta tabla._
## Gaps
| Gap | Disposición |
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Los primitivos de layout no pueden cambiar de elemento** (F21) | **canon, registrado**: `Box` —y con él `Grid`/`Flex`/`Stack`— renderiza un `<div>` fijo, así que `<main>` / `<aside>` no pueden SER una caja del sistema. Por eso esos dos elementos llevan un `style` en línea con dos declaraciones (`flex`, `min-inline-size`, `overflow`). No es re-estilizar internals de un compuesto (B-3): es el elemento propio del block. Precedente en el tier: `article-grid-article.svelte` |
| **Topbar a todo lo ancho** (eje `layout` del `Sidebar`) | **canon, v2** — el provider del `Sidebar` es la fila flex. Lo pedirá `docs-shell` (F4.1) |
| **El `Sidebar` no publica su ancho actual** | no hace falta aquí (la reserva es flexbox), pero un app que quiera anclar algo al borde del rail no tiene a qué. Mantine expone 8 vars `--app-shell-*`; anotado por si aparece un consumidor real |
| **Superficie online/offline** | no existe en el ecosistema (ni art ni dimensión de prefs). Un ribbon de «sin conexión» en `banner` lo tiene que alimentar el app desde `Connections.anyReconnecting` |
| **Dos landmarks `banner`** cuando el `banner` que entra es el canon `Banner` | **ledger A-109**, del canon: `Banner` estampa `role="banner"` DESPUÉS de los rest props, así que no se puede quitar. Nombrar los dos es todo lo que puede un app |
| `scroll-margin-block-start` en los destinos bajo `scroll="body"` | del consumidor: la altura de la cabecera la sabe él. Lo cerrará `docs-shell`, que es quien tiene anclas |
| **`Sidebar.MenuButton` es MUDO y `NavigationMenu.Link` no** — el mismo acto, dos respuestas | **canon, para una sesión de sema**: elegir un destino en una superficie de navegación emite `commit-select` en el `NavigationMenu` y NADA en el `Sidebar` ni en el `NavTree` (sus morfos sólo declaran `emerge-expand`/`emerge-collapse` sobre el panel). El README del `Sidebar` lo firma —«navegar una fila es nativo y no suena»— pero entonces el `NavigationMenu` contradice la firma. Además, en un shell la fila del raíl casi nunca navega: SELECCIONA la sección (`aria-current="page"`), que es exactamente el caso de `commit.select`. No se decide desde el tier |
| **`Toolbar.Button` no acepta `variant`/`color`** | **canon, anotado**: `ToolbarButtonProps` tipa contra el `ButtonProps` de SOMA (`{ id, disabled }`), así que el tratamiento es del root y todos los ítems lo llevan igual. Un grupo donde una acción es la principal no tiene cómo decirlo desde dentro; aquí la principal va al lado del cluster, como en las referencias |
| **No existe `description-list`** | **canon, F5**: el backlog lo condiciona a «el primer detail-view real» — y el panel de detalle de este shell lo es. Mientras no exista, el significado lo llevan `dl`/`dt`/`dd` con la tipografía del tema, y se declara aquí en vez de fingirlo con `div`s |
| Gap | Disposición |
| ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Los primitivos de layout no pueden cambiar de elemento** (F21) | **canon, registrado**: `Box` —y con él `Grid`/`Flex`/`Stack`— renderiza un `<div>` fijo, así que `<main>` / `<aside>` no pueden SER una caja del sistema. Por eso esos dos elementos llevan un `style` en línea con dos declaraciones (`flex`, `min-inline-size`, `overflow`). No es re-estilizar internals de un compuesto (B-3): es el elemento propio del block. Precedente en el tier: `article-grid-article.svelte` |
| **Topbar a todo lo ancho** (eje `layout` del `Sidebar`) | **canon, v2** — el provider del `Sidebar` es la fila flex. Lo pedirá `docs-shell` (F4.1) |
| **El `Sidebar` no publica su ancho actual** | no hace falta aquí (la reserva es flexbox), pero un app que quiera anclar algo al borde del rail no tiene a qué. Mantine expone 8 vars `--app-shell-*`; anotado por si aparece un consumidor real |
| **Superficie online/offline** | no existe en el ecosistema (ni art ni dimensión de prefs). Un ribbon de «sin conexión» en `banner` lo tiene que alimentar el app desde `Connections.anyReconnecting` |
| **Dos landmarks `banner`** cuando el `banner` que entra es el canon `Banner` | **ledger A-109**, del canon: `Banner` estampa `role="banner"` DESPUÉS de los rest props, así que no se puede quitar. Nombrar los dos es todo lo que puede un app |
| `scroll-margin-block-start` en los destinos bajo `scroll="body"` | del consumidor: la altura de la cabecera la sabe él. Lo cerrará `docs-shell`, que es quien tiene anclas |
| **`Sidebar.MenuButton` es MUDO y `NavigationMenu.Link` no** — el mismo acto, dos respuestas | **canon, para una sesión de sema**: elegir un destino en una superficie de navegación emite `commit-select` en el `NavigationMenu` y NADA en el `Sidebar` ni en el `NavTree` (sus morfos sólo declaran `emerge-expand`/`emerge-collapse` sobre el panel). El README del `Sidebar` lo firma —«navegar una fila es nativo y no suena»— pero entonces el `NavigationMenu` contradice la firma. Además, en un shell la fila del raíl casi nunca navega: SELECCIONA la sección (`aria-current="page"`), que es exactamente el caso de `commit.select`. No se decide desde el tier |
| **`Toolbar.Button` no acepta `variant`/`color`** | **canon, anotado**: `ToolbarButtonProps` tipa contra el `ButtonProps` de SOMA (`{ id, disabled }`), así que el tratamiento es del root y todos los ítems lo llevan igual. Un grupo donde una acción es la principal no tiene cómo decirlo desde dentro; aquí la principal va al lado del cluster, como en las referencias |
| **La barra superior no tiene pieza propia** | **tier, planificado**: lo que sostiene una barra de aplicación —disparador del raíl, rastro, buscador, avisos, menú de usuario— no existe como una pieza; `user-menu` (F3.6) y `notifications` (F3.7) están planificados y sin construir, y el shell los compondrá POR la excepción B-10 el día que aterricen. Mientras tanto la barra es el snippet del app, montado con canon. ⚠️ El candidato obvio, `site-header`, es la pieza equivocada aquí y por su propio API: es `Sticky` por defecto (una barra de app bajo `scroll="main"` NO se pega — nada se desplaza por debajo), envuelve en un `Container` MEDIDA (una barra de app va de borde a borde de su inset) y su forma es marca · nav · acciones + drawer móvil, o sea una SEGUNDA navegación dentro de un shell cuya navegación es el raíl. Es el cromo de un SITIO, y esto es una aplicación |
| **No existe `description-list`** | **canon, F5**: el backlog lo condiciona a «el primer detail-view real» — y el panel de detalle de este shell lo es. Mientras no exista, el significado lo llevan `dl`/`dt`/`dd` con la tipografía del tema, y se declara aquí en vez de fingirlo con `div`s |

@ -21,8 +21,28 @@
* contract and not copy (B-7 / D-BLK.5 point at exactly that door).
*
* B-10 exception: shells compose other blocks by design (`SHELL_ALLOWLIST`
* in `blocks-check.ts`). This one composes none yet — the app drops a
* `banner` or a `site-footer` into its slots.
* in `blocks-check.ts`), and this one composes none — which is a decision,
* not a pending task.
*
* The obvious candidate is `site-header`, and it is the wrong piece here on
* three counts, all of them in its own API: it is `Sticky` by default (an
* app bar under `scroll="main"` must NOT pin — nothing scrolls under it), it
* wraps its content in a `Container` MEASURE (an app bar spans its inset
* edge to edge), and its shape is brand · nav · actions + a mobile drawer —
* a second navigation inside a shell whose navigation is the rail. It is the
* chrome of a marketing or docs SITE, and this is an application.
*
* What an app bar actually holds — the rail trigger, the trail, a search
* trigger, notifications, the user menu — has no single piece in the tier
* yet: `user-menu` (F3.6) and `notifications` (F3.7) are planned and unbuilt,
* and the shell will compose them THROUGH this exception the day they land.
* Until then the bar is the app's snippet, assembled from canon
* (`Sidebar.Trigger` + `Breadcrumb` + `Toolbar` + `Button`), which is what
* the demo shows. Registered in the README's Gaps.
*
* The two blocks that DO drop into slots today are `banner` (in flow, above
* everything) and `site-footer`, and both go in as the app's snippets — the
* shell places, it does not import them.
*/
import { Box } from '$uix/eidos/components/box';
import { Grid } from '$uix/eidos/components/grid';

Loading…
Cancel
Save

Powered by TurnKey Linux.