Skip to content

Commit e01ad94

Browse files
committed
Add the blue line indicator
1 parent 05a835f commit e01ad94

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

packages/react/src/FilteredActionList/FilteredActionList.module.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
flex-grow: 1;
66
}
77

8+
.ActiveItem::after {
9+
@mixin activeIndicatorLine;
10+
}
11+
812
.FullScreenTextInput {
913
@media screen and (--viewportRange-narrow) {
1014
/* Ensures inputs don't zoom on mobile iPhone but are body-font size on iPad */

packages/react/src/FilteredActionList/FilteredActionListWithModernActionList.tsx

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import {FocusKeys} from '@primer/behaviors'
2-
import type {KeyboardEventHandler} from 'react'
31
import type React from 'react'
42
import {useCallback, useEffect, useRef, useState} from 'react'
53
import styled from 'styled-components'
@@ -134,6 +132,51 @@ export function FilteredActionList({
134132
}
135133
}, [items, inputRef, selectedItems])
136134

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+
137180
useEffect(() => {
138181
setEnableAnnouncements(announcementsEnabled)
139182
}, [announcementsEnabled])

0 commit comments

Comments
 (0)