Skip to content

Commit c031c6a

Browse files
authored
fix: Run adopted styles on connected callback (#58)
1 parent 6d548f9 commit c031c6a

2 files changed

Lines changed: 76 additions & 3 deletions

File tree

src/components/cell.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,18 @@ export default class IgcGridLiteCell<T extends object> extends LitElement {
6767
} as unknown as IgcCellContext<T>;
6868
}
6969

70+
private get _shouldAdoptStyles(): boolean {
71+
return this.adoptRootStyles && this.cellTemplate != null;
72+
}
73+
74+
public override connectedCallback(): void {
75+
super.connectedCallback();
76+
this._adoptedStylesController.shouldAdoptStyles(this._shouldAdoptStyles);
77+
}
78+
7079
protected override update(props: PropertyValues<this>): void {
7180
if (props.has('adoptRootStyles')) {
72-
this._adoptedStylesController.shouldAdoptStyles(
73-
this.adoptRootStyles && this.cellTemplate != null
74-
);
81+
this._adoptedStylesController.shouldAdoptStyles(this._shouldAdoptStyles);
7582
}
7683

7784
super.update(props);

test/adopt-root-styles.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,4 +478,70 @@ describe('Grid adopt-root-styles property', () => {
478478
expect(computedStyle.fontWeight).to.equal('700');
479479
});
480480
});
481+
482+
describe('Virtualizer cell caching', () => {
483+
beforeEach(async () => {
484+
adoptRootStylesTDD.columnConfig = [
485+
{
486+
field: 'name',
487+
sortable: true,
488+
cellTemplate: (ctx: IgcCellContext<TestData>) =>
489+
litHtml`<div class="custom-cell-class">${ctx.value}</div>`,
490+
},
491+
{ field: 'id', sortable: true },
492+
];
493+
await adoptRootStylesTDD.setUp();
494+
});
495+
496+
afterEach(() => adoptRootStylesTDD.tearDown());
497+
498+
it('should preserve adopted styles when a cell is disconnected and reconnected by the virtualizer', async () => {
499+
const cell = adoptRootStylesTDD.rows.first.cells.get('name');
500+
const cellElement = cell.element as IgcGridLiteCell<TestData>;
501+
502+
// Verify initial adopted state
503+
// @ts-expect-error - Accessing private controller for testing
504+
expect(cellElement._adoptedStylesController.hasAdoptedStyles).to.be.true;
505+
506+
// Simulate virtualizer caching: disconnect the cell and reconnect it with
507+
// properties already set (no Lit property-change cycle will fire in update)
508+
const parentNode = cellElement.parentNode!;
509+
parentNode.removeChild(cellElement);
510+
await nextFrame();
511+
parentNode.appendChild(cellElement);
512+
await cellElement.updateComplete;
513+
514+
// connectedCallback must re-apply shouldAdoptStyles regardless of whether
515+
// adoptRootStyles changed, because the property did not change so the
516+
// update() guard (props.has('adoptRootStyles')) never fires
517+
// @ts-expect-error - Accessing private controller for testing
518+
expect(cellElement._adoptedStylesController.hasAdoptedStyles).to.be.true;
519+
520+
const customDiv = cellElement.shadowRoot!.querySelector('.custom-cell-class');
521+
expect(customDiv).to.exist;
522+
const computedStyle = window.getComputedStyle(customDiv!);
523+
expect(computedStyle.color).to.equal('rgb(255, 0, 0)');
524+
});
525+
526+
it('should preserve adopted styles after sorting already-sorted data across multiple columns', async () => {
527+
// The test data IDs are 1–8 in ascending order, so sorting ascending by id
528+
// produces no reordering. The virtualizer therefore recycles cells in-place
529+
// without a full connected/disconnected lifecycle, meaning connectedCallback
530+
// is never re-invoked and update()'s props.has('adoptRootStyles') guard
531+
// does not fire — this is the exact scenario the connectedCallback fix covers.
532+
await adoptRootStylesTDD.sortHeader('id');
533+
534+
// A second sort column keeps the order stable (all ids are unique, so the
535+
// secondary key never kicks in), producing another no-op reorder pass.
536+
await adoptRootStylesTDD.sortHeader('name');
537+
538+
for (let i = 0; i < adoptRootStylesTDD.grid.rows.length; i++) {
539+
const cellElement = adoptRootStylesTDD.rows.get(i).cells.get('name')
540+
.element as IgcGridLiteCell<TestData>;
541+
542+
// @ts-expect-error - Accessing private controller for testing
543+
expect(cellElement._adoptedStylesController.hasAdoptedStyles).to.be.true;
544+
}
545+
});
546+
});
481547
});

0 commit comments

Comments
 (0)