Skip to content

Commit 016ac56

Browse files
committed
revert list item button link
1 parent c8c0eae commit 016ac56

File tree

3 files changed

+50
-21
lines changed

3 files changed

+50
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- Import types and constants from `@lumx/core` and re-export
1717
- Import `className` utilities from `@lumx/core`
1818
- Migrate tests to `vitest`
19-
- Uniformize link and button handling in `Link`, `Button`, `SideNavigationItem`, `Thumbnail`, `NavigationItem`
20-
and `ListItem`.
19+
- Uniformize link and button handling in `Link`, `Button`, `SideNavigationItem`, `Thumbnail` and `NavigationItem`.
2120
- Render disabled link as link instead of disabled buttons.
2221

2322
## [3.19.0][] - 2025-11-07

packages/lumx-react/src/components/list/ListItem.tsx

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import React, { ReactNode, Ref, SyntheticEvent } from 'react';
1+
import React, { ReactNode, Ref, SyntheticEvent, useMemo } from 'react';
22

33
import classNames from 'classnames';
44
import isEmpty from 'lodash/isEmpty';
55

66
import { ListProps, Size } from '@lumx/react';
77
import { GenericProps } from '@lumx/react/utils/type';
8+
import { onEnterPressed, onButtonPressed } from '@lumx/core/js/utils';
89
import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
10+
import { renderLink } from '@lumx/react/utils/react/renderLink';
911
import { forwardRef } from '@lumx/react/utils/react/forwardRef';
1012
import { useDisableStateProps } from '@lumx/react/utils/disabled/useDisableStateProps';
1113
import { HasAriaDisabled } from '@lumx/react/utils/type/HasAriaDisabled';
12-
import { RawClickable } from '@lumx/react/utils/react/RawClickable';
1314

1415
export type ListItemSize = Extract<Size, 'tiny' | 'regular' | 'big' | 'huge'>;
1516

@@ -93,6 +94,13 @@ export const ListItem = forwardRef<ListItemProps, HTMLLIElement>((props, ref) =>
9394
...forwardedProps
9495
} = otherProps;
9596

97+
const role = linkAs || linkProps.href ? 'link' : 'button';
98+
const onKeyDown = useMemo(() => {
99+
if (onItemSelected && role === 'link') return onEnterPressed(onItemSelected as any);
100+
if (onItemSelected && role === 'button') return onButtonPressed(onItemSelected as any);
101+
return undefined;
102+
}, [role, onItemSelected]);
103+
96104
const content = (
97105
<>
98106
{before && <div className={`${CLASSNAME}__before`}>{before}</div>}
@@ -115,23 +123,28 @@ export const ListItem = forwardRef<ListItemProps, HTMLLIElement>((props, ref) =>
115123
>
116124
{isClickable({ linkProps, onItemSelected }) ? (
117125
/* Clickable list item */
118-
<RawClickable
119-
as={linkAs || (linkProps.href ? 'a' : 'button')}
120-
{...linkProps}
121-
{...disabledStateProps}
122-
className={classNames(
123-
handleBasicClasses({
124-
prefix: `${CLASSNAME}__link`,
125-
isHighlighted,
126-
isSelected,
127-
isDisabled: isAnyDisabled,
128-
}),
129-
)}
130-
onClick={onItemSelected}
131-
ref={linkRef}
132-
>
133-
{content}
134-
</RawClickable>
126+
renderLink(
127+
{
128+
linkAs,
129+
tabIndex: !disabledStateProps.disabled ? 0 : undefined,
130+
role,
131+
'aria-disabled': isAnyDisabled,
132+
...linkProps,
133+
href: isAnyDisabled ? undefined : linkProps.href,
134+
className: classNames(
135+
handleBasicClasses({
136+
prefix: `${CLASSNAME}__link`,
137+
isHighlighted,
138+
isSelected,
139+
isDisabled: isAnyDisabled,
140+
}),
141+
),
142+
onClick: isAnyDisabled ? undefined : onItemSelected,
143+
onKeyDown: isAnyDisabled ? undefined : onKeyDown,
144+
ref: linkRef,
145+
},
146+
content,
147+
)
135148
) : (
136149
/* Non clickable list item */
137150
<div className={`${CLASSNAME}__wrapper`}>{content}</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, { ReactElement, ReactNode } from 'react';
2+
3+
interface Props {
4+
linkAs?: any;
5+
}
6+
7+
/**
8+
* Render link with default <a> HTML component or a custom one provided by `linkAs`.
9+
*
10+
* Can be used to inject the `Link` component from `react-router` and provide better a11y on LumX components.
11+
*
12+
* @param linkAs Custom link component.
13+
* @param children Link children.
14+
* @return A link.
15+
*/
16+
export const renderLink = <P extends Props>({ linkAs, ...forwardedProps }: P, ...children: ReactNode[]): ReactElement =>
17+
React.createElement(linkAs || 'a', forwardedProps, ...children);

0 commit comments

Comments
 (0)