adobe / react-spectrum

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.
https://react-spectrum.adobe.com
Apache License 2.0
12.82k stars 1.11k forks source link

[RAC] Focus events for collection items #6460

Open staticshock opened 4 months ago

staticshock commented 4 months ago

Provide a general summary of the feature here

ListBoxItem, GridListItem, MenuItem, and Row expose hover state via onHoverStart, onHoverEnd, and onHoverChange. For the sake of keyboard accessibility I generally try to have parity between hover and focus behaviors, so I was sad to find out that collection items don't also expose focus state via onFocusStart, onFocusEnd, onFocusChange.

I found a way to introduce my own onFocusChange event with the following hack:

export function GridListItem({
  children,
  onFocusChange,
  ...props
}: GridListItemProps) {
  const ref = useRef<HTMLDivElement>()

  return (
    <GridListItemBase ref={ref} {...props} className={itemStyles}>
      {(renderProps) => {
        if (onFocusChange) {
          if (renderProps.isFocused !== !!ref.current?.dataset.focused) {
            onFocusChange(renderProps.isFocused)
          }
        }
        return typeof children === 'function' ? children(renderProps) : children
      }}
    </GridListItemBase>
  )
}

This… works? It may fire too may times, but it gets me kind of close to what I was after. But I'd sure like to see something upstream that would allow me to take this code out 🙏

🤔 Expected Behavior?

N/A

😯 Current Behavior

N/A

💁 Possible Solution

No response

🔦 Context

N/A

💻 Examples

No response

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

LFDanLu commented 4 months ago

This sounds reasonable, would definitely be good to have parity with the hover events.