# @brios-sorzu/angular

Adaptador Angular standalone para Brios Grid.

```ts
import { BriosGridComponent } from '@brios-sorzu/angular';

@Component({
  standalone: true,
  imports: [BriosGridComponent],
  template: `<brios-grid [items]="items" [columns]="columns" />`
})
export class ClientesPage {}
```

Las celdas marcadas con `editable: true` se editan con doble clic. El componente emite `rowClick`, `selectionChange` y `cellEditCommit`.

La validación se ejecuta antes de confirmar una celda o una fila. Además de las reglas
de `required`, longitud, patrón y límites, `GridColumn.validate` puede devolver una
promesa para validación asíncrona o remota:

```ts
const columns: GridColumn<Customer>[] = [
  {
    key: 'email',
    header: 'Correo',
    editable: true,
    validate: async (value) => isEmailAvailable(String(value)) ? null : 'El correo ya está registrado'
  }
];
```

Mientras una validación asíncrona está pendiente se muestra `Validando…`. Si falla,
el mensaje queda asociado a la celda y, durante la edición de fila, también aparece
un resumen en la zona de acciones. Los editores reciben `aria-invalid="true"` cuando
su valor no es válido; `validation` permite integrar mensajes o telemetría propia.

También soporta `[groupBy]`, `childrenField`, `loadChildren`, `briosGridCellTemplate`, `briosGridDetailTemplate`, `[persistKey]`, selección por rangos, virtualización, filtros por valores únicos, resize/reorder, auto-size, el evento `columnResize`, exportación CSV/PDF/SpreadsheetML, pegado TSV, prefetch remoto y actualización masiva de la selección.

El layout de columnas puede configurarse con `showHeaderTitle` y
`showInColumnChooser` dentro de cada `GridColumn`. El primero controla el título
visible del encabezado y el segundo mantiene o excluye la columna del selector;
ambos son `true` por defecto. `[showColumnChooser]="true"` muestra el selector y
`columnLayoutChange` emite el layout cuando cambia el orden, la visibilidad o la
agrupación:

```ts
const columns: GridColumn<Customer>[] = [
  { key: 'id', header: 'ID', showHeaderTitle: false, showInColumnChooser: false },
  { key: 'name', header: 'Nombre' },
  { key: 'email', header: 'Correo', showInColumnChooser: false }
];
```

Las etiquetas `labels.columnChooser` y `labels.autoSizeTooltip` permiten localizar
los nombres accesibles de mostrar/ocultar columnas y auto-size.

Cuando existen varios rangos disjuntos, `copySelection()` copia cada bloque rectangular
en el orden de selección y los separa con una línea en blanco para conservar sus límites
al pegarlo en otra aplicación.

La copia usa `navigator.clipboard` cuando está disponible y cae automáticamente a un
textarea temporal si el navegador rechaza el permiso o la API no existe.

Las columnas aceptan `flex` para repartir el espacio restante del viewport respetando
`minWidth` y `maxWidth`. El template `briosGridGroupTemplate` permite reemplazar la
presentación de grupos y subtotales; su contexto expone `group`, `value`, `count`,
`aggregates` y `toggle`.

El pegado TSV valida la matriz completa antes de aplicarla. Usa `[pasteAtomic]="false"`
para permitir cambios válidos aunque existan celdas rechazadas, y escucha
`(pasteComplete)` para recibir `changes`, `errors` y `cancelled`. `[confirmPaste]`
permite confirmar o cancelar una sobrescritura después de validar y antes de mutar.
El pegado usa las columnas visibles por defecto; `[pasteColumnScope]="'all'"`
incluye también columnas ocultas en el mapeo tabular.
Las columnas pueden usar `editor: { type: 'textarea' }` para edición multilinea; Ctrl/Cmd+Enter confirma y Escape cancela.
`briosGridValidationTemplate` permite personalizar el mensaje de error con el contexto de fila, columna y estado `pending`.
Los atajos principales se pueden cambiar con `[keyboardShortcuts]`; usa `mod` para
Ctrl/Cmd y `false` para deshabilitar un comando, por ejemplo:

```html
<brios-grid
  [keyboardShortcuts]="{ copy: 'mod+shift+c', undo: false, beginEdit: 'f3' }" />
```

Los valores largos muestran un tooltip visual al pasar el mouse o al convertirse en
la celda activa, y exponen el texto completo mediante un nombre accesible. Se puede
desactivar con `[showTruncatedCellTooltip]="false"` o ajustar el umbral con
`[truncatedTooltipMinLength]`.
`[editCommitMode]="'explicit'"`
evita confirmar una celda al perder el foco; Enter o el contexto del editor pueden
confirmarla. `[confirmRemove]` permite confirmar eliminaciones de forma síncrona o
asíncrona.

En TreeGrid, `[treeSelectionPropagation]` puede ser `none`, `descendants`, `ancestors`
o `both` para controlar cómo se propaga la selección entre nodos. Los hijos anidados
entran en `selectedRows`, `selectAll()` y `applySelectionChanges()`, incluso cuando
fueron cargados de forma lazy; las actualizaciones reconstruyen los padres de forma
inmutable.

