UNPKG

kea-react

Version:

Componentes comunes de react

82 lines (67 loc) 2.54 kB
import { Tree, TreePath } from "./types"; import { TreeState, TreePathArray, CollapsedType } from "./treeState"; export interface TreeRow<T> { /**Ruta completa de este row */ path: TreePath; /**Si el row esta collapsado o no, o si no se puede colapsar */ collapsed: CollapsedType; /**Valor del row */ value: T } /**Obtiene todas las filas que se van a mostrar en un tree */ export function getTreeRows<T>( basePath: TreePath, tree: Tree<T>[], collapsedPaths: TreePathArray, ): TreeRow<T>[] { const ret: TreeRow<T>[] = []; for (const node of tree) { //Ruta del elemento const path = [...basePath, node.key]; const isLeaf = !node.children || node.children.length == 0; const collapsed: CollapsedType = isLeaf ? "leaf" : (isCollapsed(path, collapsedPaths) ? "collapsed" : "expanded"); const value = node.value; //Agregamos al elemento ret.push({ collapsed, path, value }); //Agregamos a todos los hijos: if (collapsed == "expanded") { ret.push(...getTreeRows(path, node.children || [], collapsedPaths)); } } return ret; } /**Devuelve el nuevo valor para el arreglo de elementos colapsados dada la ruta y el valor de colapsado de un evento de colapsar o expandir */ export function handleOnCollapsedChange(path: TreePath, value: boolean, oldValue: TreePathArray): TreePathArray { let newValue: TreePathArray; if (!value) { //Quitar el elemento: newValue = oldValue.filter(x => !sequenceEquals(x, path)); } else { //Agregar el elemento. newValue = [...oldValue, path]; } return newValue; } /**Devuelve true si una ruta del arbol esta colapsada */ export function isCollapsed(path: TreePath, collapsedArray: TreePathArray) { return any(collapsedArray, x => sequenceEquals(x, path)); } /**Devuelve true si 2 secuencias contienen a los mismos elementos */ export function sequenceEquals<T>(a: T[], b: T[]) { //Reference equals if (a === b) return true; if (a.length != b.length) return false; for (let i = 0; i < a.length; i++) { if (a[i] != b[i]) return false; } return true; } /**Devuelve true si algun elemento encaja con el predicado */ export function any<T>(array: T[], pred: (value: T) => boolean) { for (const a of array) { if (pred(a)) return true; } return false; }