Datos y multimedia
Gallery
Muestra una colección de miniaturas de imágenes.
Importación
import { NeuGalleryComponent } from '@neural-ui/native/gallery';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.
Estudios de paisaje
Explora una colección de ilustraciones. Cambia la composición o abre una miniatura para ver la imagen original.
Ver y copiar el ejemplo completo
import { Component, signal } from '@angular/core';
import { NeuButtonComponent } from '@neural-ui/native/button';
import { NeuGalleryComponent } from '@neural-ui/native/gallery';
import { View, Text, ScrollView } from '@ng-native/components';
import type { NeuGalleryLayout } from '@neural-ui/native/gallery';
import type { NeuImageItem } from '@neural-ui/native';
@Component({
selector: 'app-example',
imports: [NeuButtonComponent, NeuGalleryComponent, View, Text, ScrollView],
template: `
<scroll-view class="product-scroll" keyboardShouldPersistTaps="handled" [showsVerticalScrollIndicator]="false"><view class="product-stack"><view class="product-section"><text class="product-title" accessibilityRole="header">Estudios de paisaje</text><text class="product-caption">Cuatro ilustraciones originales · Colección Neural</text></view>
<view class="product-actions">
<neu-button label="Cuadrícula" size="sm" [variant]="layout() === 'grid' ? 'solid' : 'outline'" (pressed)="layout.set('grid')" />
<neu-button label="Mosaico" size="sm" [variant]="layout() === 'mosaic' ? 'solid' : 'outline'" (pressed)="layout.set('mosaic')" />
</view>
<neu-gallery [viewerLabels]="{ closeLabel: 'Cerrar visor', previousLabel: 'Imagen anterior', nextLabel: 'Imagen siguiente', zoomLabel: 'Ampliar imagen', zoomOutLabel: 'Reducir imagen', errorLabel: 'No se ha podido cargar la imagen' }" emptyLabel="No hay imágenes" label="Colección visual Neural" [items]="images" [layout]="layout()" [columns]="2" [gap]="12" [aspectRatio]="1" [showCaptions]="true" [(index)]="index" [(open)]="open" /></view></scroll-view>
`,
styles: `
.actions { gap: 12px; align-items: flex-start; } text { color: var(--neu-text, #172033); font-size: 16px; }
:host { flex: 1; flex-shrink: 1; min-height: 0; }
.product-scroll { flex: 1; flex-shrink: 1; height: 0px; min-height: 0; }
.product-stack { gap: 24px; padding-bottom: 20px; }
.product-section { gap: 12px; }
.product-row { flex-direction: row; align-items: center; gap: 12px; }
.product-copy { flex: 1; min-width: 0; gap: 4px; }
.product-title { color: var(--neu-text, #172033); font-size: 24px; line-height: 30px; font-weight: 600; }
.product-heading { color: var(--neu-text, #172033); font-size: 17px; line-height: 23px; font-weight: 600; }
.product-caption { color: var(--neu-muted, #596477); font-size: 14px; line-height: 20px; }
.product-actions { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px; }
.product-surface { gap: 16px; padding: 16px; border-radius: 16px; background-color: var(--neu-surface, #ffffff); border-width: 1px; border-color: var(--neu-border, #a5afbf); }
`,
})
export class ExampleComponent {
readonly images: readonly NeuImageItem[] = [
{
"id": "forest",
"label": "Paseo por el bosque",
"uri": "/assets/media/v2/forest.png"
},
{
"id": "desert",
"label": "Formas del desierto",
"uri": "/assets/media/v2/desert.png"
},
{
"id": "night",
"label": "Cielo nocturno",
"uri": "/assets/media/v2/night.png"
},
{
"id": "coast",
"label": "Horizonte tranquilo",
"uri": "/assets/media/v2/coast.png"
}
];
readonly index = signal(0);
readonly open = signal(false);
readonly layout = signal<NeuGalleryLayout>('mosaic');
}Miniaturas y leyendas propias
Personaliza la miniatura y su leyenda. Gallery sigue abriendo la imagen original y conserva la geometría de cuadrícula o mosaico.
Ver y copiar el ejemplo completo
import { Component, signal } from '@angular/core';
import { NeuGalleryComponent } from '@neural-ui/native/gallery';
import { View, Text, Image, ScrollView } from '@ng-native/components';
import { NeuGalleryItemDirective, NeuGalleryCaptionDirective } from '@neural-ui/native/gallery';
import type { NeuImageItem } from '@neural-ui/native';
@Component({
selector: 'app-example',
imports: [NeuGalleryComponent, NeuGalleryItemDirective, NeuGalleryCaptionDirective, View, Text, Image, ScrollView],
template: `
<scroll-view class="usage-scroll" keyboardShouldPersistTaps="handled"><view class="usage-stack">
<neu-gallery [viewerLabels]="{ closeLabel: 'Cerrar visor', previousLabel: 'Imagen anterior', nextLabel: 'Imagen siguiente', zoomLabel: 'Ampliar imagen', zoomOutLabel: 'Reducir imagen', errorLabel: 'No se ha podido cargar la imagen' }" emptyLabel="No hay imágenes" label="Colección de paisajes" [items]="images" [columns]="2" [showCaptions]="true" [(open)]="open" [(index)]="index">
<ng-template neuGalleryItem let-photo let-ratio="aspectRatio" let-radius="borderRadius">
<view class="photo-tile"><image class="custom-photo" [source]="{ uri: photo.uri }" [alt]="photo.label" resizeMode="cover" [style.aspectRatio]="ratio" [style.borderRadius]="radius" /><view class="photo-tag"><text class="photo-tag-label">Colección</text></view></view>
</ng-template>
<ng-template neuGalleryCaption let-photo let-index="index"><text class="usage-caption" [numberOfLines]="2">{{ index + 1 }} · {{ photo.label }}</text></ng-template>
</neu-gallery>
</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; }
.photo-tile { position: relative; } .custom-photo { width: 100%; } .photo-tag { position: absolute; left: 8px; bottom: 8px; padding: 5px 8px; border-radius: 6px; background-color: #172033; } .photo-tag-label { color: #ffffff; font-size: 12px; }
`,
})
export class ExampleComponent {
readonly images: readonly NeuImageItem[] = [
{
"id": "forest",
"label": "Paseo por el bosque",
"uri": "/assets/media/v2/forest.png"
},
{
"id": "desert",
"label": "Formas del desierto",
"uri": "/assets/media/v2/desert.png"
},
{
"id": "night",
"label": "Cielo nocturno",
"uri": "/assets/media/v2/night.png"
},
{
"id": "coast",
"label": "Horizonte tranquilo",
"uri": "/assets/media/v2/coast.png"
}
];
readonly index = signal(0);
readonly open = signal(false);
}Ajusta la configuración y prueba el resultado.
Capturas del dispositivo en inglés.


