* Applies sticky left and right positions to the cells of each row according to the sticky * states of the rendered column definitions. * @param rows The rows that should have its set of cells stuck according to the sticky states. * @param stickyStartStates A list of boolean states where ea
(
rows: HTMLElement[],
stickyStartStates: boolean[],
stickyEndStates: boolean[],
recalculateCellWidths = true,
replay = true,
)
| 125 | * @param replay Whether to enqueue this call for replay after a ResizeObserver update. |
| 126 | */ |
| 127 | updateStickyColumns( |
| 128 | rows: HTMLElement[], |
| 129 | stickyStartStates: boolean[], |
| 130 | stickyEndStates: boolean[], |
| 131 | recalculateCellWidths = true, |
| 132 | replay = true, |
| 133 | ) { |
| 134 | // Don't cache any state if none of the columns are sticky. |
| 135 | if ( |
| 136 | !rows.length || |
| 137 | !this._isBrowser || |
| 138 | !(stickyStartStates.some(state => state) || stickyEndStates.some(state => state)) |
| 139 | ) { |
| 140 | this._positionListener?.stickyColumnsUpdated({sizes: []}); |
| 141 | this._positionListener?.stickyEndColumnsUpdated({sizes: []}); |
| 142 | return; |
| 143 | } |
| 144 | |
| 145 | // Coalesce with sticky row updates (and potentially other changes like column resize). |
| 146 | const firstRow = rows[0]; |
| 147 | const numCells = firstRow.children.length; |
| 148 | |
| 149 | const isRtl = this.direction === 'rtl'; |
| 150 | const start = isRtl ? 'right' : 'left'; |
| 151 | const end = isRtl ? 'left' : 'right'; |
| 152 | |
| 153 | const lastStickyStart = stickyStartStates.lastIndexOf(true); |
| 154 | const firstStickyEnd = stickyEndStates.indexOf(true); |
| 155 | |
| 156 | let cellWidths: number[]; |
| 157 | let startPositions: number[]; |
| 158 | let endPositions: number[]; |
| 159 | |
| 160 | if (replay) { |
| 161 | this._updateStickyColumnReplayQueue({ |
| 162 | rows: [...rows], |
| 163 | stickyStartStates: [...stickyStartStates], |
| 164 | stickyEndStates: [...stickyEndStates], |
| 165 | }); |
| 166 | } |
| 167 | |
| 168 | afterNextRender( |
| 169 | { |
| 170 | earlyRead: () => { |
| 171 | cellWidths = this._getCellWidths(firstRow, recalculateCellWidths); |
| 172 | |
| 173 | startPositions = this._getStickyStartColumnPositions(cellWidths, stickyStartStates); |
| 174 | endPositions = this._getStickyEndColumnPositions(cellWidths, stickyEndStates); |
| 175 | }, |
| 176 | write: () => { |
| 177 | for (const row of rows) { |
| 178 | for (let i = 0; i < numCells; i++) { |
| 179 | const cell = row.children[i] as HTMLElement; |
| 180 | if (stickyStartStates[i]) { |
| 181 | this._addStickyStyle(cell, start, startPositions[i], i === lastStickyStart); |
| 182 | } |
| 183 | |
| 184 | if (stickyEndStates[i]) { |
no test coverage detected