11import {
22 ChangeDetectionStrategy ,
33 Component ,
4- Input ,
54 input ,
65 signal ,
76 type TemplateRef ,
@@ -11,17 +10,19 @@ import {
1110 type CellContext ,
1211 ColumnDef ,
1312 getCoreRowModel ,
13+ TableOptions ,
14+ type TableState ,
1415} from '@tanstack/table-core'
1516import {
1617 createAngularTable ,
18+ FlexRender ,
1719 flexRenderComponent ,
18- FlexRenderComponent ,
1920 type FlexRenderContent ,
2021 FlexRenderDirective ,
2122 injectFlexRenderContext ,
2223} from '../src'
2324import { TestBed } from '@angular/core/testing'
24- import { describe , expect , test } from 'vitest'
25+ import { describe , expect , test , vi } from 'vitest'
2526import { By } from '@angular/platform-browser'
2627
2728const defaultData : TestData [ ] = [ { id : '1' , title : 'My title' } ] as TestData [ ]
@@ -149,6 +150,63 @@ describe('FlexRenderDirective', () => {
149150 expect ( el ! . tagName ) . toEqual ( 'APP-TEST-BADGE' )
150151 expect ( el . textContent ) . toEqual ( 'Updated status' )
151152 } )
153+
154+ test ( 'Cell content always get the latest context value' , async ( ) => {
155+ const contextCaptor = vi . fn ( )
156+
157+ const tableState = signal < Partial < TableState > > ( {
158+ rowSelection : { } ,
159+ } )
160+
161+ @Component ( {
162+ template : `` ,
163+ } )
164+ class EmptyCell { }
165+
166+ const { dom, fixture } = createTestTable (
167+ defaultData ,
168+ [
169+ {
170+ id : 'cell' ,
171+ header : 'Header' ,
172+ cell : context => {
173+ contextCaptor ( context )
174+ return flexRenderComponent ( EmptyCell )
175+ } ,
176+ } ,
177+ ] ,
178+ ( ) => ( {
179+ state : tableState ( ) ,
180+ onStateChange : updater => {
181+ return typeof updater === 'function'
182+ ? tableState . update ( updater as any )
183+ : tableState . set ( updater )
184+ } ,
185+ } )
186+ )
187+
188+ const latestCall = ( ) =>
189+ contextCaptor . mock . lastCall [ 0 ] as CellContext < TestData , any >
190+ // TODO: As a perf improvement, check in a future if we can avoid evaluating the cell twice during the first render.
191+ // This is caused due to the registration of the initial effect and the first #getContentValue() to detect the
192+ // type of content to render.
193+ expect ( contextCaptor ) . toHaveBeenCalledTimes ( 2 )
194+
195+ expect ( latestCall ( ) . row . getIsExpanded ( ) ) . toEqual ( false )
196+ expect ( latestCall ( ) . row . getIsSelected ( ) ) . toEqual ( false )
197+
198+ fixture . componentInstance . table . getRow ( '0' ) . toggleSelected ( true )
199+ dom . clickTriggerCdButton2 ( )
200+ expect ( contextCaptor ) . toHaveBeenCalledTimes ( 3 )
201+ expect ( latestCall ( ) . row . getIsSelected ( ) ) . toEqual ( true )
202+
203+ fixture . componentInstance . table . getRow ( '0' ) . toggleSelected ( false )
204+ fixture . componentInstance . table . getRow ( '0' ) . toggleExpanded ( true )
205+ dom . clickTriggerCdButton2 ( )
206+ expect ( contextCaptor ) . toHaveBeenCalledTimes ( 4 )
207+ expect ( latestCall ( ) . row . getIsSelected ( ) ) . toEqual ( false )
208+ expect ( latestCall ( ) . row . getIsExpanded ( ) ) . toEqual ( true )
209+ } )
152210} )
153211
154212function expectPrimitiveValueIs (
@@ -166,7 +224,8 @@ type TestData = { id: string; title: string }
166224
167225export function createTestTable (
168226 data : TestData [ ] ,
169- columns : ColumnDef < TestData , any > [ ]
227+ columns : ColumnDef < TestData , any > [ ] ,
228+ optionsFn ?: ( ) => Partial < TableOptions < TestData > >
170229) {
171230 @Component ( {
172231 template : `
@@ -229,7 +288,7 @@ export function createTestTable(
229288 changeDetection : ChangeDetectionStrategy . OnPush ,
230289 standalone : true ,
231290 selector : 'app-table-test' ,
232- imports : [ FlexRenderDirective ] ,
291+ imports : [ FlexRender ] ,
233292 } )
234293 class TestComponent {
235294 readonly columns = input < ColumnDef < TestData > [ ] > ( columns )
@@ -239,6 +298,7 @@ export function createTestTable(
239298
240299 readonly table = createAngularTable ( ( ) => {
241300 return {
301+ ...( optionsFn ?.( ) ?? { } ) ,
242302 columns : this . columns ( ) ,
243303 data : this . data ( ) ,
244304 getCoreRowModel : getCoreRowModel ( ) ,
0 commit comments