@@ -2,26 +2,49 @@ import { expandElement, collapseElement, initCollapsible } from "./../../collaps
22import { $d , $$ } from "@flexilla/utilities/selector"
33
44const getAdjacentTrigger = ( currentTrigger : HTMLElement , goUp : boolean , accordionElement : HTMLElement ) => {
5- const allAccordionItems = $$ ( "[data-accordion-item]" , accordionElement )
6- const accordionItems = allAccordionItems . filter ( ( item ) => item . parentElement === accordionElement ) ;
7- const currentTriggerIndex = Array . from ( accordionItems ) . indexOf ( currentTrigger . closest ( '[data-accordion-item]' ) ! ) ;
8- const nextIndex = goUp ? currentTriggerIndex - 1 : currentTriggerIndex + 1 ;
9- const nextTrigger = $d ( "[data-accordion-trigger]" , accordionItems [ nextIndex ] ) as HTMLElement
5+ // Get all direct children [data-accordion-item] of accordionElement
6+ const accordionItems = $$ ( `:scope > [data-accordion-item]` , accordionElement ) as HTMLElement [ ] ;
107
11- return nextTrigger ?? ( goUp ? $d ( "[data-accordion-trigger]" , accordionItems [ accordionItems . length - 1 ] ) : $d ( "[data-accordion-trigger]" , accordionItems [ 0 ] ) )
12- }
8+ // Find the current accordion item (direct parent of the trigger)
9+ const currentItem = currentTrigger . parentElement ;
10+ if ( ! accordionItems . includes ( currentItem as HTMLElement ) ) return null ; // Not a valid direct child item
11+
12+ const currentIndex = accordionItems . indexOf ( currentItem as HTMLElement ) ;
13+ const nextIndex = goUp ? currentIndex - 1 : currentIndex + 1 ;
14+
15+ // Determine the next item, looping to last/first if out of bounds
16+ const nextItem =
17+ accordionItems [ nextIndex ] ??
18+ ( goUp ? accordionItems [ accordionItems . length - 1 ] : accordionItems [ 0 ] ) ;
19+
20+ // Select trigger that is a direct child of the next item
21+ const nextTrigger = $d ( `:scope > [data-accordion-trigger]` , nextItem ) ;
22+ return nextTrigger instanceof HTMLElement ? nextTrigger : null ;
23+ } ;
1324
1425const initKeyEvents = ( event : KeyboardEvent , accordionElement : HTMLElement ) => {
26+ if ( ! ( document . activeElement instanceof HTMLElement ) ) return ;
27+
1528 const focusedTrigger = document . activeElement ;
16- if ( ! ( focusedTrigger instanceof HTMLElement ) ) return
1729
18- const isTriggerFocused = focusedTrigger . matches ( '[data-accordion-trigger]' ) ;
19- if ( isTriggerFocused && ( event . key === 'ArrowUp' || event . key === 'ArrowDown' ) ) {
20- event . preventDefault ( ) ; // Prevent default scrolling behavior
30+ // Ensure it's the right trigger in the correct structure
31+ const parentItem = focusedTrigger . parentElement ;
32+ if (
33+ ! focusedTrigger . matches ( '[data-accordion-trigger]' ) ||
34+ ! parentItem ?. matches ( '[data-accordion-item]' ) ||
35+ parentItem . parentElement !== accordionElement
36+ ) {
37+ return ;
38+ }
39+
40+ if ( event . key === 'ArrowUp' || event . key === 'ArrowDown' ) {
41+ event . preventDefault ( ) ; // Prevent default scrolling
2142 const nextTrigger = getAdjacentTrigger ( focusedTrigger , event . key === 'ArrowUp' , accordionElement ) ;
22- nextTrigger . focus ( ) ;
43+ if ( nextTrigger ) {
44+ nextTrigger . focus ( ) ;
45+ }
2346 }
24- }
47+ } ;
2548
2649const changeTriggerState = ( trigger : HTMLElement , state : "open" | "close" ) => {
2750 trigger . ariaExpanded = state === "open" ? "true" : "false" ;
0 commit comments