Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
Copy link

@github-actions github-actions bot Mar 5, 2026

Choose a reason for hiding this comment

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

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-react-components/CalendarCompat 4 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/CalendarCompat.multiDayView - High Contrast.default.chromium.png 1236 Changed
vr-tests-react-components/CalendarCompat.multiDayView - Dark Mode.default.chromium.png 1107 Changed
vr-tests-react-components/CalendarCompat.multiDayView - RTL.default.chromium.png 495 Changed
vr-tests-react-components/CalendarCompat.multiDayView.default.chromium_1.png 403 Changed
vr-tests-react-components/Charts-DonutChart 3 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Charts-DonutChart.Dynamic.default.chromium.png 5581 Changed
vr-tests-react-components/Charts-DonutChart.Dynamic - RTL.default.chromium.png 5570 Changed
vr-tests-react-components/Charts-DonutChart.Dynamic - Dark Mode.default.chromium.png 7530 Changed
vr-tests-react-components/Menu Converged - submenuIndicator slotted content 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default - RTL.submenus open.chromium.png 404 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.chromium.png 139 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 516 Changed
vr-tests-react-components/TagPicker 3 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - Dark Mode.chromium.png 658 Changed
vr-tests-react-components/TagPicker.disabled - High Contrast.disabled input hover.chromium.png 1319 Changed
vr-tests-react-components/TagPicker.disabled - RTL.disabled input hover.chromium.png 635 Changed

There were 4 duplicate changes discarded. Check the build logs for more information.

"type": "minor",
"comment": "feat: add base hooks for List",
"packageName": "@fluentui/react-list",
"email": "dmytrokirpa@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ export type ListContextValues = {
* State used in rendering List
*/
export type ListState = ComponentState<ListSlots> & ListContextValue & ListSynchronousContextValue;

/**
* List props type alias for the base hook.
* List has no design-specific props, so ListBaseProps is equivalent to ListProps.
*/
export type ListBaseProps = ListProps;

/**
* List state type alias for the base hook.
* List has no design-specific state, so ListBaseState is equivalent to ListState.
*/
export type ListBaseState = ListState;
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export { List } from './List';
export type {
ListBaseProps,
ListBaseState,
ListContextValue,
ListContextValues,
ListNavigationMode,
Expand All @@ -9,5 +11,5 @@ export type {
OnListSelectionChangeData,
} from './List.types';
export { renderList_unstable } from './renderList';
export { useList_unstable } from './useList';
export { useList_unstable, useListBase_unstable } from './useList';
export { listClassNames, useListStyles_unstable } from './useListStyles.styles';
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
useEventCallback,
} from '@fluentui/react-utilities';
import { useArrowNavigationGroup, useFocusFinders } from '@fluentui/react-tabster';
import { ListProps, ListState } from './List.types';
import { ListBaseProps, ListBaseState, ListProps, ListState } from './List.types';
import { useListSelection } from '../../hooks/useListSelection';
import {
calculateListItemRoleForListRole,
Expand All @@ -34,6 +34,21 @@ export const useList_unstable = (
props: ListProps,
ref: React.Ref<HTMLDivElement | HTMLUListElement | HTMLOListElement>,
): ListState => {
return useListBase_unstable(props, ref);
};

/**
* Base hook for List component, which manages state related to ARIA, keyboard navigation,
* selection, and slot structure. List has no design-specific props, so this hook contains
* the full component logic.
*
* @param props - User provided props to the List component.
* @param ref - User provided ref to be passed to the List component.
*/
export const useListBase_unstable = (
props: ListBaseProps,
ref: React.Ref<HTMLDivElement | HTMLUListElement | HTMLOListElement>,
): ListBaseState => {
const { navigationMode, selectionMode, selectedItems, defaultSelectedItems, onSelectionChange } = props;

const as = props.as || navigationMode === 'composite' ? 'div' : DEFAULT_ROOT_EL_TYPE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,15 @@ export type ListItemState = ComponentState<ListItemSlots> & {
navigable: boolean;
disabled?: boolean;
};

/**
* ListItem props type alias for the base hook.
* ListItem has no design-specific props, so ListItemBaseProps is equivalent to ListItemProps.
*/
export type ListItemBaseProps = ListItemProps;

/**
* ListItem state type alias for the base hook.
* ListItem has no design-specific state, so ListItemBaseState is equivalent to ListItemState.
*/
export type ListItemBaseState = ListItemState;
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
export { ListItem } from './ListItem';
export type {
ListItemActionEventData,
ListItemBaseProps,
ListItemBaseState,
ListItemProps,
ListItemSlots,
ListItemState,
ListItemValue,
} from './ListItem.types';
export { renderListItem_unstable } from './renderListItem';
export { useListItem_unstable } from './useListItem';
export { useListItem_unstable, useListItemBase_unstable } from './useListItem';
export { listItemClassNames, useListItemStyles_unstable } from './useListItemStyles.styles';
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
useId,
useMergedRefs,
} from '@fluentui/react-utilities';
import type { ListItemProps, ListItemState } from './ListItem.types';
import type { ListItemBaseProps, ListItemBaseState, ListItemProps, ListItemState } from './ListItem.types';
import { useListSynchronousContext, useListContext_unstable } from '../List/listContext';
import { Enter, Space, ArrowUp, ArrowDown, ArrowRight, ArrowLeft } from '@fluentui/keyboard-keys';
import { Checkbox, CheckboxOnChangeData } from '@fluentui/react-checkbox';
Expand All @@ -45,6 +45,21 @@ export const useListItem_unstable = (
props: ListItemProps,
ref: React.Ref<HTMLLIElement | HTMLDivElement>,
): ListItemState => {
return useListItemBase_unstable(props, ref);
};

/**
* Base hook for ListItem component, which manages state related to ARIA, keyboard handling,
* selection, focus management, and slot structure. ListItem has no design-specific props,
* so this hook contains the full component logic.
*
* @param props - User provided props to the ListItem component.
* @param ref - User provided ref to be passed to the ListItem component.
*/
export const useListItemBase_unstable = (
props: ListItemBaseProps,
ref: React.Ref<HTMLLIElement | HTMLDivElement>,
): ListItemBaseState => {
const id = useId('listItem');
const { value = id, onKeyDown, onClick, tabIndex, role, onAction, disabledSelection } = props;

Expand Down
6 changes: 6 additions & 0 deletions packages/react-components/react-list/library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ export {
useListItem_unstable,
} from './ListItem';
export type { ListItemProps, ListItemSlots, ListItemState } from './ListItem';

// Experimental APIs - will be uncommented in the experimental release branch
// export { useListBase_unstable } from './List';
// export type { ListBaseProps, ListBaseState } from './List';
// export { useListItemBase_unstable } from './ListItem';
// export type { ListItemBaseProps, ListItemBaseState } from './ListItem';