Skip to content

Commit bb54db6

Browse files
authored
fix(virtualizer): layout measure override, patch scale w/ offsetHeight (#30)
1 parent 54de980 commit bb54db6

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

src/components/virtualizer.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import { LitVirtualizer } from '@lit-labs/virtualizer/LitVirtualizer.js';
22
import { registerComponent } from '../internal/register.js';
33
import { GRID_BODY } from '../internal/tags.js';
4+
import { IgcFlowLayout } from '../internal/virt-flow-layout.js';
45

56
export default class IgcVirtualizer extends LitVirtualizer {
67
public static get tagName() {
78
return GRID_BODY;
89
}
910

11+
public override layout: LitVirtualizer['layout'] = {
12+
type: IgcFlowLayout,
13+
};
14+
1015
public static register(): void {
1116
registerComponent(IgcVirtualizer);
1217
}

src/internal/virt-flow-layout.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { FlowLayout } from '@lit-labs/virtualizer/layouts/flow.js';
2+
3+
/**
4+
* Override for the [built-in item measure function](https://github.com/lit/lit/blob/f243134b226735320b61466cebdaf0c1e574bfa7/packages/labs/virtualizer/src/Virtualizer.ts#L519-L524)
5+
* @see {@link https://github.com/IgniteUI/igniteui-grid-lite/issues/20 #20} for more.
6+
* @remarks
7+
* Note: Unlike the built-in, this does _not_ measure margins and will not work with such.
8+
*/
9+
function measureItemWithScaleAdjust(element: HTMLElement) {
10+
let { width, height } = element.getBoundingClientRect();
11+
const offsetHeight = element.offsetHeight;
12+
if (Math.abs(offsetHeight - height) > 1) {
13+
// likely scaling, prefer the offsetHeight
14+
// should check if its on rows vs virtualizer, but oh well
15+
height = offsetHeight;
16+
}
17+
return { width, height };
18+
}
19+
20+
export class IgcFlowLayout extends FlowLayout {
21+
public override get measureChildren(): boolean {
22+
// @ts-expect-error - Base class types this as boolean, but runtime accepts a function override
23+
return measureItemWithScaleAdjust;
24+
}
25+
}

test/virtualization.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { expect } from '@open-wc/testing';
2+
import GridTestFixture from './utils/grid-fixture.js';
3+
import data from './utils/test-data.js';
4+
5+
const TDD = new GridTestFixture(data, { transform: 'scale(0.5, 0.5)' });
6+
7+
describe('Grid scaled initial render', () => {
8+
beforeEach(async () => await TDD.setUp());
9+
afterEach(() => TDD.tearDown());
10+
11+
it('should position items correctly in virtualizer', async () => {
12+
function checkRowTopTranslate(index: number) {
13+
const row = TDD.rows.get(index).element;
14+
const { height } = row.getBoundingClientRect();
15+
const offsetHeight = row.offsetHeight;
16+
const { transform } = row.style;
17+
18+
expect(offsetHeight / height).to.equal(2);
19+
expect(transform).to.equal(`translate(0px, ${offsetHeight * index}px)`);
20+
}
21+
22+
for (let i = 0; i < data.length; i++) {
23+
checkRowTopTranslate(i);
24+
}
25+
});
26+
});

0 commit comments

Comments
 (0)