`[showFilterMenu]` activa el menú de filtros estilo Excel en los headers, con operador,
búsqueda de valores, selección múltiple, limpiar y cierre al hacer click fuera. El
límite `[maxFilterValues]` evita materializar listas enormes. El valor global se puede
sobrescribir por columna con `showFilterMenu` dentro de la definición de `GridColumn`:

```ts
columns = [
  { key: 'id', header: 'ID', showFilterMenu: true },
  { key: 'name', header: 'Nombre', showFilterMenu: false }
];
```

Si una columna no define la propiedad, hereda `[showFilterMenu]` del grid. La fila de
filtros completa sigue controlándose con `[filterable]`.

Con `[showGroupSummaries]` la grilla inserta subtotales por grupo. Los editores pueden
personalizarse con `briosGridEditorTemplate`, cuyo contexto expone `value`, `setValue`,
`commit` y `cancel`.
`[showGroupDropZone]="true"` habilita un panel accesible para agregar grupos con
teclado o arrastrando columnas desde los headers; cada grupo puede retirarse desde
su chip y el orden se conserva en el estado persistido.

El estado persistido puede versionarse con `[persistVersion]`. Cuando cambia el esquema,
`[persistMigrate]` recibe el snapshot anterior y puede devolver el snapshot adaptado.

La exportación integrada respeta las columnas visibles y `[exportSelectionOnly]` y
descarga XLSX Open XML real. `downloadCsv()` usa bloques cooperativos; también se puede
usar `downloadCsvAsync()` para esperar la promesa y observar el mismo estado de progreso,
cancelación y error que XLSX. PDF emite el estado `running`/`completed`/`error` durante
su generación síncrona. Para conservar la estructura visible de grupos y detalles
se pueden activar `[exportGroups]`, `[exportGroupSummaries]` y `[exportDetails]`; el XLSX
usa bloques cooperativos configurables con `[exportChunkSize]`, progreso y cancelación.
La API de exportación completa (`toCsv`, `toXlsx`, `toPdf`, hooks y múltiples hojas)
se puede importar desde `@brios-sorzu/components`.

Para fuentes remotas se pueden configurar reintentos cancelables con
`[remoteRetries]`, `[remoteRetryDelayMs]`, `[remoteRetryBackoff]` y
`[remoteShouldRetry]`. La grilla cancela cargas pendientes cuando cambia el datasource
o se destruye el componente.
El datasource también puede definir `resolveConflict` para devolver la fila reconciliada
cuando una actualización remota es rechazada; si devuelve `null` se conserva el rollback
actual. Cuando la resolución no devuelve una fila, la grilla expone el evento
`remoteConflict` y mantiene `remoteConflictState` para que la aplicación pueda mostrar
una política propia; el banner incorporado permite reabrir la edición o descartar el
conflicto. La interfaz `BriosGridRemoteConflict` incluye la clave, fila, índice, cambios
y error original. Para conflictos bulk se emite `remoteConflictBulk`, que incluye todas
las filas rechazadas y expone acciones integradas de reintento o descarte.

En `applySelectionChanges`, si el datasource usa `updateMany` y rechaza el batch,
`GridController` intenta `resolveConflict` por cada fila. El commit bulk continúa solo
si todas las filas se reconcilian; una resolución parcial aplica las filas resueltas,
revierte solo las rechazadas y publica `remoteConflictBulk` con las filas pendientes.

Los adaptadores cursor pueden avanzar con `loadNextCursor()` y consultar el valor
actual mediante `nextCursor`; también es posible iniciar un cursor con `setCursor()`.

Los textos de operadores se pueden traducir con `labels.operatorLabels`, por ejemplo
`{ between: 'entre', isEmpty: 'sin valor' }`.
También puedes traducir `filterValuesSearch`, `selectFilterValues` y
`clearFilterValues` dentro de `labels`.
Si no pasas `labels`, `[locale]="'es-MX'"` usa defaults en español y
`[locale]="'en-US'"` defaults en inglés. `labels` es parcial: solo reemplaza las
claves que necesites y conserva las demás del locale activo.

Para sincronizar filtros, búsqueda, sort, grupos y paginación con el router o un
storage propio, usa los métodos públicos:

```ts
const state = grid.serializeQueryState();
grid.restoreQueryState(state);
```

El valor es URL-safe y `restoreQueryState` devuelve `false` si recibe datos inválidos.

Las columnas admiten `locale`, `currency`, `numberFormat` y `dateFormat` cuando no se
define un `formatter`, y la grilla expone `[locale]` como valor predeterminado para
presentar números, moneda y fechas según la región.
Para edición localizada se puede usar `dataType: 'currency'` o `editor: { type: 'currency' }`;
el campo acepta separadores regionales y el valor confirmado siempre es numérico.
`applySelectionChanges()` agrupa los cambios locales en una transacción y hace
rollback si la persistencia remota falla.

Las eliminaciones remotas son optimistas por defecto; `[optimisticMutations]="false"`
permite esperar la confirmación del servidor antes de retirar la fila.

Los estados también son personalizables:

```html
<ng-template briosGridStateTemplate="empty">No hay clientes.</ng-template>
<ng-template briosGridStateTemplate="error" let-error="error" let-retry="retry">
  Error: {{ error }} <button type="button" (click)="retry()">Reintentar</button>
</ng-template>
```

El contexto de `error` expone `error` y `retry`, de modo que un estado personalizado
conserva la recuperación remota.
