Estados y avisos
Skeleton
Mantén visible la estructura del contenido mientras se carga.
Importación
import { NeuSkeletonComponent } from '@neural-ui/native/skeleton';Ejemplos
Importa ExampleComponent en su padre y coloca <app-example /> dentro del neu-theme raíz de tu aplicación. El preview aporta el marco y las zonas seguras; utiliza la estructura raíz de Instalación en tu app.
Carga y contenido
Alterna entre los marcadores de carga y la tarjeta con contenido.
Ver y copiar el ejemplo completo
import { Component, signal } from '@angular/core';
import { NeuButtonComponent } from '@neural-ui/native/button';
import { NeuCardComponent } from '@neural-ui/native/card';
import { NeuSkeletonComponent } from '@neural-ui/native/skeleton';
import { View, Text, ScrollView } from '@ng-native/components';
@Component({
selector: 'app-example',
imports: [NeuButtonComponent, NeuCardComponent, NeuSkeletonComponent, View, Text, ScrollView],
template: `
<scroll-view class="usage-scroll" keyboardShouldPersistTaps="handled"><view class="usage-stack">
<view class="usage-section">
<neu-button [label]="loading() ? 'Mostrar contenido' : 'Mostrar marcadores de carga'" variant="outline" size="sm" (pressed)="loading.set(!loading())" />
@if (loading()) {
<view class="loading-card">
<view class="loading-header">
<neu-skeleton label="Cargando la foto del perfil" variant="circle" [width]="40" [height]="40" />
<view class="loading-name">
<neu-skeleton label="Cargando la autoría" [lines]="2" [height]="12" [gap]="8" lastLineWidth="55%" />
</view>
</view>
<neu-skeleton label="Cargando la imagen del proyecto" variant="rect" [height]="112" [borderRadius]="10" />
<neu-skeleton label="Cargando la descripción del proyecto" [lines]="3" [height]="12" [gap]="8" lastLineWidth="70%" />
</view>
} @else {
<neu-card title="Revisión de diseño" description="Alex Morgan · Equipo de producto" variant="outlined"><text>La bienvenida está lista para tus comentarios.</text></neu-card>
}
</view>
</view></scroll-view>
`,
styles: `
.actions { gap: 12px; align-items: flex-start; } text { color: var(--neu-text, #172033); font-size: 16px; }
.usage-scroll { flex: 1; }
.usage-stack { gap: 20px; padding-bottom: 20px; }
.usage-section { gap: 12px; }
.usage-heading { color: var(--neu-text, #172033); font-size: 16px; font-weight: 600; }
.usage-caption { color: var(--neu-muted, #64748b); font-size: 14px; }
.usage-row { flex-direction: row; flex-wrap: wrap; gap: 12px; align-items: center; }
.usage-actions { flex-direction: row; flex-wrap: wrap; gap: 8px; align-items: center; }
:host { width: 100%; } .loading-card { gap: 16px; } .loading-header { flex-direction: row; align-items: center; gap: 12px; } .loading-name { flex: 1; min-width: 0; }
`,
})
export class ExampleComponent {
readonly loading = signal(true);
}Sin animación
Utiliza marcadores estáticos cuando no necesites movimiento.
Ver y copiar el ejemplo completo
import { Component, signal } from '@angular/core';
import { NeuSkeletonComponent } from '@neural-ui/native/skeleton';
import { View, ScrollView } from '@ng-native/components';
@Component({
selector: 'app-example',
imports: [NeuSkeletonComponent, View, ScrollView],
template: `
<scroll-view class="usage-scroll" keyboardShouldPersistTaps="handled"><view class="usage-stack">
<view class="usage-section">
<neu-skeleton label="Descripción de carga estática" animation="none" [lines]="2" [height]="12" lastLineWidth="55%" />
</view>
</view></scroll-view>
`,
styles: `
.actions { gap: 12px; align-items: flex-start; } text { color: var(--neu-text, #172033); font-size: 16px; }
.usage-scroll { flex: 1; }
.usage-stack { gap: 20px; padding-bottom: 20px; }
.usage-section { gap: 12px; }
.usage-heading { color: var(--neu-text, #172033); font-size: 16px; font-weight: 600; }
.usage-caption { color: var(--neu-muted, #64748b); font-size: 14px; }
.usage-row { flex-direction: row; flex-wrap: wrap; gap: 12px; align-items: center; }
.usage-actions { flex-direction: row; flex-wrap: wrap; gap: 8px; align-items: center; }
:host { width: 100%; } .loading-card { gap: 16px; } .loading-header { flex-direction: row; align-items: center; gap: 12px; } .loading-name { flex: 1; min-width: 0; }
`,
})
export class ExampleComponent {
readonly loading = signal(true);
}Playground interactivo
Ajusta la configuración y prueba el resultado.
Capturas del dispositivo en inglés.


Referencia API
Inputs
| Nombre | Tipo | Predeterminado | Enlace | Descripción |
|---|---|---|---|---|
| label | string | 'Loading' | Input | Nombre legible del control, acción o grupo. |
| lines | number | 3 | Input | Número de líneas de texto, limitado a 1–20. Las variantes rect y circle siempre dibujan una figura. Los valores no finitos usan tres líneas. |
| variant | NeuSkeletonVariant | 'text' | Input | La variante text dibuja varias líneas; rect y circle dibujan una figura. Elige la forma del contenido que la sustituirá. |
| width | string | number | undefined | undefined | Input | Ancho en puntos de layout (número o string numérico), px o porcentaje del padre. Sin definir usa 100% para text/rect y la altura resuelta para circle. Usa el mismo ancho y alto para un círculo; su radio siempre es completamente redondeado. Los valores inválidos recuperan el ancho automático y el contenedor no supera al padre. |
| height | number | undefined | undefined | Input | Alto de cada línea o figura en puntos de layout. Sin definir usa 16 en text/rect y 40 en circle. Los valores negativos se normalizan a cero. |
| borderRadius | number | 8 | Input | Radio de las esquinas en puntos de layout para text y rect. Cero crea esquinas rectas. La variante circle conserva el redondeado completo. |
| gap | number | 12 | Input | Separación vertical entre líneas en puntos de layout. Cero las une; no tiene efecto visible en una figura única. |
| lastLineWidth | string | number | '65%' | Input | Ancho de la última línea de texto en puntos de layout, px o porcentaje del ancho del skeleton. Usa 100% para igualar todas las líneas. No afecta a rect ni circle. |
| animation | NeuSkeletonAnimation | 'pulse' | Input | La animación pulse cambia suavemente la opacidad; none mantiene el placeholder estático. El movimiento reducido del sistema y un tema con duración cero desactivan la animación aunque se seleccione pulse. |
Models
Este componente no declara models bidireccionales.
Outputs
Este componente no declara outputs públicos.
Tipos e interfaces de datos
Utiliza los imports en tu aplicación. Las definiciones siguientes se muestran como referencia.
NeuSkeletonVariant
import type { NeuSkeletonVariant } from '@neural-ui/native/skeleton';
// Public definition for reference only. Import this type; do not redeclare it.
export type NeuSkeletonVariant = 'text' | 'rect' | 'circle';NeuSkeletonAnimation
import type { NeuSkeletonAnimation } from '@neural-ui/native/skeleton';
// Public definition for reference only. Import this type; do not redeclare it.
export type NeuSkeletonAnimation = 'pulse' | 'none';