This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.1.0.
npm install @cbm-common/tree-selectbash
ng generate component component-name
`
For a complete list of available schematics (such as components, directives, or pipes), run:
@cbm-common/tree-select
Documentación en español para la librería @cbm-common/tree-select.
Resumen
-------
tree-select es un componente standalone de Angular que implementa un selector en forma de árbol (tree select) con soporte para búsqueda (typeahead), selección múltiple, devolución del nodo completo o solo el valor, y comportamiento configurable (cerrar al seleccionar, seleccionar nodo "All", etc.). Está pensado para integrarse en formularios reactivos y para ser usado tanto en formularios controlados (ControlValueAccessor) como en uso independiente.
Características principales
- Standalone component (Angular 20+) con ControlValueAccessor.
- Soporta selección simple y múltiple.
- Soporta devolver el nodo completo o solo el valor (returnNode).
- Búsqueda interna o typeahead externo mediante Subject.
- Permite marcar como cargando (loading) y mostrar estado de invalidez (invalid).
- Utiliza ShadowDom (encapsulación) para aislar estilos.
Tipos
-----
El componente usa el namespace CbmTreeSelect con el tipo principal:
- CbmTreeSelect.Node: { label: string; value: T; children?: Node[] }
- CbmTreeSelect.Children: Node[]
Instalación
-----------
Si el paquete está publicado en tu registro npm:
`bash
npm install @cbm-common/tree-select
`
Uso - Inputs principales
-----------------------
El componente expone los siguientes inputs (con su comportamiento):
- [options] (CbmTreeSelect.Children | CbmTreeSelect.Node) — Lista de nodos o un nodo raíz.
- [formControl] (FormControl) — Opcional. Si se proporciona, el componente puede reflejar estado de validación y usarse dentro de formularios reactivos.
- [placeholder] (string) — Texto placeholder del input.
- [loading] (boolean) — Muestra un estado de carga si es true.
- [invalid] (boolean) — Indica visualmente un estado inválido.
- [isSmall] (boolean) — Versión compacta del control.
- [typeahead] (Subject) — Si se proporciona, el componente emitirá los valores de búsqueda a este Subject en vez de filtrar localmente.
- [returnNode] (boolean) — Si true, las selecciones devuelven el nodo completo; si false, devuelve node.value.
- [selectedAllNode] (boolean) — Soporte para nodo "Seleccionar todo" (implementación interna depende de opciones).
- [multiple] (boolean) — Permite selección múltiple.
- [closeOnSelected] (boolean) — Si true, el dropdown se cierra al seleccionar.
- [bindLabel] (string, default 'name') — Nombre de la propiedad a usar como label cuando el valor no es un Node.
- [bindId] (string, default '_id') — Nombre de la propiedad que identifica un objeto cuando se utiliza compareWith por defecto.
API - Eventos / Salidas
----------------------
El componente implementa ControlValueAccessor y expone los métodos estándar:
- writeValue(value) — Se llama para inicializar el valor del control.
- registerOnChange(fn) — Callback para cambios.
- registerOnTouched(fn) — Callback para touched.
- setDisabledState(isDisabled) — Control de estado disabled.
Comportamiento interno importante
-------------------------------
- Comparador por defecto (compareWith) admite tanto comparación simple como comparación cuando multiple = true (compara ids usando bindId).
- Si no se pasa un typeahead externo, el componente filtra localmente usando searchValue (propiedad interna ligada al input de búsqueda).
- El componente controla la apertura/cierre con isExpanded y cierra cuando se hace click fuera del elemento (manejador global document:click).
- Soporta enfoque automático del input cuando se abre (openAndFocus).
- Maneja selección y eliminación en modo múltiple (funciones setValue, removeSelected).
Ejemplos de uso
---------------
Ejemplo simple (selección única devolviendo valor):
`html
[options]="categories"
[returnNode]="false"
placeholder="Seleccione una categoría"
>
`
Ejemplo con FormControl y selección múltiple (devuelve nodos):
`html
[options]="categories"
[formControl]="categoryControl"
[multiple]="true"
[returnNode]="true"
[selectedAllNode]="true"
[typeahead]="searchSubject"
placeholder="Buscar y seleccionar"
>
`
En el componente TypeScript:
`ts
import { FormControl } from '@angular/forms';
import { Subject } from 'rxjs';
export class MiComponente {
categoryControl = new FormControl(null);
searchSubject = new Subject();
categories = [
{ label: 'A', value: { id: 1 }, children: [{ label: 'A1', value: { id: 11 } }] },
{ label: 'B', value: { id: 2 } }
];
}
`
Notas sobre estilos y ShadowDom
-------------------------------
- El componente usa ViewEncapsulation.ShadowDom. Esto aísla los estilos del componente del resto de la app. Si necesitas customizar su apariencia desde fuera, puedes:
- Usar propiedades CSS personalizadas definidas en el componente (:host { --mi-color: ... }) si están expuestas.
- Evitar ShadowDom si prefieres que los estilos globales afecten el componente (recompilar con ViewEncapsulation.None).
Compatibilidad y recomendaciones
--------------------------------
- Recomendado para Angular 20.x.
- Si usas multiple, la value emitida por ControlValueAccessor será un array de valores o nodos según returnNode.
- Proveer un typeahead (Subject) es útil para delegar búsquedas al servidor y evitar filtrar localmente.
Pruebas
------
Ejecuta las pruebas unitarias con:
`bash
ng test
`
Build y publicación
-------------------
Para construir la librería dentro del monorepo:
`bash
ng build tree-select
`
El paquete compilado quedará en dist/tree-select. Para publicar:
`bash
cd dist/tree-select
npm publish
`
Contribuciones
--------------
Si quieres contribuir, abre un PR con pruebas y una descripción clara del cambio. Para cambios de estilo, incluye capturas o un pequeño demo.
Contacto
-------
Revisa el código fuente en projects/tree-select/src/lib` para más detalles, o abre un issue en el repositorio principal del monorepo.