|
1 |
| -import {FocusKeys} from '@primer/behaviors' |
2 |
| -import type {KeyboardEventHandler} from 'react' |
3 | 1 | import type React from 'react'
|
4 | 2 | import {useCallback, useEffect, useRef, useState} from 'react'
|
5 | 3 | import styled from 'styled-components'
|
@@ -134,6 +132,51 @@ export function FilteredActionList({
|
134 | 132 | }
|
135 | 133 | }, [items, inputRef, selectedItems])
|
136 | 134 |
|
| 135 | + // Focus management for active indicator line |
| 136 | + useEffect(() => { |
| 137 | + const list = listRef.current |
| 138 | + if (!list) return |
| 139 | + |
| 140 | + const updateActiveIndicator = () => { |
| 141 | + // Clear any existing active indicators |
| 142 | + const activeItems = list.querySelectorAll(`.${classes.ActiveItem}`) |
| 143 | + activeItems.forEach(item => { |
| 144 | + item.classList.remove(classes.ActiveItem) |
| 145 | + }) |
| 146 | + |
| 147 | + if (inputRef.current && document.activeElement === inputRef.current) { |
| 148 | + // When input is focused, mark the first item as active |
| 149 | + const firstItem = list.querySelector('[role="option"]') as HTMLElement | null |
| 150 | + if (firstItem) { |
| 151 | + firstItem.classList.add(classes.ActiveItem) |
| 152 | + } |
| 153 | + } else if (list.contains(document.activeElement)) { |
| 154 | + // When an item in the list is focused, mark it as active |
| 155 | + const focusedItem = document.activeElement as HTMLElement |
| 156 | + if (focusedItem.getAttribute('role') === 'option') { |
| 157 | + focusedItem.classList.add(classes.ActiveItem) |
| 158 | + } |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + // Initial update |
| 163 | + updateActiveIndicator() |
| 164 | + |
| 165 | + // Listen for focus changes within the container |
| 166 | + const handleFocusIn = (event: FocusEvent) => { |
| 167 | + if (event.target === inputRef.current || list.contains(event.target as Node)) { |
| 168 | + updateActiveIndicator() |
| 169 | + } |
| 170 | + } |
| 171 | + |
| 172 | + // Attach focus listeners to the document to catch all focus changes |
| 173 | + document.addEventListener('focusin', handleFocusIn) |
| 174 | + |
| 175 | + return () => { |
| 176 | + document.removeEventListener('focusin', handleFocusIn) |
| 177 | + } |
| 178 | + }, [items]) // Re-run when items change to ensure first item is properly marked |
| 179 | + |
137 | 180 | useEffect(() => {
|
138 | 181 | setEnableAnnouncements(announcementsEnabled)
|
139 | 182 | }, [announcementsEnabled])
|
|
0 commit comments