File tree Expand file tree Collapse file tree 3 files changed +52
-11
lines changed Expand file tree Collapse file tree 3 files changed +52
-11
lines changed Original file line number Diff line number Diff line change @@ -83,6 +83,45 @@ describe('Rendering', () => {
8383 assertTabs ( { active : 0 } )
8484 } )
8585
86+ it ( 'should guarantee the order of DOM nodes when performing actions' , async ( ) => {
87+ render ( svelte `
88+ <script>
89+ let hide = false;
90+ </script>
91+
92+ <button on:click={() => hide = !hide}>toggle</button>
93+ <TabGroup>
94+ <TabList>
95+ <Tab>Tab 1</Tab>
96+ {#if !hide}
97+ <Tab>Tab 2</Tab>
98+ {/if}
99+ <Tab>Tab 3</Tab>
100+ </TabList>
101+
102+ <TabPanels>
103+ <TabPanel>Content 1</TabPanel>
104+ {#if !hide}
105+ <TabPanel>Content 2</TabPanel>
106+ {/if}
107+ <TabPanel>Content 3</TabPanel>
108+ </TabPanels>
109+ </TabGroup>
110+ ` )
111+
112+ await click ( getByText ( 'toggle' ) ) // Remove Tab 2
113+ await click ( getByText ( 'toggle' ) ) // Re-add Tab 2
114+
115+ await press ( Keys . Tab )
116+ assertTabs ( { active : 0 } )
117+
118+ await press ( Keys . ArrowRight )
119+ assertTabs ( { active : 1 } )
120+
121+ await press ( Keys . ArrowRight )
122+ assertTabs ( { active : 2 } )
123+ } )
124+
86125 describe ( '`slot props`' , ( ) => {
87126 it ( 'should expose the `selectedIndex` on the `TabGroup` component' , async ( ) => {
88127 render ( svelte `
Original file line number Diff line number Diff line change @@ -1359,12 +1359,8 @@ export function assertTabs(
13591359 expect ( list ) . toHaveAttribute ( "role" , "tablist" ) ;
13601360 expect ( list ) . toHaveAttribute ( "aria-orientation" , orientation ) ;
13611361
1362- let activeTab = tabs . find (
1363- ( tab ) => tab . dataset . headlessuiIndex === "" + active
1364- ) ;
1365- let activePanel = panels . find (
1366- ( panel ) => panel . dataset . headlessuiIndex === "" + active
1367- ) ;
1362+ let activeTab = Array . from ( list . querySelectorAll ( '[id^="headlessui-tabs-tab-"]' ) ) [ active ]
1363+ let activePanel = panels . find ( panel => panel . id === activeTab . getAttribute ( 'aria-controls' ) )
13681364
13691365 for ( let tab of tabs ) {
13701366 expect ( tab ) . toHaveAttribute ( "id" ) ;
Original file line number Diff line number Diff line change @@ -16,10 +16,10 @@ let focusableSelector = [
1616 . map (
1717 process . env . NODE_ENV === "test"
1818 ? // TODO: Remove this once JSDOM fixes the issue where an element that is
19- // "hidden" can be the document.activeElement, because this is not possible
20- // in real browsers.
21- ( selector ) =>
22- `${ selector } :not([tabindex='-1']):not([style*='display: none'])`
19+ // "hidden" can be the document.activeElement, because this is not possible
20+ // in real browsers.
21+ ( selector ) =>
22+ `${ selector } :not([tabindex='-1']):not([style*='display: none'])`
2323 : ( selector ) => `${ selector } :not([tabindex='-1'])`
2424 )
2525 . join ( "," ) ;
@@ -100,7 +100,13 @@ export function focusElement(element: HTMLElement | null) {
100100
101101export function focusIn ( container : HTMLElement | HTMLElement [ ] , focus : Focus ) {
102102 let elements = Array . isArray ( container )
103- ? container
103+ ? container . slice ( ) . sort ( ( a , b ) => {
104+ let position = a . compareDocumentPosition ( b )
105+
106+ if ( position & Node . DOCUMENT_POSITION_FOLLOWING ) return - 1
107+ if ( position & Node . DOCUMENT_POSITION_PRECEDING ) return 1
108+ return 0
109+ } )
104110 : getFocusableElements ( container ) ;
105111 let active = document . activeElement as HTMLElement ;
106112
You can’t perform that action at this time.
0 commit comments