@@ -236,6 +236,64 @@ describe('field directive', () => {
236236 } ) ;
237237 } ) ;
238238
239+ describe ( 'hidden' , ( ) => {
240+ it ( 'should bind to a custom control' , ( ) => {
241+ @Component ( { selector : 'custom-control' , template : `` } )
242+ class CustomControl implements FormValueControl < string > {
243+ readonly value = model . required < string > ( ) ;
244+ readonly hidden = input . required < boolean > ( ) ;
245+ }
246+
247+ const visible = signal ( false ) ;
248+
249+ @Component ( {
250+ imports : [ Field , CustomControl ] ,
251+ template : `<custom-control [field]="field()" />` ,
252+ } )
253+ class TestCmp {
254+ readonly f = form ( signal ( '' ) , ( p ) => {
255+ hidden ( p , ( ) => ! visible ( ) ) ;
256+ } ) ;
257+ readonly field = signal ( this . f ) ;
258+ readonly customControl = viewChild . required ( CustomControl ) ;
259+ }
260+
261+ const fixture = act ( ( ) => TestBed . createComponent ( TestCmp ) ) ;
262+ const component = fixture . componentInstance ;
263+ expect ( component . customControl ( ) . hidden ( ) ) . toBe ( true ) ;
264+
265+ act ( ( ) => visible . set ( true ) ) ;
266+ expect ( component . customControl ( ) . hidden ( ) ) . toBe ( false ) ;
267+ } ) ;
268+
269+ it ( 'should be reset when field changes on custom control' , ( ) => {
270+ @Component ( { selector : 'custom-control' , template : `` } )
271+ class CustomControl implements FormValueControl < string > {
272+ readonly value = model . required < string > ( ) ;
273+ readonly hidden = input . required < boolean > ( ) ;
274+ }
275+
276+ @Component ( {
277+ imports : [ Field , CustomControl ] ,
278+ template : `<custom-control [field]="field()" />` ,
279+ } )
280+ class TestCmp {
281+ readonly f = form ( signal ( { x : 'a' , y : 'b' } ) , ( p ) => {
282+ hidden ( p . x , ( ) => true ) ;
283+ } ) ;
284+ readonly field = signal ( this . f . x ) ;
285+ readonly customControl = viewChild . required ( CustomControl ) ;
286+ }
287+
288+ const fixture = act ( ( ) => TestBed . createComponent ( TestCmp ) ) ;
289+ const component = fixture . componentInstance ;
290+ expect ( component . customControl ( ) . hidden ( ) ) . toBe ( true ) ;
291+
292+ act ( ( ) => component . field . set ( component . f . y ) ) ;
293+ expect ( component . customControl ( ) . hidden ( ) ) . toBe ( false ) ;
294+ } ) ;
295+ } ) ;
296+
239297 describe ( 'name' , ( ) => {
240298 it ( 'should bind to native control' , ( ) => {
241299 @Component ( {
@@ -2036,34 +2094,6 @@ describe('field directive', () => {
20362094 expect ( comp . myInput ( ) . invalid ( ) ) . toBe ( false ) ;
20372095 } ) ;
20382096
2039- it ( 'should synchronize hidden status' , ( ) => {
2040- @Component ( {
2041- selector : 'my-input' ,
2042- template : '<input #i [value]="value()" (input)="value.set(i.value)" />' ,
2043- } )
2044- class CustomInput implements FormValueControl < string > {
2045- value = model ( '' ) ;
2046- hidden = input ( false ) ;
2047- }
2048-
2049- @Component ( {
2050- template : ` <my-input [field]="f" /> ` ,
2051- imports : [ CustomInput , Field ] ,
2052- } )
2053- class HiddenTestCmp {
2054- myInput = viewChild . required < CustomInput > ( CustomInput ) ;
2055- data = signal ( '' ) ;
2056- f = form ( this . data , ( p ) => {
2057- hidden ( p , ( { value} ) => value ( ) === '' ) ;
2058- } ) ;
2059- }
2060-
2061- const comp = act ( ( ) => TestBed . createComponent ( HiddenTestCmp ) ) . componentInstance ;
2062- expect ( comp . myInput ( ) . hidden ( ) ) . toBe ( true ) ;
2063- act ( ( ) => comp . f ( ) . value . set ( 'visible' ) ) ;
2064- expect ( comp . myInput ( ) . hidden ( ) ) . toBe ( false ) ;
2065- } ) ;
2066-
20672097 it ( 'should synchronize dirty status' , ( ) => {
20682098 @Component ( {
20692099 selector : 'my-input' ,
0 commit comments