Files
pireon-ui/apps/playground/src/app/pages/layouts/layouts.page.ts
2026-07-30 11:56:57 +02:00

118 lines
3.9 KiB
TypeScript

import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { LayoutHeight, LayoutTypeClass } from '@pi/ui';
import { ShowcaseSection } from '../showcase-section';
interface LayoutDemo {
/** Nombre corto para el título del apartado. */
name: string;
/** Constante de `LayoutTypeClass`, tal cual se aplica en el HostBinding. */
classes: string;
/** Qué hace realmente el CSS de este layout. */
description: string;
/** Bloques de relleno que se pintan dentro de la vista previa. */
blocks: string[];
}
@Component({
selector: 'app-layouts',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './layouts.page.html',
styleUrl: './layouts.page.scss',
imports: [ShowcaseSection],
})
export class LayoutsPage {
/**
* Layouts que se sostienen solos: su CSS actúa sobre el propio contenedor,
* así que la vista previa con bloques sueltos ya enseña lo que hacen.
*/
protected readonly standalone: LayoutDemo[] = [
{
name: 'Vertically centered',
classes: LayoutTypeClass.VerticallyCentered,
description:
'Columna flex centrada verticalmente (justify-content: center). Típico de login, errores o estados vacíos.',
blocks: ['Bloque centrado'],
},
{
name: 'Space between',
classes: LayoutTypeClass.SpaceBetween,
description:
'Columna flex con justify-content: space-between: empuja el primer bloque arriba y el último abajo.',
blocks: ['Cabecera', 'Pie'],
},
{
name: 'Full width auto',
classes: LayoutTypeClass.FullWidthAuto,
description:
'Añade margin: auto sobre el full width, para centrar el bloque cuando no ocupa todo el ancho.',
blocks: ['Contenido centrado'],
},
{
name: 'Pricing',
classes: LayoutTypeClass.Pricing,
description:
'Rejilla de 3 columnas (repeat(3, 1fr)) para tarifas; tiene variante 1fr 3fr con tarjeta destacada.',
blocks: ['Básico', 'Pro', 'Empresas'],
},
];
/**
* Estos no se pueden enseñar con bloques sueltos: su CSS apunta a los
* componentes de wrapper o a estados del shell de la aplicación, así que
* fuera de esa composición no cambian nada visible.
*/
protected readonly compositional = [
{
name: 'Full width',
classes: LayoutTypeClass.FullWidth,
needs:
'Un ancestro con `aside-is-open`: los anchos máximos se calculan a partir del aside y el navbar.',
},
{
name: 'Splitted',
classes: LayoutTypeClass.Splitted,
needs:
'No parte en dos por sí solo: es una columna a 100vh y las mitades las aportan los slots izquierdo/derecho de `pi-main-wrapper`.',
},
{
name: 'Edge to edge',
classes: LayoutTypeClass.EdgeToEdge,
needs:
'Un `pi-wrapper__header` como hijo dentro de `.pi-container-layout`: lo que ajusta es su espaciado superior.',
},
{
name: 'List',
classes: LayoutTypeClass.List,
needs:
'Wrappers (`pi-wrapper`, `pi-wrapper__list`) y un `pi-data-grid`: limita sus anchos y centra la rejilla.',
},
{
name: 'List auto',
classes: LayoutTypeClass.ListAuto,
needs: 'Igual que List, para listados con scroll infinito.',
},
{
name: 'Form',
classes: LayoutTypeClass.Form,
needs:
'Ir anidado dentro de un `pi-layout__05-splitted`: solo ahí recibe padding y scrollbar propios.',
},
];
/** Alturas mínimas, aplicables sobre cualquier layout. */
protected readonly heights = [
{ label: 'small', cls: LayoutHeight.Small, hint: '33.33vh' },
{ label: 'medium', cls: LayoutHeight.Medium, hint: '40vh' },
{ label: 'large', cls: LayoutHeight.Large, hint: '75vh' },
{ label: 'full', cls: LayoutHeight.Full, hint: '100vh' },
];
/**
* Las vistas previas van recortadas: varios layouts piden `vh` y ocuparían
* pantallas enteras. Se puede soltar el recorte para verlos a tamaño real.
*/
protected readonly clipped = signal(true);
}