Personalización
Importa estas directivas junto con el componente y añádelas a Component.imports. Los ejemplos anteriores incluyen la configuración completa.
import { NeuGalleryItemDirective, NeuGalleryCaptionDirective } from '@neural-ui/native/gallery';| Plantilla o región | Contexto | Uso |
|---|---|---|
ng-template[neuGalleryItem] | $implicit: NeuImageItem; index: number; aspectRatio: number; borderRadius: number | Sustituye la miniatura. Aplica aspectRatio y borderRadius a tu imagen para conservar el diseño. La acción de galería sigue abriendo el elemento original. |
ng-template[neuGalleryCaption] | $implicit: NeuImageItem; index: number; aspectRatio: number; borderRadius: number | Sustituye la leyenda cuando showCaptions es true. index es la posición original en items, también en los mosaicos. |
Contextos de las plantillas
import type { NeuGalleryItemContext } from '@neural-ui/native/gallery';let-item recibe $implicit; los campos con nombre utilizan let-index="index". Usa los tipos exportados al declarar un TemplateRef reutilizable. Mantén el contenido interno como presentación: el padre conserva la acción accesible y el comportamiento de selección.
Referencia API
Inputs
| Nombre | Tipo | Predeterminado | Enlace | Descripción |
|---|---|---|---|---|
| label | string | 'Gallery' | Input | Nombre legible del control, acción o grupo. |
| viewerLabels | NeuGalleryViewerLabels | {} | Input | Textos opcionales del visor interno: label, closeLabel, previousLabel, nextLabel, zoomLabel, zoomOutLabel y errorLabel. Las entradas omitidas conservan sus valores predeterminados en inglés; label utiliza la etiqueta de la galería. Los textos se actualizan sin recrear la galería. |
| items | readonly NeuImageItem[] | [] | Input | Datos ordenados del componente. Utiliza el contrato siguiente e identificadores estables y únicos. |
| emptyLabel | string | 'No images' | Input | Texto o nombre accesible utilizado para estado vacío. No ejecuta la acción por sí solo. |
| layout | NeuGalleryLayout | 'grid' | Input | El diseño grid alinea miniaturas iguales en filas; mosaic usa columnas con alturas de imagen alternadas. Ambos conservan el índice original en el visor. Mosaic no admite fusionar celdas arbitrariamente. |
| columns | number | 2 | Input | Columnas solicitadas, limitadas a enteros entre 1 y 4. El layout nativo las reduce cuando el contenedor no admite miniaturas de 48 puntos de ancho más sus separaciones. |
| gap | number | 10 | Input | Espacio entre celdas o columnas/elementos del mosaico, de 0 a 48 puntos. Cero crea una composición continua. |
| aspectRatio | number | 1 | Input | Proporción base ancho/alto, de 0,25 a 4. 1 crea imágenes cuadradas en grid; 1,5 crea imágenes apaisadas. Mosaic aplica sus factores de altura alternada sobre esta base. Las imágenes se recortan con cover sin deformarlas. |
| borderRadius | number | 12 | Input | Radio de las esquinas de cada miniatura en puntos. Cero crea esquinas rectas para un mosaico continuo. No afecta al visor completo. |
| showCaptions | boolean | true | Input | Muestra la etiqueta debajo de cada miniatura. Ocultarla conserva el nombre accesible y el título del visor. |
Models
| Nombre | Tipo | Predeterminado | Enlace | Descripción |
|---|---|---|---|---|
| index | number | 0 | Model · bidireccional | Posición actual de imagen o carrusel, empezando por cero. Enlaza una signal escribible mediante [(index)]. |
| open | boolean | false | Model · bidireccional | Indica si se solicita mantener abierta la presentación o mensaje. Enlaza una signal escribible mediante [(open)]. |
Outputs
| Nombre | Payload | Cuándo se emite |
|---|---|---|
| indexChange | number | Emite el valor actualizado de index. [(index)] enlaza este output junto con su input model. |
| openChange | boolean | Emite el valor actualizado de open. [(open)] enlaza este output junto con su input model. |
Estado de los models
Enlaza la signal con [(nombreModel)] sin llamarla. Utiliza nombreModel() para leer su valor.
import { signal } from '@angular/core';
// Fields inside your component class
readonly index = signal<number>(0);
readonly open = signal<boolean>(false);Tipos e interfaces de datos
Utiliza los imports en tu aplicación. Las definiciones siguientes se muestran como referencia.
NeuGalleryViewerLabels
import type { NeuGalleryViewerLabels } from '@neural-ui/native/gallery';
// Public definition for reference only. Import this type; do not redeclare it.
export interface NeuGalleryViewerLabels {
readonly label?: string;
readonly closeLabel?: string;
readonly previousLabel?: string;
readonly nextLabel?: string;
readonly zoomLabel?: string;
readonly zoomOutLabel?: string;
readonly errorLabel?: string;
}| Campo | Tipo | Requisito | Significado |
|---|---|---|---|
| label | string | Opcional | Nombre accesible del visor completo; utiliza la etiqueta de la galería si se omite. |
| closeLabel | string | Opcional | Nombre accesible de la acción de cerrar el visor. |
| previousLabel | string | Opcional | Nombre accesible de la acción de imagen anterior. |
| nextLabel | string | Opcional | Nombre accesible de la acción de imagen siguiente. |
| zoomLabel | string | Opcional | Nombre accesible de la acción de ampliar la imagen. |
| zoomOutLabel | string | Opcional | Nombre accesible de la acción de reducir la imagen. |
| errorLabel | string | Opcional | Mensaje anunciado cuando no se puede cargar la imagen. |
NeuImageItem
import type { NeuImageItem } from '@neural-ui/native';
// Public definition for reference only. Import this type; do not redeclare it.
export interface NeuImageItem {
readonly id: string;
readonly uri: string;
readonly label: string;
}| Campo | Tipo | Requisito | Significado |
|---|---|---|---|
| id | string | Obligatorio | Identificador estable y único para seguimiento y selección. |
| uri | string | Obligatorio | URI nativa de imagen o archivo. |
| label | string | Obligatorio | Nombre legible del elemento. |
NeuGalleryLayout
import type { NeuGalleryLayout } from '@neural-ui/native/gallery';
// Public definition for reference only. Import this type; do not redeclare it.
export type NeuGalleryLayout = 'grid' | 'mosaic';