@@ -2,8 +2,9 @@ import type { DOMWrapper, VueWrapper } from '@vue/test-utils'
22import { mount } from '@vue/test-utils'
33import { beforeEach , describe , expect , it } from 'vitest'
44import { axe } from 'vitest-axe'
5- import { nextTick } from 'vue'
5+ import { defineComponent , h , nextTick } from 'vue'
66import { useKbd } from '@/shared'
7+ import { TreeItem , TreeRoot } from '.'
78import Tree from './story/_Tree.vue'
89
910const kbd = useKbd ( )
@@ -333,3 +334,75 @@ describe('given a Tree with bubbleSelect and propagateSelect', () => {
333334 expect ( items . map ( i => i . attributes ( 'aria-selected' ) ) ) . toStrictEqual ( [ 'false' , 'false' , 'false' , 'false' ] )
334335 } )
335336} )
337+
338+ describe ( 'given a Tree with disabled items' , ( ) => {
339+ const treeItems = [
340+ { title : 'apple' } ,
341+ { title : 'banana' } ,
342+ { title : 'cherry' } ,
343+ { title : 'fruits' , children : [ { title : 'grape' } , { title : 'kiwi' } ] } ,
344+ ]
345+
346+ function mountTree ( disabledKeys : string [ ] = [ 'banana' ] , rootDisabled = false ) {
347+ const wrapper = mount ( defineComponent ( {
348+ setup ( ) {
349+ return ( ) => h ( TreeRoot as any , {
350+ items : treeItems ,
351+ getKey : ( item : any ) => item . title ,
352+ selectionBehavior : 'toggle' ,
353+ disabled : rootDisabled ,
354+ expanded : [ 'fruits' ] ,
355+ } , {
356+ default : ( { flattenItems } : any ) => flattenItems . map ( ( item : any ) =>
357+ h ( TreeItem as any , {
358+ key : item . _id ,
359+ ...item . bind ,
360+ disabled : disabledKeys . includes ( item . _id ) ,
361+ } , { default : ( ) => item . value . title } ) ,
362+ ) ,
363+ } )
364+ } ,
365+ } ) , { attachTo : document . body } )
366+ return { wrapper, items : ( ) => wrapper . findAll ( '[role=treeitem]' ) }
367+ }
368+
369+ beforeEach ( ( ) => {
370+ document . body . innerHTML = ''
371+ } )
372+
373+ it ( 'should set aria-disabled and data-disabled attributes' , ( ) => {
374+ const { items } = mountTree ( )
375+ expect ( items ( ) [ 1 ] . attributes ( 'aria-disabled' ) ) . toBe ( 'true' )
376+ expect ( items ( ) [ 1 ] . attributes ( 'data-disabled' ) ) . toBe ( '' )
377+ expect ( items ( ) [ 0 ] . attributes ( 'aria-disabled' ) ) . toBeUndefined ( )
378+ expect ( items ( ) [ 0 ] . attributes ( 'data-disabled' ) ) . toBeUndefined ( )
379+ } )
380+
381+ it ( 'should not select a disabled item on click or keydown' , async ( ) => {
382+ const { items } = mountTree ( )
383+ await items ( ) [ 1 ] . trigger ( 'click' )
384+ expect ( items ( ) [ 1 ] . attributes ( 'aria-selected' ) ) . toBe ( 'false' )
385+ await items ( ) [ 1 ] . trigger ( 'keydown' , { key : kbd . ENTER } )
386+ expect ( items ( ) [ 1 ] . attributes ( 'aria-selected' ) ) . toBe ( 'false' )
387+ } )
388+
389+ it ( 'should not toggle a disabled item' , async ( ) => {
390+ const { items } = mountTree ( [ 'fruits' ] )
391+ expect ( items ( ) . length ) . toBe ( 6 )
392+
393+ await items ( ) [ 3 ] . trigger ( 'click' )
394+ expect ( items ( ) . length ) . toBe ( 6 )
395+
396+ await items ( ) [ 3 ] . trigger ( 'keydown' , { key : kbd . ARROW_LEFT } )
397+ expect ( items ( ) . length ) . toBe ( 6 )
398+ } )
399+
400+ it ( 'should disable all items when root is disabled' , async ( ) => {
401+ const { items } = mountTree ( [ ] , true )
402+ for ( const item of items ( ) ) {
403+ expect ( item . attributes ( 'aria-disabled' ) ) . toBe ( 'true' )
404+ }
405+ await items ( ) [ 0 ] . trigger ( 'click' )
406+ expect ( items ( ) [ 0 ] . attributes ( 'aria-selected' ) ) . toBe ( 'false' )
407+ } )
408+ } )
0 commit comments