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 39 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
---

Utilizes `<button>` inside of `ActionList.Item` instead of relying on `<li>` as an interactive item.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

What would be the best way to convey that this feature is feature flagged and not available outside of the flag? 🤔

Copy link
Member

Choose a reason for hiding this comment

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

Curious to learn that as well!

Copy link
Member

Choose a reason for hiding this comment

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

How about:

Suggested change
Utilizes `<button>` inside of `ActionList.Item` instead of relying on `<li>` as an interactive item.
(Behind feature flag) ActionList: Utilizes `<button>` inside of `<li>` for interactive items.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is great, thank you! 😁

42 changes: 42 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,45 @@ 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 {container} = HTMLRender(
<FeatureFlags flags={{primer_react_action_list_item_as_button: true}}>
Copy link
Member

Choose a reason for hiding this comment

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

Because this is tests, I don't think it is super important to memoize or initialise the ff object outside of render but I wonder if we should do it anyway in case if anyone refers here for the practice? 🤔 What do you think?

const ff = {primer_react_action_list_item_as_button: true}
<FeatureFlags flags={ff}>...</FeatureFlags>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea! I've added your suggestion!

<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)
})
})
67 changes: 58 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,24 @@ 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
const validRole = listRole === 'listbox' || listRole === 'menu' || inactive
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 rename the validRole var to be more explicit? I am not sure if it communicates the differentiation. Or maybe it is just me. Or we can maybe add a line of comment to explain why we picked these specific roles and why we are not rendering buttons when these roles are present?

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 fair, I can add both, but let me know if we'd rather go with one or the other!


const ButtonItemWrapper = buttonSemantics
Copy link
Member

Choose a reason for hiding this comment

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

I think we can initialise the ButtonItemWrapper here without worrying about the value of ff and on line 288 we can render the proper wrapper based on our conditions. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, that is fair! Thank you for the suggestion! 😁

? (React.forwardRef(({as: Component = 'button', children, ...props}, forwardedRef) => {
return (
<Box
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason why we didn't use the Button component here? Apologise if we already discussed this before!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

<Box> is used here to provide a non-styled <button>, this also goes for anything that's passed to it via as. We could use a <Button> here, but I'm not sure if it'll provide more than the current implementation, but I may be wrong 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 think you are right, because both render as buttons semantically at the end of the day. Unless we need to utilize Button props, I think we are good with the Box!

as={Component as React.ElementType}
sx={merge<BetterSystemStyleObject>(styles, sxProp)}
ref={forwardedRef}
{...props}
>
{children}
</Box>
)
}) as PolymorphicForwardRefComponent<React.ElementType, ActionListItemProps>)
: React.Fragment

const ItemWrapper = _PrivateItemWrapper || React.Fragment
const ItemWrapper = _PrivateItemWrapper || (validRole || !buttonSemantics ? React.Fragment : ButtonItemWrapper)
Copy link
Member

Choose a reason for hiding this comment

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

I think we also need to add NavList context check into this condition, don't we?

let DefaultItemWrapper = React.Fragment 
if(buttonSemantics) {
  DefaultItemWrapper = validRole || navListContext ? React.Fragment : ButtonItemWrapper
} 

const ItemWrapper = _PrivateItemWrapper || DefautlItemWrapper

I don't mean to re-write the condition, it wasn't straightforward to read when I added the NavList (at least for me 😅) Do it however you feel comfortable 💖

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right! This is easier to read too. Thank you! I adjusted validRole to handle what navListContext would be here.


// only apply aria-selected and aria-checked to selectable items
const selectableRoles = ['menuitemradio', 'menuitemcheckbox', 'option']
Expand All @@ -281,20 +306,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
(validRole && {...menuItemProps, ...props, ref: forwardedRef}) || {}

wrapperProps = _PrivateItemWrapper
? menuItemProps
: !validRole && {
...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 || validRole ? forwardedRef : null}
Copy link
Member

Choose a reason for hiding this comment

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

I think we should have the ref forwardedRef regardless of the condition, shouldn't we? 🤔 Or did I miss understand anything here?

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 switches between the inner <button> and the list item depending on the context. When the <button> is applied, we pass the props and forwardedRef to it, whereas if it's a list item only (i.e. validRole is true), then we provide the forwardedRef to that list item. I did it this way so that the forwardedRef will always be on the thing that you can pass props to.

sx={
buttonSemantics
? merge<BetterSystemStyleObject>(
validRole || _PrivateItemWrapper ? styles : listItemStyles,
validRole || _PrivateItemWrapper ? sxProp : {},
)
: 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
16 changes: 15 additions & 1 deletion packages/react/src/NavList/NavList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ 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'
import sx, {merge} from '../sx'
import {defaultSxProp} from '../utils/defaultSxProp'
import {useId} from '../hooks/useId'
import useIsomorphicLayoutEffect from '../utils/useIsomorphicLayoutEffect'
import {useFeatureFlag} from '../FeatureFlags'

const getSubnavStyles = (depth: number) => {
return {
Expand All @@ -31,9 +33,21 @@ export type NavListProps = {
const NavBox = styled.nav<SxProp>(sx)

const Root = React.forwardRef<HTMLElement, NavListProps>(({children, ...props}, ref) => {
const listSemantics = useFeatureFlag('action_list_item_as_button')

return (
<NavBox {...props} ref={ref}>
<ActionList>{children}</ActionList>
{listSemantics ? (
Copy link
Member

Choose a reason for hiding this comment

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

I think we can use the context provider here regardless of the ff?

<ActionListContainerContext.Provider
value={{
container: 'NavList',
}}
>
<ActionList>{children}</ActionList>
</ActionListContainerContext.Provider>
) : (
<ActionList>{children}</ActionList>
)}
</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