( keyMap: Map<Key, GridNode<T>>, columnNodes: GridNode<T>[] )
| 44 | |
| 45 | /** @private */ |
| 46 | export function buildHeaderRows<T>( |
| 47 | keyMap: Map<Key, GridNode<T>>, |
| 48 | columnNodes: GridNode<T>[] |
| 49 | ): GridNode<T>[] { |
| 50 | if (columnNodes.length === 0) { |
| 51 | return []; |
| 52 | } |
| 53 | |
| 54 | let columns: GridNode<T>[][] = []; |
| 55 | let seen = new Map(); |
| 56 | for (let column of columnNodes) { |
| 57 | let parentKey = column.parentKey; |
| 58 | let col = [column]; |
| 59 | |
| 60 | while (parentKey != null) { |
| 61 | let parent: GridNode<T> | undefined = keyMap.get(parentKey); |
| 62 | if (!parent) { |
| 63 | break; |
| 64 | } |
| 65 | |
| 66 | // If we've already seen this parent, than it is shared |
| 67 | // with a previous column. If the current column is taller |
| 68 | // than the previous column, than we need to shift the parent |
| 69 | // in the previous column so it's level with the current column. |
| 70 | if (seen.has(parent)) { |
| 71 | parent.colSpan ??= 0; |
| 72 | parent.colSpan++; |
| 73 | parent.colspan = parent.colSpan; |
| 74 | |
| 75 | let {column, index} = seen.get(parent); |
| 76 | if (index > col.length) { |
| 77 | break; |
| 78 | } |
| 79 | |
| 80 | for (let i = index; i < col.length; i++) { |
| 81 | column.splice(i, 0, null); |
| 82 | } |
| 83 | |
| 84 | // Adjust shifted indices |
| 85 | for (let i = col.length; i < column.length; i++) { |
| 86 | // eslint-disable-next-line max-depth |
| 87 | if (column[i] && seen.has(column[i])) { |
| 88 | seen.get(column[i]).index = i; |
| 89 | } |
| 90 | } |
| 91 | } else { |
| 92 | parent.colSpan = 1; |
| 93 | parent.colspan = 1; |
| 94 | col.push(parent); |
| 95 | seen.set(parent, {column: col, index: col.length - 1}); |
| 96 | } |
| 97 | |
| 98 | parentKey = parent.parentKey; |
| 99 | } |
| 100 | |
| 101 | columns.push(col); |
| 102 | column.index = columns.length - 1; |
| 103 | } |
no test coverage detected