@@ -2,7 +2,7 @@ import type {ScrollIntoViewOptions} from '@primer/behaviors'
22import { scrollIntoView , FocusKeys } from '@primer/behaviors'
33import type { KeyboardEventHandler , JSX } from 'react'
44import type React from 'react'
5- import { useCallback , useEffect , useRef , useState } from 'react'
5+ import { act , useCallback , useEffect , useRef , useState } from 'react'
66import type { TextInputProps } from '../TextInput'
77import TextInput from '../TextInput'
88import { ActionList } from '../ActionList'
@@ -23,6 +23,7 @@ import {isValidElementType} from 'react-is'
2323import { useAnnouncements } from './useAnnouncements'
2424import { clsx } from 'clsx'
2525import { useFeatureFlag } from '../FeatureFlags'
26+ import { useIsMacOS } from '../hooks'
2627
2728const menuScrollMargins : ScrollIntoViewOptions = { startMargin : 0 , endMargin : 8 }
2829
@@ -93,6 +94,8 @@ export function FilteredActionList({
9394 const inputDescriptionTextId = useId ( )
9495 const [ isInputFocused , setIsInputFocused ] = useState ( false )
9596
97+ const isMacOS = useIsMacOS ( )
98+
9699 const selectAllChecked = items . length > 0 && items . every ( item => item . selected )
97100 const selectAllIndeterminate = ! selectAllChecked && items . some ( item => item . selected )
98101
@@ -152,6 +155,16 @@ export function FilteredActionList({
152155
153156 const onInputKeyPress : KeyboardEventHandler = useCallback (
154157 ( event : React . KeyboardEvent < HTMLInputElement > ) => {
158+ if ( event . key === 'U' || event . key === 'u' ) {
159+ if ( event . shiftKey && ( isMacOS ? event . metaKey : event . ctrlKey ) ) {
160+ if ( ! activeDescendantRef . current ?. hasAttribute ( 'data-has-trailing-action' ) ) return
161+
162+ event . preventDefault ( )
163+ alert ( 'Activated Trailing Action' )
164+ // do some action ...
165+ }
166+ }
167+
155168 if ( event . key === 'Enter' && activeDescendantRef . current ) {
156169 event . preventDefault ( )
157170 event . nativeEvent . stopImmediatePropagation ( )
@@ -161,7 +174,7 @@ export function FilteredActionList({
161174 activeDescendantRef . current . dispatchEvent ( activeDescendantEvent )
162175 }
163176 } ,
164- [ activeDescendantRef ] ,
177+ [ activeDescendantRef , isMacOS ] ,
165178 )
166179
167180 // BEGIN: Todo remove when we remove usingRemoveActiveDescendant
@@ -184,7 +197,10 @@ export function FilteredActionList({
184197 bindKeys : FocusKeys . ArrowVertical | FocusKeys . PageUpDown ,
185198 focusOutBehavior : 'wrap' ,
186199 focusableElementFilter : element => {
187- return ! ( element instanceof HTMLInputElement )
200+ return (
201+ ! ( element instanceof HTMLInputElement ) &&
202+ ! ( element . parentElement ?. getAttribute ( 'data-component' ) === 'TrailingAction' )
203+ )
188204 } ,
189205 activeDescendantFocus : inputRef ,
190206 onActiveDescendantChanged : ( current , previous , directlyActivated ) => {
@@ -347,8 +363,8 @@ export function FilteredActionList({
347363 color = "fg.default"
348364 value = { filterValue }
349365 onChange = { onInputChange }
350- onKeyPress = { onInputKeyPress }
351- onKeyDown = { usingRemoveActiveDescendant ? onInputKeyDown : ( ) => { } }
366+ // onKeyPress={onInputKeyPress}
367+ onKeyDown = { usingRemoveActiveDescendant ? onInputKeyDown : onInputKeyPress }
352368 placeholder = { placeholderText }
353369 role = "combobox"
354370 aria-expanded = "true"
@@ -398,6 +414,7 @@ function MappedActionListItem(item: ItemInput & {renderItem?: RenderItemFn}) {
398414 leadingVisual : LeadingVisual ,
399415 trailingText,
400416 trailingIcon : TrailingIcon ,
417+ trailingAction,
401418 onAction,
402419 children,
403420 ...rest
@@ -436,6 +453,16 @@ function MappedActionListItem(item: ItemInput & {renderItem?: RenderItemFn}) {
436453 { TrailingIcon && < TrailingIcon /> }
437454 </ ActionList . TrailingVisual >
438455 ) : null }
456+ { trailingAction ? (
457+ < ActionList . TrailingAction
458+ label = { trailingAction . label }
459+ icon = { trailingAction . icon }
460+ { ...( trailingAction . as === 'a' && trailingAction . href
461+ ? { as : 'a' as const , href : trailingAction . href }
462+ : { as : 'button' as const , loading : trailingAction . loading } ) }
463+ onClick = { trailingAction . onClick }
464+ />
465+ ) : null }
439466 </ ActionList . Item >
440467 )
441468}
0 commit comments