kea-react
Version:
Componentes comunes de react
82 lines (67 loc) • 2.54 kB
text/typescript
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;
}