@amboss/design-system 3.42.2 → 3.42.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
1
  import React from "react";
2
2
  import type { EntityListProps } from "./types";
3
- export declare function BaseEntityList({ data, size, onClick, isSelectable, selectedIds, onSelectionChange, onSelectionToggle, renderRightContent, getLeftIconProps, hideBorder, filterFn, isVirtualized, maxHeight, ariaAttributes: deprecatedAriaAttributes, slotProps, role: roleProp, "data-e2e-test-id": dataE2eTestId, ...ariaAttributes }: EntityListProps): React.ReactElement;
3
+ export declare function BaseEntityList({ data, size, onClick, focusOnMount, isSelectable, selectedIds, onSelectionChange, onSelectionToggle, renderRightContent, getLeftIconProps, hideBorder, filterFn, isVirtualized, maxHeight, ariaAttributes: deprecatedAriaAttributes, slotProps, role: roleProp, "data-e2e-test-id": dataE2eTestId, ...ariaAttributes }: EntityListProps): React.ReactElement;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"BaseEntityList",{enumerable:!0,get:function(){return BaseEntityList}});const _react=/*#__PURE__*/require("@swc/helpers/_/_interop_require_wildcard")._(require("react")),_styledcomponents=require("./styled-components"),_useKeyboard=require("../../shared/useKeyboard"),_Icon=require("../Icon/Icon"),_EntityListItem=require("./EntityListItem"),_VirtualizedEntityList=require("./VirtualizedEntityList"),_useFocusByIndex=require("./useFocusByIndex"),ITEM_ROLE_MAP={list:"listitem",listbox:"option",menu:"menuitem"};function BaseEntityList({data,size="m",onClick,isSelectable,selectedIds,onSelectionChange,onSelectionToggle,renderRightContent,getLeftIconProps,hideBorder,filterFn,isVirtualized,maxHeight,ariaAttributes:deprecatedAriaAttributes,slotProps,role:roleProp,"data-e2e-test-id":dataE2eTestId,...ariaAttributes}){let rootRole,{itemRole,...rootAriaProps}=(rootRole=roleProp??"list",isSelectable&&(rootRole="listbox"),{role:rootRole,itemRole:ITEM_ROLE_MAP[rootRole],"aria-multiselectable":"listbox"===rootRole&&!!isSelectable||void 0}),ariaLabelExpand=slotProps?.toggle?.["aria-label-expand"]??deprecatedAriaAttributes?.ariaLabelExpand,ariaLabelCollapse=slotProps?.toggle?.["aria-label-collapse"]??deprecatedAriaAttributes?.ariaLabelCollapse,dataShown=(0,_react.useMemo)(()=>data.length&&filterFn?data.filter(filterFn):data,[data,filterFn]),selectedIdsSet=(0,_react.useMemo)(()=>new Set(selectedIds),[selectedIds]),listRef=(0,_react.useRef)(null),focusableItems=(0,_react.useMemo)(()=>dataShown.map(item=>({id:item.id,isDisabled:!!item.isDisabled})),[dataShown]),initialActiveIndex=(0,_react.useMemo)(()=>{let index=dataShown.findIndex(item=>item.isActive);return -1!==index?index:0},[dataShown]),{moveFocus,focusedIndex:selectedIndex}=(0,_useFocusByIndex.useFocusByIndex)({containerRef:listRef,nodeSelector:"data-list-item",data:focusableItems,preventScroll:isVirtualized,initialIndex:initialActiveIndex});(0,_useKeyboard.useKeyboard)({ArrowDown:()=>{moveFocus(1)},ArrowUp:()=>{moveFocus(-1)}},listRef,isSelectable||!!onClick);let handleOnClick=(0,_react.useCallback)(item=>{let{id}=item;if(isSelectable){let willBeSelected=!selectedIdsSet.has(id),newSelectedIdsSet=new Set(selectedIdsSet);willBeSelected?newSelectedIdsSet.add(id):newSelectedIdsSet.delete(id),onSelectionToggle?.(id,willBeSelected),onSelectionChange?.(Array.from(newSelectedIdsSet))}onClick?.(item)},[selectedIdsSet,onSelectionChange,onSelectionToggle,onClick,isSelectable]),renderEntityItem=index=>{let tabIndex,item=dataShown[index];if(!item)return null;let isLastItem=index===dataShown.length-1,isSelected=selectedIdsSet.has(item.id);return(isSelectable||onClick)&&(tabIndex=item.isDisabled||index!==selectedIndex&&(0!==index||selectedIndex)?-1:0),_react.default.createElement(_EntityListItem.EntityListItem,{key:item.id,"data-list-item":index,"aria-label":item["aria-label"]||item.label,size:size,hideBorder:hideBorder||isLastItem,isActive:item.isActive,isDisabled:item.isDisabled,isClickable:!!(onClick||selectedIds),isSelected:isSelectable?isSelected:void 0,role:itemRole,description:item.description,onSpaceEnterPress:()=>handleOnClick(item),tabIndex:tabIndex,ariaLabelExpand:ariaLabelExpand,ariaLabelCollapse:ariaLabelCollapse,onClick:e=>{e.target.closest("label")||handleOnClick(item)},checkboxProps:isSelectable&&{name:"list-checkbox",size:"s",checked:isSelected,onChange:()=>handleOnClick(item)},renderLabel:()=>item.label,renderLeft:getLeftIconProps?({textSize})=>_react.default.createElement(_Icon.Icon,{...getLeftIconProps(item),size:textSize}):null,renderRight:renderRightProps=>renderRightContent?renderRightContent({...renderRightProps,...item}):void 0})};return _react.default.createElement("div",{ref:listRef},isVirtualized&&maxHeight?_react.default.createElement(_VirtualizedEntityList.VirtualizedEntityList,{id:dataE2eTestId,maxHeight:maxHeight,size:size,dataShown:dataShown,selectedIndex:selectedIndex,itemTemplate:renderEntityItem,"data-e2e-test-id":dataE2eTestId,...rootAriaProps,...ariaAttributes}):_react.default.createElement(_styledcomponents.StyledList,{size:size,"data-e2e-test-id":dataE2eTestId,"data-ds-id":"EntityList",...rootAriaProps,...ariaAttributes},dataShown.map((_item,i)=>renderEntityItem(i))))}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"BaseEntityList",{enumerable:!0,get:function(){return BaseEntityList}});const _react=/*#__PURE__*/require("@swc/helpers/_/_interop_require_wildcard")._(require("react")),_styledcomponents=require("./styled-components"),_useKeyboard=require("../../shared/useKeyboard"),_Icon=require("../Icon/Icon"),_EntityListItem=require("./EntityListItem"),_VirtualizedEntityList=require("./VirtualizedEntityList"),_useFocusByIndex=require("./useFocusByIndex"),ITEM_ROLE_MAP={list:"listitem",listbox:"option",menu:"menuitem"};function BaseEntityList({data,size="m",onClick,focusOnMount,isSelectable,selectedIds,onSelectionChange,onSelectionToggle,renderRightContent,getLeftIconProps,hideBorder,filterFn,isVirtualized,maxHeight,ariaAttributes:deprecatedAriaAttributes,slotProps,role:roleProp,"data-e2e-test-id":dataE2eTestId,...ariaAttributes}){let rootRole,{itemRole,...rootAriaProps}=(rootRole=roleProp??"list",isSelectable&&(rootRole="listbox"),{role:rootRole,itemRole:ITEM_ROLE_MAP[rootRole],"aria-multiselectable":"listbox"===rootRole&&!!isSelectable||void 0}),ariaLabelExpand=slotProps?.toggle?.["aria-label-expand"]??deprecatedAriaAttributes?.ariaLabelExpand,ariaLabelCollapse=slotProps?.toggle?.["aria-label-collapse"]??deprecatedAriaAttributes?.ariaLabelCollapse,dataShown=(0,_react.useMemo)(()=>data.length&&filterFn?data.filter(filterFn):data,[data,filterFn]),selectedIdsSet=(0,_react.useMemo)(()=>new Set(selectedIds),[selectedIds]),listRef=(0,_react.useRef)(null),focusableItems=(0,_react.useMemo)(()=>dataShown.map(item=>({id:item.id,isDisabled:!!item.isDisabled})),[dataShown]),initialActiveIndex=(0,_react.useMemo)(()=>{let index=dataShown.findIndex(item=>item.isActive);return -1!==index?index:0},[dataShown]),{moveFocus,focusItemAtIndex,focusedIndex:selectedIndex}=(0,_useFocusByIndex.useFocusByIndex)({containerRef:listRef,nodeSelector:"data-list-item",data:focusableItems,preventScroll:isVirtualized,initialIndex:initialActiveIndex});(0,_react.useEffect)(()=>{focusOnMount&&focusItemAtIndex(selectedIndex)},[]),(0,_useKeyboard.useKeyboard)({ArrowDown:()=>{moveFocus(1)},ArrowUp:()=>{moveFocus(-1)}},listRef,isSelectable||!!onClick);let handleOnClick=(0,_react.useCallback)(item=>{let{id}=item;if(isSelectable){let willBeSelected=!selectedIdsSet.has(id),newSelectedIdsSet=new Set(selectedIdsSet);willBeSelected?newSelectedIdsSet.add(id):newSelectedIdsSet.delete(id),onSelectionToggle?.(id,willBeSelected),onSelectionChange?.(Array.from(newSelectedIdsSet))}onClick?.(item)},[selectedIdsSet,onSelectionChange,onSelectionToggle,onClick,isSelectable]),renderEntityItem=index=>{let tabIndex,item=dataShown[index];if(!item)return null;let isLastItem=index===dataShown.length-1,isSelected=selectedIdsSet.has(item.id);if(isSelectable||onClick){let defaultTabIndex=0===index&&!selectedIndex;tabIndex=!item.isDisabled&&(index===selectedIndex||defaultTabIndex)?0:-1}return _react.default.createElement(_EntityListItem.EntityListItem,{key:item.id,"data-list-item":index,"aria-label":item["aria-label"]||item.label,size:size,hideBorder:hideBorder||isLastItem,isActive:item.isActive,isDisabled:item.isDisabled,isClickable:!!(onClick||selectedIds),isSelected:isSelectable?isSelected:void 0,role:itemRole,description:item.description,onSpaceEnterPress:()=>handleOnClick(item),tabIndex:tabIndex,ariaLabelExpand:ariaLabelExpand,ariaLabelCollapse:ariaLabelCollapse,onClick:e=>{e.target.closest("label")||handleOnClick(item)},checkboxProps:isSelectable&&{name:"list-checkbox",size:"s",checked:isSelected,onChange:()=>handleOnClick(item)},renderLabel:()=>item.label,renderLeft:getLeftIconProps?({textSize})=>_react.default.createElement(_Icon.Icon,{...getLeftIconProps(item),size:textSize}):null,renderRight:renderRightProps=>renderRightContent?renderRightContent({...renderRightProps,...item}):void 0})};return _react.default.createElement("div",{ref:listRef},isVirtualized&&maxHeight?_react.default.createElement(_VirtualizedEntityList.VirtualizedEntityList,{id:dataE2eTestId,maxHeight:maxHeight,size:size,dataShown:dataShown,selectedIndex:selectedIndex,itemTemplate:renderEntityItem,"data-e2e-test-id":dataE2eTestId,...rootAriaProps,...ariaAttributes}):_react.default.createElement(_styledcomponents.StyledList,{size:size,"data-e2e-test-id":dataE2eTestId,"data-ds-id":"EntityList",...rootAriaProps,...ariaAttributes},dataShown.map((_item,i)=>renderEntityItem(i))))}
@@ -44,6 +44,7 @@ export type BaseEntityListProps = {
44
44
  * @param ListNode[].customProp - Your data in order to use it custom "render" functions
45
45
  */
46
46
  data: ListNode[];
47
+ focusOnMount?: boolean;
47
48
  size?: ListSize;
48
49
  selectedIds?: string[];
49
50
  /** Allows selection of items with checkboxes. */
@@ -6,6 +6,7 @@ type FocusableItem = {
6
6
  type UseFocusByIndexResult = {
7
7
  moveFocus: (offset: number) => void;
8
8
  focusedIndex: number;
9
+ focusItemAtIndex: (index: number) => void;
9
10
  };
10
11
  type UseFocusByIndexOptions = {
11
12
  data: FocusableItem[];
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"useFocusByIndex",{enumerable:!0,get:function(){return useFocusByIndex}});const _react=require("react"),getNextEnabledIndex=(items,startIndex,direction)=>{let index=startIndex+direction;for(;index>=0&&index<items.length;){if(!items[index]?.isDisabled)return index;index+=direction}return -1},getClosestEnabledIndex=(items,currentIndex)=>{if(!items.length)return -1;if(currentIndex>=0&&currentIndex<items.length&&!items[currentIndex]?.isDisabled)return currentIndex;let forward=getNextEnabledIndex(items,currentIndex,1);return -1!==forward?forward:getNextEnabledIndex(items,currentIndex,-1)},useFocusByIndex=({data,containerRef,nodeSelector,preventScroll=!1,initialIndex=0})=>{let[focusedIndex,setFocusedIndex]=(0,_react.useState)(()=>getClosestEnabledIndex(data,initialIndex)),focusedIndexRef=(0,_react.useRef)(focusedIndex);(0,_react.useEffect)(()=>{focusedIndexRef.current=focusedIndex},[focusedIndex]);let focusItemAtIndex=(0,_react.useCallback)(index=>{if(-1===index)return;let container=containerRef.current;if(!container)return;let element=container.querySelector(`[${nodeSelector}="${index}"]`);!element||data[index]?.isDisabled||(element.focus({preventScroll}),setFocusedIndex(index))},[containerRef,data,nodeSelector,preventScroll]);return(0,_react.useEffect)(()=>{let container=containerRef.current;if(!container)return;let handleContainerFocus=()=>{let nextIndex=getClosestEnabledIndex(data,focusedIndexRef.current);-1!==nextIndex&&focusItemAtIndex(nextIndex)},handleFocusIn=event=>{let target=event.target;if(!container.contains(target))return;let attributeValue=target.getAttribute(nodeSelector);if(null===attributeValue)return;let parsedIndex=Number(attributeValue);Number.isNaN(parsedIndex)||data[parsedIndex]?.isDisabled||setFocusedIndex(parsedIndex)};return container.addEventListener("focus",handleContainerFocus),container.addEventListener("focusin",handleFocusIn),()=>{container.removeEventListener("focus",handleContainerFocus),container.removeEventListener("focusin",handleFocusIn)}},[containerRef,data,focusItemAtIndex,nodeSelector]),{moveFocus:(0,_react.useCallback)(offset=>{let nextIndex;if(!data.length)return;let direction=offset>0?1:-1,remainingSteps=Math.abs(offset);for(nextIndex=-1===focusedIndex?direction>0?-1:data.length:focusedIndex;remainingSteps>0;){let candidate=getNextEnabledIndex(data,nextIndex,direction);if(-1===candidate)return;nextIndex=candidate,remainingSteps-=1}nextIndex!==focusedIndex&&focusItemAtIndex(nextIndex)},[data,focusItemAtIndex,focusedIndex]),focusedIndex}};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"useFocusByIndex",{enumerable:!0,get:function(){return useFocusByIndex}});const _react=require("react"),getNextEnabledIndex=(items,startIndex,direction)=>{let index=startIndex+direction;for(;index>=0&&index<items.length;){if(!items[index]?.isDisabled)return index;index+=direction}return -1},getClosestEnabledIndex=(items,currentIndex)=>{if(!items.length)return -1;if(currentIndex>=0&&currentIndex<items.length&&!items[currentIndex]?.isDisabled)return currentIndex;let forward=getNextEnabledIndex(items,currentIndex,1);return -1!==forward?forward:getNextEnabledIndex(items,currentIndex,-1)},useFocusByIndex=({data,containerRef,nodeSelector,preventScroll=!1,initialIndex=0})=>{let[focusedIndex,setFocusedIndex]=(0,_react.useState)(()=>getClosestEnabledIndex(data,initialIndex)),focusedIndexRef=(0,_react.useRef)(focusedIndex);(0,_react.useEffect)(()=>{focusedIndexRef.current=focusedIndex},[focusedIndex]);let focusItemAtIndex=(0,_react.useCallback)(index=>{if(-1===index)return;let container=containerRef.current;if(!container)return;let element=container.querySelector(`[${nodeSelector}="${index}"]`);!element||data[index]?.isDisabled||(element.focus({preventScroll}),setFocusedIndex(index))},[containerRef,data,nodeSelector,preventScroll]);return(0,_react.useEffect)(()=>{let container=containerRef.current;if(!container)return;let handleContainerFocus=()=>{let nextIndex=getClosestEnabledIndex(data,focusedIndexRef.current);-1!==nextIndex&&focusItemAtIndex(nextIndex)},handleFocusIn=event=>{let target=event.target;if(!container.contains(target))return;let attributeValue=target.getAttribute(nodeSelector);if(null===attributeValue)return;let parsedIndex=Number(attributeValue);Number.isNaN(parsedIndex)||data[parsedIndex]?.isDisabled||setFocusedIndex(parsedIndex)};return container.addEventListener("focus",handleContainerFocus),container.addEventListener("focusin",handleFocusIn),()=>{container.removeEventListener("focus",handleContainerFocus),container.removeEventListener("focusin",handleFocusIn)}},[containerRef,data,focusItemAtIndex,nodeSelector]),{moveFocus:(0,_react.useCallback)(offset=>{let nextIndex;if(!data.length)return;let direction=offset>0?1:-1,remainingSteps=Math.abs(offset);for(nextIndex=-1===focusedIndex?direction>0?-1:data.length:focusedIndex;remainingSteps>0;){let candidate=getNextEnabledIndex(data,nextIndex,direction);if(-1===candidate)return;nextIndex=candidate,remainingSteps-=1}nextIndex!==focusedIndex&&focusItemAtIndex(nextIndex)},[data,focusItemAtIndex,focusedIndex]),focusedIndex,focusItemAtIndex}};
@@ -1,3 +1,3 @@
1
1
  import React from "react";
2
2
  import type { EntityListProps } from "./types";
3
- export declare function BaseEntityList({ data, size, onClick, isSelectable, selectedIds, onSelectionChange, onSelectionToggle, renderRightContent, getLeftIconProps, hideBorder, filterFn, isVirtualized, maxHeight, ariaAttributes: deprecatedAriaAttributes, slotProps, role: roleProp, "data-e2e-test-id": dataE2eTestId, ...ariaAttributes }: EntityListProps): React.ReactElement;
3
+ export declare function BaseEntityList({ data, size, onClick, focusOnMount, isSelectable, selectedIds, onSelectionChange, onSelectionToggle, renderRightContent, getLeftIconProps, hideBorder, filterFn, isVirtualized, maxHeight, ariaAttributes: deprecatedAriaAttributes, slotProps, role: roleProp, "data-e2e-test-id": dataE2eTestId, ...ariaAttributes }: EntityListProps): React.ReactElement;
@@ -1 +1 @@
1
- import React,{useRef,useMemo,useCallback}from"react";import{StyledList}from"./styled-components";import{useKeyboard}from"../../shared/useKeyboard";import{Icon}from"../Icon/Icon";import{EntityListItem}from"./EntityListItem";import{VirtualizedEntityList}from"./VirtualizedEntityList";import{useFocusByIndex}from"./useFocusByIndex";let ITEM_ROLE_MAP={list:"listitem",listbox:"option",menu:"menuitem"};export function BaseEntityList({data,size="m",onClick,isSelectable,selectedIds,onSelectionChange,onSelectionToggle,renderRightContent,getLeftIconProps,hideBorder,filterFn,isVirtualized,maxHeight,ariaAttributes:deprecatedAriaAttributes,slotProps,role:roleProp,"data-e2e-test-id":dataE2eTestId,...ariaAttributes}){let rootRole,{itemRole,...rootAriaProps}=(rootRole=roleProp??"list",isSelectable&&(rootRole="listbox"),{role:rootRole,itemRole:ITEM_ROLE_MAP[rootRole],"aria-multiselectable":"listbox"===rootRole&&!!isSelectable||void 0}),ariaLabelExpand=slotProps?.toggle?.["aria-label-expand"]??deprecatedAriaAttributes?.ariaLabelExpand,ariaLabelCollapse=slotProps?.toggle?.["aria-label-collapse"]??deprecatedAriaAttributes?.ariaLabelCollapse,dataShown=useMemo(()=>data.length&&filterFn?data.filter(filterFn):data,[data,filterFn]),selectedIdsSet=useMemo(()=>new Set(selectedIds),[selectedIds]),listRef=useRef(null),{moveFocus,focusedIndex:selectedIndex}=useFocusByIndex({containerRef:listRef,nodeSelector:"data-list-item",data:useMemo(()=>dataShown.map(item=>({id:item.id,isDisabled:!!item.isDisabled})),[dataShown]),preventScroll:isVirtualized,initialIndex:useMemo(()=>{let index=dataShown.findIndex(item=>item.isActive);return -1!==index?index:0},[dataShown])});useKeyboard({ArrowDown:()=>{moveFocus(1)},ArrowUp:()=>{moveFocus(-1)}},listRef,isSelectable||!!onClick);let handleOnClick=useCallback(item=>{let{id}=item;if(isSelectable){let willBeSelected=!selectedIdsSet.has(id),newSelectedIdsSet=new Set(selectedIdsSet);willBeSelected?newSelectedIdsSet.add(id):newSelectedIdsSet.delete(id),onSelectionToggle?.(id,willBeSelected),onSelectionChange?.(Array.from(newSelectedIdsSet))}onClick?.(item)},[selectedIdsSet,onSelectionChange,onSelectionToggle,onClick,isSelectable]),renderEntityItem=index=>{let tabIndex,item=dataShown[index];if(!item)return null;let isLastItem=index===dataShown.length-1,isSelected=selectedIdsSet.has(item.id);return(isSelectable||onClick)&&(tabIndex=item.isDisabled||index!==selectedIndex&&(0!==index||selectedIndex)?-1:0),React.createElement(EntityListItem,{key:item.id,"data-list-item":index,"aria-label":item["aria-label"]||item.label,size:size,hideBorder:hideBorder||isLastItem,isActive:item.isActive,isDisabled:item.isDisabled,isClickable:!!(onClick||selectedIds),isSelected:isSelectable?isSelected:void 0,role:itemRole,description:item.description,onSpaceEnterPress:()=>handleOnClick(item),tabIndex:tabIndex,ariaLabelExpand:ariaLabelExpand,ariaLabelCollapse:ariaLabelCollapse,onClick:e=>{e.target.closest("label")||handleOnClick(item)},checkboxProps:isSelectable&&{name:"list-checkbox",size:"s",checked:isSelected,onChange:()=>handleOnClick(item)},renderLabel:()=>item.label,renderLeft:getLeftIconProps?({textSize})=>React.createElement(Icon,{...getLeftIconProps(item),size:textSize}):null,renderRight:renderRightProps=>renderRightContent?renderRightContent({...renderRightProps,...item}):void 0})};return React.createElement("div",{ref:listRef},isVirtualized&&maxHeight?React.createElement(VirtualizedEntityList,{id:dataE2eTestId,maxHeight:maxHeight,size:size,dataShown:dataShown,selectedIndex:selectedIndex,itemTemplate:renderEntityItem,"data-e2e-test-id":dataE2eTestId,...rootAriaProps,...ariaAttributes}):React.createElement(StyledList,{size:size,"data-e2e-test-id":dataE2eTestId,"data-ds-id":"EntityList",...rootAriaProps,...ariaAttributes},dataShown.map((_item,i)=>renderEntityItem(i))))}
1
+ import React,{useEffect,useRef,useMemo,useCallback}from"react";import{StyledList}from"./styled-components";import{useKeyboard}from"../../shared/useKeyboard";import{Icon}from"../Icon/Icon";import{EntityListItem}from"./EntityListItem";import{VirtualizedEntityList}from"./VirtualizedEntityList";import{useFocusByIndex}from"./useFocusByIndex";let ITEM_ROLE_MAP={list:"listitem",listbox:"option",menu:"menuitem"};export function BaseEntityList({data,size="m",onClick,focusOnMount,isSelectable,selectedIds,onSelectionChange,onSelectionToggle,renderRightContent,getLeftIconProps,hideBorder,filterFn,isVirtualized,maxHeight,ariaAttributes:deprecatedAriaAttributes,slotProps,role:roleProp,"data-e2e-test-id":dataE2eTestId,...ariaAttributes}){let rootRole,{itemRole,...rootAriaProps}=(rootRole=roleProp??"list",isSelectable&&(rootRole="listbox"),{role:rootRole,itemRole:ITEM_ROLE_MAP[rootRole],"aria-multiselectable":"listbox"===rootRole&&!!isSelectable||void 0}),ariaLabelExpand=slotProps?.toggle?.["aria-label-expand"]??deprecatedAriaAttributes?.ariaLabelExpand,ariaLabelCollapse=slotProps?.toggle?.["aria-label-collapse"]??deprecatedAriaAttributes?.ariaLabelCollapse,dataShown=useMemo(()=>data.length&&filterFn?data.filter(filterFn):data,[data,filterFn]),selectedIdsSet=useMemo(()=>new Set(selectedIds),[selectedIds]),listRef=useRef(null),{moveFocus,focusItemAtIndex,focusedIndex:selectedIndex}=useFocusByIndex({containerRef:listRef,nodeSelector:"data-list-item",data:useMemo(()=>dataShown.map(item=>({id:item.id,isDisabled:!!item.isDisabled})),[dataShown]),preventScroll:isVirtualized,initialIndex:useMemo(()=>{let index=dataShown.findIndex(item=>item.isActive);return -1!==index?index:0},[dataShown])});useEffect(()=>{focusOnMount&&focusItemAtIndex(selectedIndex)},[]),useKeyboard({ArrowDown:()=>{moveFocus(1)},ArrowUp:()=>{moveFocus(-1)}},listRef,isSelectable||!!onClick);let handleOnClick=useCallback(item=>{let{id}=item;if(isSelectable){let willBeSelected=!selectedIdsSet.has(id),newSelectedIdsSet=new Set(selectedIdsSet);willBeSelected?newSelectedIdsSet.add(id):newSelectedIdsSet.delete(id),onSelectionToggle?.(id,willBeSelected),onSelectionChange?.(Array.from(newSelectedIdsSet))}onClick?.(item)},[selectedIdsSet,onSelectionChange,onSelectionToggle,onClick,isSelectable]),renderEntityItem=index=>{let tabIndex,item=dataShown[index];if(!item)return null;let isLastItem=index===dataShown.length-1,isSelected=selectedIdsSet.has(item.id);if(isSelectable||onClick){let defaultTabIndex=0===index&&!selectedIndex;tabIndex=!item.isDisabled&&(index===selectedIndex||defaultTabIndex)?0:-1}return React.createElement(EntityListItem,{key:item.id,"data-list-item":index,"aria-label":item["aria-label"]||item.label,size:size,hideBorder:hideBorder||isLastItem,isActive:item.isActive,isDisabled:item.isDisabled,isClickable:!!(onClick||selectedIds),isSelected:isSelectable?isSelected:void 0,role:itemRole,description:item.description,onSpaceEnterPress:()=>handleOnClick(item),tabIndex:tabIndex,ariaLabelExpand:ariaLabelExpand,ariaLabelCollapse:ariaLabelCollapse,onClick:e=>{e.target.closest("label")||handleOnClick(item)},checkboxProps:isSelectable&&{name:"list-checkbox",size:"s",checked:isSelected,onChange:()=>handleOnClick(item)},renderLabel:()=>item.label,renderLeft:getLeftIconProps?({textSize})=>React.createElement(Icon,{...getLeftIconProps(item),size:textSize}):null,renderRight:renderRightProps=>renderRightContent?renderRightContent({...renderRightProps,...item}):void 0})};return React.createElement("div",{ref:listRef},isVirtualized&&maxHeight?React.createElement(VirtualizedEntityList,{id:dataE2eTestId,maxHeight:maxHeight,size:size,dataShown:dataShown,selectedIndex:selectedIndex,itemTemplate:renderEntityItem,"data-e2e-test-id":dataE2eTestId,...rootAriaProps,...ariaAttributes}):React.createElement(StyledList,{size:size,"data-e2e-test-id":dataE2eTestId,"data-ds-id":"EntityList",...rootAriaProps,...ariaAttributes},dataShown.map((_item,i)=>renderEntityItem(i))))}
@@ -44,6 +44,7 @@ export type BaseEntityListProps = {
44
44
  * @param ListNode[].customProp - Your data in order to use it custom "render" functions
45
45
  */
46
46
  data: ListNode[];
47
+ focusOnMount?: boolean;
47
48
  size?: ListSize;
48
49
  selectedIds?: string[];
49
50
  /** Allows selection of items with checkboxes. */
@@ -6,6 +6,7 @@ type FocusableItem = {
6
6
  type UseFocusByIndexResult = {
7
7
  moveFocus: (offset: number) => void;
8
8
  focusedIndex: number;
9
+ focusItemAtIndex: (index: number) => void;
9
10
  };
10
11
  type UseFocusByIndexOptions = {
11
12
  data: FocusableItem[];
@@ -1 +1 @@
1
- import{useCallback,useEffect,useRef,useState}from"react";let getNextEnabledIndex=(items,startIndex,direction)=>{let index=startIndex+direction;for(;index>=0&&index<items.length;){if(!items[index]?.isDisabled)return index;index+=direction}return -1},getClosestEnabledIndex=(items,currentIndex)=>{if(!items.length)return -1;if(currentIndex>=0&&currentIndex<items.length&&!items[currentIndex]?.isDisabled)return currentIndex;let forward=getNextEnabledIndex(items,currentIndex,1);return -1!==forward?forward:getNextEnabledIndex(items,currentIndex,-1)};export const useFocusByIndex=({data,containerRef,nodeSelector,preventScroll=!1,initialIndex=0})=>{let[focusedIndex,setFocusedIndex]=useState(()=>getClosestEnabledIndex(data,initialIndex)),focusedIndexRef=useRef(focusedIndex);useEffect(()=>{focusedIndexRef.current=focusedIndex},[focusedIndex]);let focusItemAtIndex=useCallback(index=>{if(-1===index)return;let container=containerRef.current;if(!container)return;let element=container.querySelector(`[${nodeSelector}="${index}"]`);!element||data[index]?.isDisabled||(element.focus({preventScroll}),setFocusedIndex(index))},[containerRef,data,nodeSelector,preventScroll]);return useEffect(()=>{let container=containerRef.current;if(!container)return;let handleContainerFocus=()=>{let nextIndex=getClosestEnabledIndex(data,focusedIndexRef.current);-1!==nextIndex&&focusItemAtIndex(nextIndex)},handleFocusIn=event=>{let target=event.target;if(!container.contains(target))return;let attributeValue=target.getAttribute(nodeSelector);if(null===attributeValue)return;let parsedIndex=Number(attributeValue);Number.isNaN(parsedIndex)||data[parsedIndex]?.isDisabled||setFocusedIndex(parsedIndex)};return container.addEventListener("focus",handleContainerFocus),container.addEventListener("focusin",handleFocusIn),()=>{container.removeEventListener("focus",handleContainerFocus),container.removeEventListener("focusin",handleFocusIn)}},[containerRef,data,focusItemAtIndex,nodeSelector]),{moveFocus:useCallback(offset=>{let nextIndex;if(!data.length)return;let direction=offset>0?1:-1,remainingSteps=Math.abs(offset);for(nextIndex=-1===focusedIndex?direction>0?-1:data.length:focusedIndex;remainingSteps>0;){let candidate=getNextEnabledIndex(data,nextIndex,direction);if(-1===candidate)return;nextIndex=candidate,remainingSteps-=1}nextIndex!==focusedIndex&&focusItemAtIndex(nextIndex)},[data,focusItemAtIndex,focusedIndex]),focusedIndex}};
1
+ import{useCallback,useEffect,useRef,useState}from"react";let getNextEnabledIndex=(items,startIndex,direction)=>{let index=startIndex+direction;for(;index>=0&&index<items.length;){if(!items[index]?.isDisabled)return index;index+=direction}return -1},getClosestEnabledIndex=(items,currentIndex)=>{if(!items.length)return -1;if(currentIndex>=0&&currentIndex<items.length&&!items[currentIndex]?.isDisabled)return currentIndex;let forward=getNextEnabledIndex(items,currentIndex,1);return -1!==forward?forward:getNextEnabledIndex(items,currentIndex,-1)};export const useFocusByIndex=({data,containerRef,nodeSelector,preventScroll=!1,initialIndex=0})=>{let[focusedIndex,setFocusedIndex]=useState(()=>getClosestEnabledIndex(data,initialIndex)),focusedIndexRef=useRef(focusedIndex);useEffect(()=>{focusedIndexRef.current=focusedIndex},[focusedIndex]);let focusItemAtIndex=useCallback(index=>{if(-1===index)return;let container=containerRef.current;if(!container)return;let element=container.querySelector(`[${nodeSelector}="${index}"]`);!element||data[index]?.isDisabled||(element.focus({preventScroll}),setFocusedIndex(index))},[containerRef,data,nodeSelector,preventScroll]);return useEffect(()=>{let container=containerRef.current;if(!container)return;let handleContainerFocus=()=>{let nextIndex=getClosestEnabledIndex(data,focusedIndexRef.current);-1!==nextIndex&&focusItemAtIndex(nextIndex)},handleFocusIn=event=>{let target=event.target;if(!container.contains(target))return;let attributeValue=target.getAttribute(nodeSelector);if(null===attributeValue)return;let parsedIndex=Number(attributeValue);Number.isNaN(parsedIndex)||data[parsedIndex]?.isDisabled||setFocusedIndex(parsedIndex)};return container.addEventListener("focus",handleContainerFocus),container.addEventListener("focusin",handleFocusIn),()=>{container.removeEventListener("focus",handleContainerFocus),container.removeEventListener("focusin",handleFocusIn)}},[containerRef,data,focusItemAtIndex,nodeSelector]),{moveFocus:useCallback(offset=>{let nextIndex;if(!data.length)return;let direction=offset>0?1:-1,remainingSteps=Math.abs(offset);for(nextIndex=-1===focusedIndex?direction>0?-1:data.length:focusedIndex;remainingSteps>0;){let candidate=getNextEnabledIndex(data,nextIndex,direction);if(-1===candidate)return;nextIndex=candidate,remainingSteps-=1}nextIndex!==focusedIndex&&focusItemAtIndex(nextIndex)},[data,focusItemAtIndex,focusedIndex]),focusedIndex,focusItemAtIndex}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amboss/design-system",
3
- "version": "3.42.2",
3
+ "version": "3.42.3",
4
4
  "description": "the design system for AMBOSS products",
5
5
  "author": "AMBOSS",
6
6
  "license": "ISC",