|
| 1 | +import { setupIgnoreWindowResizeObserverLoopErrors } from '@lit-labs/virtualizer/support/resize-observer-errors.js'; |
1 | 2 | import { expect } from '@open-wc/testing'; |
2 | 3 | import type { Keys } from '../src/internal/types.js'; |
3 | 4 | import GridTestFixture from './utils/grid-fixture.js'; |
4 | 5 | import data, { type TestData } from './utils/test-data.js'; |
5 | 6 |
|
6 | | -const TDD = new GridTestFixture(data); |
| 7 | +// reduced width to force scroll: |
| 8 | +const TDD = new GridTestFixture(data, { width: '300px' }); |
7 | 9 | const keys = Object.keys(data[0]) as Array<Keys<TestData>>; |
8 | 10 |
|
| 11 | +function isVisibleGrid(element: Element): boolean { |
| 12 | + const rect = element.getBoundingClientRect(); |
| 13 | + const { top, bottom } = TDD.gridBody.getBoundingClientRect(); |
| 14 | + const { left, right } = TDD.grid.getBoundingClientRect(); |
| 15 | + |
| 16 | + return rect.top >= top && rect.bottom <= bottom && rect.left >= left && rect.right <= right; |
| 17 | +} |
| 18 | + |
9 | 19 | describe('Grid activation', () => { |
| 20 | + setupIgnoreWindowResizeObserverLoopErrors(beforeEach, afterEach); |
10 | 21 | beforeEach(async () => await TDD.setUp()); |
11 | 22 | afterEach(() => TDD.tearDown()); |
12 | 23 |
|
@@ -118,4 +129,108 @@ describe('Grid activation', () => { |
118 | 129 | expect(TDD.rows.last.cells.first.active).to.be.true; |
119 | 130 | }); |
120 | 131 | }); |
| 132 | + |
| 133 | + describe('navigateTo API', () => { |
| 134 | + // extend test data to move into virtualized scroll: |
| 135 | + const testData = [ |
| 136 | + ...data, |
| 137 | + ...data.map((x) => ({ ...x, id: x.id + data.length })), |
| 138 | + ...data.map((x) => ({ ...x, id: x.id + data.length * 2 })), |
| 139 | + ]; |
| 140 | + |
| 141 | + beforeEach(async () => { |
| 142 | + await TDD.updateProperty('data', testData); |
| 143 | + // expect horizontal and vertical scroll to ensure test setup doesn't change |
| 144 | + expect(TDD.grid.scrollWidth > TDD.grid.clientWidth).to.be.true; |
| 145 | + expect(TDD.gridBody.scrollHeight > TDD.gridBody.clientHeight).to.be.true; |
| 146 | + }); |
| 147 | + |
| 148 | + it('navigates to rows only', async () => { |
| 149 | + await TDD.grid.navigateTo(testData.length - 1); |
| 150 | + |
| 151 | + let cell = TDD.rows.last.cells.first; |
| 152 | + expect(cell.active).to.be.false; |
| 153 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 154 | + |
| 155 | + await TDD.grid.navigateTo(0); |
| 156 | + |
| 157 | + cell = TDD.rows.first.cells.first; |
| 158 | + expect(cell.active).to.be.false; |
| 159 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 160 | + }); |
| 161 | + |
| 162 | + it('navigates to a specific row and column', async () => { |
| 163 | + await TDD.grid.navigateTo(testData.length - 2, 'name'); |
| 164 | + |
| 165 | + const cell = TDD.rows.get(-2).cells.get('name'); |
| 166 | + expect(cell.active).to.be.false; |
| 167 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 168 | + }); |
| 169 | + |
| 170 | + it('navigates to a cell within already scrolled-to row', async () => { |
| 171 | + await TDD.grid.navigateTo(testData.length - 1, 'id'); |
| 172 | + |
| 173 | + let cell = TDD.rows.last.cells.get('id'); |
| 174 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 175 | + |
| 176 | + // last cell |
| 177 | + cell = TDD.rows.last.cells.last; |
| 178 | + expect(isVisibleGrid(cell.element)).to.be.false; |
| 179 | + await TDD.grid.navigateTo(testData.length - 1, keys.at(-1)); |
| 180 | + |
| 181 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 182 | + }); |
| 183 | + |
| 184 | + it('navigates through all columns', async () => { |
| 185 | + for (const key of keys) { |
| 186 | + await TDD.grid.navigateTo(0, key); |
| 187 | + const cell = TDD.rows.first.cells.get(key); |
| 188 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 189 | + } |
| 190 | + }); |
| 191 | + |
| 192 | + it('updates active state when navigating', async () => { |
| 193 | + await TDD.grid.navigateTo(0, 'id', true); |
| 194 | + expect(TDD.rows.first.cells.get('id').active).to.be.true; |
| 195 | + |
| 196 | + await TDD.grid.navigateTo(1, 'name', true); |
| 197 | + expect(TDD.rows.first.cells.get('id').active).to.be.false; |
| 198 | + |
| 199 | + let cell = TDD.rows.get(1).cells.get('name'); |
| 200 | + expect(cell.active).to.be.true; |
| 201 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 202 | + |
| 203 | + // last cell |
| 204 | + await TDD.grid.navigateTo(testData.length - 1, keys.at(-1), true); |
| 205 | + |
| 206 | + cell = TDD.rows.last.cells.last; |
| 207 | + expect(cell.active).to.be.true; |
| 208 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 209 | + }); |
| 210 | + |
| 211 | + it('can navigate after click activation', async () => { |
| 212 | + await TDD.clickCell(TDD.rows.first.cells.first); |
| 213 | + expect(TDD.rows.first.cells.first.active).to.be.true; |
| 214 | + |
| 215 | + await TDD.grid.navigateTo(3, 'active', true); |
| 216 | + expect(TDD.rows.first.cells.first.active).to.be.false; |
| 217 | + |
| 218 | + const cell = TDD.rows.get(3).cells.get('active'); |
| 219 | + expect(cell.active).to.be.true; |
| 220 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 221 | + }); |
| 222 | + |
| 223 | + it('keyboard navigation works after navigateTo', async () => { |
| 224 | + await TDD.grid.navigateTo(2, 'id', true); |
| 225 | + expect(TDD.rows.get(2).cells.get('id').active).to.be.true; |
| 226 | + |
| 227 | + await TDD.fireNavigationEvent({ key: 'ArrowRight' }); |
| 228 | + expect(TDD.rows.get(2).cells.get('name').active).to.be.true; |
| 229 | + |
| 230 | + await TDD.fireNavigationEvent({ key: 'ArrowDown' }); |
| 231 | + const cell = TDD.rows.get(3).cells.get('name'); |
| 232 | + expect(cell.active).to.be.true; |
| 233 | + expect(isVisibleGrid(cell.element)).to.be.true; |
| 234 | + }); |
| 235 | + }); |
121 | 236 | }); |
0 commit comments