diff --git a/src/components/List/List.tsx b/src/components/List/List.tsx index 6eb9f86b0c..0e029b420c 100644 --- a/src/components/List/List.tsx +++ b/src/components/List/List.tsx @@ -25,9 +25,16 @@ import {block} from '../utils/cn'; import {getUniqId} from '../utils/common'; import {ListLoadingIndicator} from './ListLoadingIndicator'; -import {ListItem, SimpleContainer, defaultRenderItem} from './components'; +import type {VariableSizeListElementTypeProps} from './components'; +import { + ListItem, + SimpleContainer, + createVariableSizeListElementType, + defaultRenderItem, +} from './components'; import {listNavigationIgnoredKeys} from './constants'; import type {ListItemData, ListItemProps, ListProps} from './types'; +import {getElementId} from './utils'; import './List.scss'; @@ -60,8 +67,20 @@ const reorder = (list: T[], startIndex: number, endIndex: num return result; }; -const ListContainer = React.forwardRef((props, ref) => { - return ; +const ListContainer = React.forwardRef< + VariableSizeList, + VariableSizeListProps & VariableSizeListElementTypeProps +>((props, ref) => { + const {role, listId, ...restProps} = props; + + return ( + + ); }); ListContainer.displayName = 'ListContainer'; @@ -139,15 +158,7 @@ export class List extends React.Component, ListState extends React.Component, ListState {this.renderItems()} {items.length === 0 && Boolean(emptyPlaceholder) && ( @@ -362,13 +372,23 @@ export class List extends React.Component, ListState ); } private renderSimpleContainer() { - const {sortable} = this.props; + const {sortable, role = 'list'} = this.props; const items = this.getItemsWithLoading(); if (sortable) { @@ -394,6 +414,8 @@ export class List extends React.Component, ListState {items.map((_item, index) => { return ( @@ -428,6 +450,8 @@ export class List extends React.Component, ListState {items.map((_item, index) => this.renderItem({index, height: this.getItemHeight(index)}), @@ -437,6 +461,7 @@ export class List extends React.Component, ListState extends React.Component, ListState extends React.Component, ListState(item: T) => String(item); function getStyle(provided?: DraggableProvided, style?: React.CSSProperties) { @@ -59,7 +62,7 @@ export class ListItem extends React.Component> { // eslint-disable-next-line jsx-a11y/click-events-have-key-events
extends React.Component> { onClickCapture={item.disabled ? undefined : this.onClickCapture} onMouseEnter={this.onMouseEnter} ref={this.setRef} - id={`${this.props.listId}-item-${this.props.itemIndex}`} + id={getElementId(this.props.listId, this.props.itemIndex)} > {this.renderSortIcon()} {this.renderContent()} diff --git a/src/components/List/components/SimpleContainer.tsx b/src/components/List/components/SimpleContainer.tsx index 8a5ec39134..258c2393e6 100644 --- a/src/components/List/components/SimpleContainer.tsx +++ b/src/components/List/components/SimpleContainer.tsx @@ -10,6 +10,8 @@ export type SimpleContainerProps = React.PropsWithChildren<{ itemCount: number; provided?: DroppableProvided; onScrollToItem?: (node: HTMLElement) => boolean; + role: React.AriaRole; + id: string; }>; type RefsList = Record>; @@ -54,7 +56,11 @@ export class SimpleContainer extends React.Component{children}
; + return ( +
+ {children} +
+ ); } scrollToItem(index: number) { diff --git a/src/components/List/components/VariableSizeListElementType.tsx b/src/components/List/components/VariableSizeListElementType.tsx new file mode 100644 index 0000000000..5852e61c85 --- /dev/null +++ b/src/components/List/components/VariableSizeListElementType.tsx @@ -0,0 +1,29 @@ +'use client'; + +import * as React from 'react'; + +export interface VariableSizeListElementTypeProps { + role: string; + listId: string; +} + +export const VariableSizeListElementType = React.forwardRef< + HTMLDivElement, + VariableSizeListElementTypeProps & React.HTMLAttributes +>(({style, role, listId, ...rest}, ref) => ( +
+)); + +VariableSizeListElementType.displayName = 'VariableSizeListElementType'; + +export const createVariableSizeListElementType = (role: string, listId: string) => { + const Component = React.forwardRef( + (props, ref) => ( + + ), + ); + + Component.displayName = 'VariableSizeListElementType'; + + return Component; +}; diff --git a/src/components/List/components/index.ts b/src/components/List/components/index.ts index ec1e24eeed..d7885e11e6 100644 --- a/src/components/List/components/index.ts +++ b/src/components/List/components/index.ts @@ -1,2 +1,3 @@ export * from './ListItem'; export * from './SimpleContainer'; +export * from './VariableSizeListElementType'; diff --git a/src/components/List/utils.ts b/src/components/List/utils.ts new file mode 100644 index 0000000000..854fc2a1d5 --- /dev/null +++ b/src/components/List/utils.ts @@ -0,0 +1,7 @@ +export function getElementId(id?: string, activeItem?: number) { + if (!id || !activeItem) { + return undefined; + } + + return `${id}-item-${activeItem}`; +}