Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for ActionList semantics #4272

Merged
merged 48 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
7f21a16
Add fixes for ActionList
TylerJDev Feb 14, 2024
fa708b1
More type fixes
TylerJDev Feb 15, 2024
e087f87
temp type fixes
TylerJDev Feb 15, 2024
76e2606
Add condition for inactive items
TylerJDev Feb 15, 2024
eab6fd9
add yet another condition
TylerJDev Feb 16, 2024
8b4f311
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Feb 20, 2024
614749a
chore(deps): bump changesets/action from 1.4.5 to 1.4.6 (#4282)
dependabot[bot] Feb 20, 2024
bfb8fe2
test(e2e): add e2e test for SelectPanel2 default story (#4279)
joshblack Feb 20, 2024
4b18eed
Address a few v8 color bugs (#4278)
langermank Feb 20, 2024
d13668d
chore(deps-dev): bump ip from 2.0.0 to 2.0.1 (#4291)
dependabot[bot] Feb 20, 2024
10d9866
Change how `ref` is handled
TylerJDev Feb 20, 2024
0939a90
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Feb 20, 2024
cc6a63c
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Feb 29, 2024
1cd9fb1
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Mar 4, 2024
3d1daf3
Change types
TylerJDev Mar 8, 2024
5999a77
Update storybook example types
TylerJDev Mar 8, 2024
9f77b09
Update types on component
TylerJDev Mar 11, 2024
087ab1f
Add another type
TylerJDev Mar 11, 2024
f4a5021
Update type in `SegmentedControl`
TylerJDev Mar 11, 2024
ba31e40
Add back `li`-only type
TylerJDev Mar 13, 2024
8e2921d
Add onto `onSelect` type
TylerJDev Mar 14, 2024
afa8d9f
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Mar 14, 2024
4b1f2b4
Update more types
TylerJDev Mar 14, 2024
10cd551
Type fixes for `LinkItem`
TylerJDev Mar 14, 2024
65c23c8
Changes from feedback
TylerJDev Mar 18, 2024
70659ed
Change types
TylerJDev Mar 20, 2024
1a9b3e0
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Mar 20, 2024
1f783fa
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Apr 9, 2024
6774f93
Replace `role="list"` with context
TylerJDev Apr 11, 2024
5ed547f
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev May 17, 2024
cf5ecf9
Add feature flag to `ActionList.Item
TylerJDev May 18, 2024
2f13c76
Add back forwardedRef in cases where valid role is true
TylerJDev May 20, 2024
f32f416
Update FF name
TylerJDev May 20, 2024
84f041e
Add lint disable
TylerJDev May 20, 2024
55632b1
Update FF name
TylerJDev May 21, 2024
8bc5c15
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev May 21, 2024
ce70779
Add changeset
TylerJDev May 22, 2024
3e8af88
Remove `list` condition
TylerJDev May 23, 2024
4c8a4de
Rename FF
TylerJDev May 23, 2024
0d076dc
Address feedback
TylerJDev May 29, 2024
d2faa9a
Add feature flag story
TylerJDev May 29, 2024
54eab93
Add new test
TylerJDev May 30, 2024
d1c1d60
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev May 31, 2024
9bbc8a2
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Jun 12, 2024
1ceaa0c
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Jun 13, 2024
d0a6c54
Add feature flag to all stories
TylerJDev Jun 17, 2024
77027ad
Merge remote-tracking branch 'refs/remotes/origin/tylerjdev/action-li…
TylerJDev Jun 17, 2024
0298349
Merge branch 'main' into tylerjdev/action-list-a11y-fixes
TylerJDev Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hot-mayflies-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

(Behind feature flag) ActionList: Utilizes `<button>` inside of `<li>` for interactive items.
24 changes: 24 additions & 0 deletions packages/react/src/ActionList/ActionList.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import {
PeopleIcon,
FileDirectoryIcon,
PlusCircleIcon,
LinkExternalIcon,
} from '@primer/octicons-react'
import {FeatureFlags} from '../FeatureFlags'

export default {
title: 'Components/ActionList/Features',
Expand Down Expand Up @@ -710,3 +712,25 @@ export const GroupWithFilledTitle = () => {
</ActionList>
)
}

export const ActionListWithButtonSemantics = () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can enable the flag in all our stories and see how the changes are working?

I haven't tried it but maybe wrapping the story here with the feature flag component? 🤔

<BaseStyles>
  <FeatureFlags flags={{primer_react_action_list_item_as_button: true}}>
    <Story {...context} />
    {context.globals.colorScheme === 'all' && <p className="theme-name">{theme}</p>}
  </FeatureFlags>
</BaseStyles>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We definitely could! But would we want to keep this on even after we ship this PR, or would it just during this PR?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late response! I was thinking enabling the ff in this PR to make sure the changes are working as expected before releasing it to dotcom. It is like testing it in the small surface area (primer/react) and once we confirm that the changes are good, we can release.

This is only a suggestion though. If you think we can directly release it that is okay too!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added! Should now be enabled for all stories!

return (
<FeatureFlags flags={{primer_react_action_list_item_as_button: true}}>
<ActionList>
<ActionList.Item>Copy link</ActionList.Item>
<ActionList.Item inactiveText="Nothing to quote">Quote reply</ActionList.Item>
<ActionList.Item disabled>Edit comment</ActionList.Item>
<ActionList.Divider />
<ActionList.Item variant="danger">Delete file</ActionList.Item>
<ActionList.LinkItem href="https://github.com/primer/react#readme">
Support
<ActionList.TrailingVisual>
<LinkExternalIcon />
</ActionList.TrailingVisual>
</ActionList.LinkItem>
</ActionList>
</FeatureFlags>
)
}

ActionListWithButtonSemantics.storyName = 'With Button Semantics (Behind feature flag)'
67 changes: 67 additions & 0 deletions packages/react/src/ActionList/ActionList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import theme from '../theme'
import {ActionList} from '.'
import {behavesAsComponent, checkExports} from '../utils/testing'
import {BaseStyles, ThemeProvider, SSRProvider, ActionMenu} from '..'
import {FeatureFlags} from '../FeatureFlags'
broccolinisoup marked this conversation as resolved.
Show resolved Hide resolved

function SimpleActionList(): JSX.Element {
return (
Expand Down Expand Up @@ -378,4 +379,70 @@ describe('ActionList', () => {
const heading = getByText('Group Heading')
expect(list).toHaveAttribute('aria-label', heading.textContent)
})

it('should render ActionList.Item as button when feature flag is enabled', async () => {
const featureFlag = {
primer_react_action_list_item_as_button: true,
}

const {container} = HTMLRender(
<FeatureFlags flags={featureFlag}>
<ActionList>
<ActionList.Item disabled={true}>Item 1</ActionList.Item>
<ActionList.Item>Item 2</ActionList.Item>
</ActionList>
</FeatureFlags>,
)

const button = container.querySelector('button')
expect(button).toHaveTextContent('Item 1')

// Ensure passed prop "disabled" is applied to the button
expect(button).toHaveAttribute('aria-disabled', 'true')

const listItems = container.querySelectorAll('li')
expect(listItems.length).toBe(2)
})

it('should render ActionList.Item as li when feature flag is disabled', async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we want to test some of the listSemantics conditions as well or is it not necessary? For example;

  • Flag is enabled and the action list is a SelectBox -> expected to see the list semantics

Just a suggestion!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a great suggestion! Just added a new test!

const {container} = HTMLRender(
<FeatureFlags flags={{primer_react_action_list_item_as_button: false}}>
<ActionList>
<ActionList.Item>Item 1</ActionList.Item>
<ActionList.Item>Item 2</ActionList.Item>
</ActionList>
</FeatureFlags>,
)

const listitem = container.querySelector('li')
const button = container.querySelector('button')

expect(listitem).toHaveTextContent('Item 1')
expect(listitem).toHaveAttribute('tabindex', '0')
expect(button).toBeNull()

const listItems = container.querySelectorAll('li')
expect(listItems.length).toBe(2)
})

it('should render ActionList.Item as li when feature flag is enabled and has proper aria role', async () => {
const {container} = HTMLRender(
<FeatureFlags flags={{primer_react_action_list_item_as_button: false}}>
<ActionList role="listbox">
<ActionList.Item role="option">Item 1</ActionList.Item>
<ActionList.Item role="option">Item 2</ActionList.Item>
</ActionList>
</FeatureFlags>,
)

const listitem = container.querySelector('li')
const button = container.querySelector('button')

expect(listitem).toHaveTextContent('Item 1')
expect(listitem).toHaveAttribute('tabindex', '0')
expect(button).toBeNull()

const listItems = container.querySelectorAll('li')
expect(listItems.length).toBe(2)
})
})
71 changes: 62 additions & 9 deletions packages/react/src/ActionList/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {getVariantStyles, ItemContext, TEXT_ROW_HEIGHT, ListContext} from './sha
import type {VisualProps} from './Visuals'
import {LeadingVisual, TrailingVisual} from './Visuals'
import {ConditionalWrapper} from '../internal/components/ConditionalWrapper'
import {useFeatureFlag} from '../FeatureFlags'

const LiBox = styled.li<SxProp>(sx)

Expand Down Expand Up @@ -77,6 +78,8 @@ export const Item = React.forwardRef<HTMLLIElement, ActionListItemProps>(
const {container, afterSelect, selectionAttribute, defaultTrailingVisual} =
React.useContext(ActionListContainerContext)

const buttonSemantics = useFeatureFlag('primer_react_action_list_item_as_button')

// Be sure to avoid rendering the container unless there is a default
const wrappedDefaultTrailingVisual = defaultTrailingVisual ? (
<TrailingVisual>{defaultTrailingVisual}</TrailingVisual>
Expand All @@ -95,7 +98,7 @@ export const Item = React.forwardRef<HTMLLIElement, ActionListItemProps>(

const onSelect = React.useCallback(
(
event: React.MouseEvent<HTMLLIElement> | React.KeyboardEvent<HTMLLIElement>,
event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if loosening the type here (which I think is a good way to eliminate the integration issue with dotcom) might have any "tangible" disadvantages? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's definitely not as strict, but it does ease the integration in dotcom. I think with the feature flag it makes it a bit trickier as the type is dependent on the FF being enabled. The issue I had when I was dealing with TS early on was that there are two potential things it could be; a list item or a button. In addition to that, the <li> will always be the parent to anything else within the item, so technically it is an HTMLLIElement, but also a HTMLButtonElement since everything is being applied to the button, not the <li>.

I did try adding both types HTMLLIElement | HTMLButtonElement and I got odd issues in dotcom 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I remember that! Let's see how this type works then and since it is under ff, we can always work on it!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello from the future! This came up during release conductor stuff this week in dotcom, it seems like this change will cause typed handlers to fail since they are using the more specific type.

Since we've switched to a more generic type, these more specific ones will fail 😭

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Josh! This was a tricky situation since the current type HTMLLIElement is technically correct, but also isn't depending on the context. Adding both the LI type and Button type caused a different issue ☹️.

I made the types more generic in dotcom in my integration test PR that should clean up the failures you're seeing. It does involve making the type a bit more generic, but we don't seem to lose out on too much. Let me know what you think though!

// eslint-disable-next-line @typescript-eslint/ban-types
afterSelect?: Function,
) => {
Expand Down Expand Up @@ -146,6 +149,12 @@ export const Item = React.forwardRef<HTMLLIElement, ActionListItemProps>(
},
}

const listItemStyles = {
display: 'flex',
// show between 2 items
':not(:first-of-type)': {'--divider-color': theme?.colors.actionListItem.inlineDivider},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just checking, Is this and the following line conflicting?

':not(:first-of-type)': {'--divider-color': theme?.colors.actionListItem.inlineDivider},

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this was added to fix some styles when <button> was added. @broccolinisoup might have more context here!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember sorry 😢 It has been a while since I pushed that draft PR. We can comment it out and see how the stlyes are different to figure out if it still works fine in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and removed it, and it seems like it was needed for cases where a divider is used and the "button" semantics are applied. I think it's worth keeping for this 🤔

}

const styles = {
position: 'relative',
display: 'flex',
Expand Down Expand Up @@ -231,15 +240,15 @@ export const Item = React.forwardRef<HTMLLIElement, ActionListItemProps>(
}

const clickHandler = React.useCallback(
(event: React.MouseEvent<HTMLLIElement>) => {
(event: React.MouseEvent<HTMLElement>) => {
if (disabled || inactive) return
onSelect(event, afterSelect)
},
[onSelect, disabled, inactive, afterSelect],
)

const keyPressHandler = React.useCallback(
(event: React.KeyboardEvent<HTMLLIElement>) => {
(event: React.KeyboardEvent<HTMLElement>) => {
if (disabled || inactive) return
if ([' ', 'Enter'].includes(event.key)) {
if (event.key === ' ') {
Expand All @@ -259,8 +268,28 @@ export const Item = React.forwardRef<HTMLLIElement, ActionListItemProps>(
const inlineDescriptionId = `${itemId}--inline-description`
const blockDescriptionId = `${itemId}--block-description`
const inactiveWarningId = inactive && !showInactiveIndicator ? `${itemId}--warning-message` : undefined
// Ensures ActionList.Item retains list item semantics if a valid ARIA role is applied, or if item is inactive
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

const listSemantics = listRole === 'listbox' || listRole === 'menu' || inactive || container === 'NavList'

const ButtonItemWrapper = React.forwardRef(({as: Component = 'button', children, ...props}, forwardedRef) => {
return (
<Box
as={Component as React.ElementType}
sx={merge<BetterSystemStyleObject>(styles, sxProp)}
ref={forwardedRef}
{...props}
>
{children}
</Box>
)
}) as PolymorphicForwardRefComponent<React.ElementType, ActionListItemProps>

let DefaultItemWrapper = React.Fragment
if (buttonSemantics) {
DefaultItemWrapper = listSemantics ? React.Fragment : ButtonItemWrapper
}

const ItemWrapper = _PrivateItemWrapper || React.Fragment
const ItemWrapper = _PrivateItemWrapper || DefaultItemWrapper

// only apply aria-selected and aria-checked to selectable items
const selectableRoles = ['menuitemradio', 'menuitemcheckbox', 'option']
Expand All @@ -281,20 +310,44 @@ export const Item = React.forwardRef<HTMLLIElement, ActionListItemProps>(
id: itemId,
}

const containerProps = _PrivateItemWrapper ? {role: itemRole ? 'none' : undefined} : menuItemProps
let containerProps
let wrapperProps

const wrapperProps = _PrivateItemWrapper ? menuItemProps : {}
if (buttonSemantics) {
containerProps = _PrivateItemWrapper
? {role: itemRole ? 'none' : undefined, ...props}
: // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
(listSemantics && {...menuItemProps, ...props, ref: forwardedRef}) || {}

wrapperProps = _PrivateItemWrapper
? menuItemProps
: !listSemantics && {
...menuItemProps,
...props,
styles: merge<BetterSystemStyleObject>(styles, sxProp),
ref: forwardedRef,
}
} else {
containerProps = _PrivateItemWrapper ? {role: itemRole ? 'none' : undefined} : {...menuItemProps, ...props}
wrapperProps = _PrivateItemWrapper ? menuItemProps : {}
}

return (
<ItemContext.Provider
value={{variant, disabled, inactive: Boolean(inactiveText), inlineDescriptionId, blockDescriptionId}}
>
<LiBox
ref={forwardedRef}
sx={merge<BetterSystemStyleObject>(styles, sxProp)}
ref={buttonSemantics || listSemantics ? forwardedRef : null}
sx={
buttonSemantics
? merge<BetterSystemStyleObject>(
listSemantics || _PrivateItemWrapper ? styles : listItemStyles,
listSemantics || _PrivateItemWrapper ? sxProp : {},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listSemantics || _PrivateItemWrapper ? sxProp : {},

I am not sure if I understand this line, sorry. Does that mean we don't allow custom overrides for listItemStyles ? In other words, we don't want to merge listItemStyles with sxProp when listSemantics || _PrivateItemWrapper is false? I hope I am making sense 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries! This is basically saying that, if the ActionList.Item is going to be rendered with list semantics or if it's a private item wrapper, apply the styles and sxProp, as these are the styles that you'd expect when the items are being rendered as list items only. This retains what we have right now in ActionList/Item.tsx.

When it's not listSemantics or _PrivateItemWrapper we need to adjust the styles slightly, as the styles are placed on the <button> instead, meaning that we don't want to have duplicate styles on the <li> and <button>.

Let me know if this still makes sense, or if you have suggestions on how we can make this more readable 🤔

)
: merge<BetterSystemStyleObject>(styles, sxProp)
}
data-variant={variant === 'danger' ? variant : undefined}
{...containerProps}
{...props}
>
<ItemWrapper {...wrapperProps}>
<Selection selected={selected} />
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/ActionList/LinkItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const LinkItem = React.forwardRef(({sx = {}, active, inactiveText, as: Co
inactiveText={inactiveText}
data-inactive={inactiveText ? true : undefined}
_PrivateItemWrapper={({children, onClick, ...rest}) => {
const clickHandler = (event: React.MouseEvent) => {
const clickHandler = (event: React.MouseEvent<HTMLElement>) => {
onClick && onClick(event)
props.onClick && props.onClick(event as React.MouseEvent<HTMLAnchorElement>)
}
Expand Down
6 changes: 3 additions & 3 deletions packages/react/src/ActionList/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type ActionListItemProps = {
* Callback that will trigger both on click selection and keyboard selection.
* This is not called for disabled or inactive items.
*/
onSelect?: (event: React.MouseEvent<HTMLLIElement> | React.KeyboardEvent<HTMLLIElement>) => void
onSelect?: (event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void
/**
* Is the `Item` is currently selected?
*/
Expand Down Expand Up @@ -51,8 +51,8 @@ export type ActionListItemProps = {
} & SxProp

type MenuItemProps = {
onClick?: (event: React.MouseEvent) => void
onKeyPress?: (event: React.KeyboardEvent) => void
onClick?: (event: React.MouseEvent<HTMLElement>) => void
onKeyPress?: (event: React.KeyboardEvent<HTMLElement>) => void
'aria-disabled'?: boolean
tabIndex?: number
'aria-labelledby'?: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ export const MultipleSections = () => {
export const DelayedMenuClose = () => {
const [open, setOpen] = React.useState(false)
const [copyLinkSuccess, setCopyLinkSuccess] = React.useState(false)
const onSelect = (event: React.MouseEvent<HTMLLIElement> | React.KeyboardEvent<HTMLLIElement>) => {
const onSelect = (event: React.MouseEvent | React.KeyboardEvent) => {
event.preventDefault()

setCopyLinkSuccess(true)
Expand Down
9 changes: 8 additions & 1 deletion packages/react/src/NavList/NavList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, {isValidElement} from 'react'
import styled from 'styled-components'
import type {ActionListDividerProps, ActionListLeadingVisualProps, ActionListTrailingVisualProps} from '../ActionList'
import {ActionList} from '../ActionList'
import {ActionListContainerContext} from '../ActionList/ActionListContainerContext'
import Box from '../Box'
import Octicon from '../Octicon'
import type {SxProp} from '../sx'
Expand Down Expand Up @@ -33,7 +34,13 @@ const NavBox = styled.nav<SxProp>(sx)
const Root = React.forwardRef<HTMLElement, NavListProps>(({children, ...props}, ref) => {
return (
<NavBox {...props} ref={ref}>
<ActionList>{children}</ActionList>
<ActionListContainerContext.Provider
value={{
container: 'NavList',
}}
>
<ActionList>{children}</ActionList>
</ActionListContainerContext.Provider>
</NavBox>
)
})
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/SegmentedControl/SegmentedControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ const Root: React.FC<React.PropsWithChildren<SegmentedControlProps>> = ({
<ActionList.Item
key={`segmented-control-action-btn-${index}`}
selected={index === selectedIndex}
onSelect={(event: React.MouseEvent<HTMLLIElement> | React.KeyboardEvent<HTMLLIElement>) => {
onSelect={(event: React.MouseEvent | React.KeyboardEvent) => {
isUncontrolled && setSelectedIndexInternalState(index)
onChange && onChange(index)
child.props.onClick && child.props.onClick(event as React.MouseEvent<HTMLLIElement>)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ const AutocompleteSuggestions = ({
left={triggerCharCoords.left}
ref={overlayRef}
>
<ActionList ref={setList}>
<ActionList ref={setList} role="listbox">
{suggestions === 'loading' ? (
<LoadingIndicator />
) : (
Expand Down
Loading