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.default.chromium_1.png 403 Changed
vr-tests-react-components/CalendarCompat.multiDayView - RTL.default.chromium.png 495 Changed
vr-tests-react-components/Charts-DonutChart 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Charts-DonutChart.Dynamic - RTL.default.chromium.png 5570 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.updated 2 times.chromium.png 504 Changed
vr-tests-react-components/Positioning.Positioning end.chromium.png 967 Changed
vr-tests-react-components/Skeleton converged 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Skeleton converged.Opaque Skeleton with circle - High Contrast.default.chromium.png 1 Changed
vr-tests-react-components/TagPicker 4 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - Dark Mode.disabled input hover.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
vr-tests-react-components/TagPicker.disabled.disabled input hover.chromium.png 677 Changed

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

"type": "minor",
"comment": "feat: add base hooks for Nav",
"packageName": "@fluentui/react-nav",
"email": "dmytrokirpa@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import * as React from 'react';

import type { ComponentProps, ComponentState, EventData, EventHandler, Slot } from '@fluentui/react-utilities';
import type {
ComponentProps,
ComponentState,
DistributiveOmit,
EventData,
EventHandler,
Slot,
} from '@fluentui/react-utilities';
import type { NavContextValue, NavItemValue } from '../NavContext.types';

export type NavSlots = {
Expand Down Expand Up @@ -97,7 +104,17 @@ export type OnNavItemSelectData = EventData<'click', React.MouseEvent<HTMLButton
categoryValue?: NavItemValue;
};

/**
* Nav base props — excludes design/density props.
*/
export type NavBaseProps = DistributiveOmit<NavProps, 'density'>;

/**
* State used in rendering Nav
*/
export type NavState = ComponentState<NavSlots> & NavContextValue;

/**
* Nav base state — excludes design/density props.
*/
export type NavBaseState = DistributiveOmit<NavState, 'density'>;
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
export { Nav } from './Nav';
export type { NavSlots, NavProps, OnNavItemSelectData, NavState, NavDensity } from './Nav.types';
export type {
NavSlots,
NavProps,
NavBaseProps,
OnNavItemSelectData,
NavState,
NavBaseState,
NavDensity,
} from './Nav.types';
export { renderNav_unstable } from './renderNav';
export { useNav_unstable } from './useNav';
export { useNav_unstable, useNavBase_unstable } from './useNav';
export { useNavStyles_unstable, navClassNames } from './useNavStyles.styles';
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
EventHandler,
} from '@fluentui/react-utilities';

import type { NavProps, NavState, OnNavItemSelectData } from './Nav.types';
import type { NavBaseProps, NavBaseState, NavProps, NavState, OnNavItemSelectData } from './Nav.types';
import type { NavItemRegisterData, NavItemValue } from '../NavContext.types';

/**
Expand Down Expand Up @@ -57,11 +57,27 @@ const updateOpenCategories = (value: NavItemValue, previousOpenItems: NavItemVal
* @param ref - reference to root HTMLDivElement of Nav
*/
export const useNav_unstable = (props: NavProps, ref: React.Ref<HTMLDivElement>): NavState => {
const { density = 'medium', ...baseProps } = props;
const state = useNavBase_unstable(baseProps, ref);

return {
...state,
density,
};
};

/**
* Base hook for Nav component. Manages state related to selection, open categories,
* slot structure, and nav item registration — without density/design props.
*
* @param props - props from this instance of Nav (without density)
* @param ref - reference to root HTMLDivElement of Nav
*/
export const useNavBase_unstable = (props: NavBaseProps, ref: React.Ref<HTMLDivElement>): NavBaseState => {
const {
onNavItemSelect,
onNavCategoryItemToggle,
multiple = true,
density = 'medium',
openCategories: controlledOpenCategoryItems,
selectedCategoryValue: controlledSelectedCategoryValue,
selectedValue: controlledSelectedValue,
Expand Down Expand Up @@ -166,7 +182,6 @@ export const useNav_unstable = (props: NavProps, ref: React.Ref<HTMLDivElement>)
getRegisteredNavItems,
onRequestNavCategoryItemToggle,
multiple,
density,
tabbable: false,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ export type NavCategoryProps = {
children?: React.ReactNode | null;
};

/**
* NavCategory base props — same as NavCategoryProps (no design-only props).
*/
export type NavCategoryBaseProps = NavCategoryProps;

/**
* State used in rendering NavCategory
*/
export type NavCategoryState = NavCategoryContextValue & Required<NavCategoryProps>;

/**
* NavCategory base state — same as NavCategoryState (no design-only state).
*/
export type NavCategoryBaseState = NavCategoryState;
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export { NavCategory } from './NavCategory';
export type { NavCategoryProps, NavCategoryState } from './NavCategory.types';
export type {
NavCategoryProps,
NavCategoryBaseProps,
NavCategoryState,
NavCategoryBaseState,
} from './NavCategory.types';
export { renderNavCategory_unstable } from './renderNavCategory';
export { useNavCategory_unstable } from './useNavCategory';
export { useNavCategory_unstable, useNavCategoryBase_unstable } from './useNavCategory';
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
import * as React from 'react';
import { useNavContext_unstable } from '../NavContext';

import type { NavCategoryProps, NavCategoryState } from './NavCategory.types';
import type {
NavCategoryBaseProps,
NavCategoryBaseState,
NavCategoryProps,
NavCategoryState,
} from './NavCategory.types';

/**
* Create the state required to render NavCategory.
Expand All @@ -15,6 +20,20 @@ import type { NavCategoryProps, NavCategoryState } from './NavCategory.types';
* @param ref - reference to root HTMLDivElement of NavCategory
*/
export const useNavCategory_unstable = (props: NavCategoryProps, ref: React.Ref<HTMLDivElement>): NavCategoryState => {
return useNavCategoryBase_unstable(props, ref);
};

/**
* Base hook for NavCategory component. Manages the open/closed state of a category
* by reading from the Nav context.
*
* @param props - props from this instance of NavCategory
* @param ref - reference to root HTMLDivElement of NavCategory
*/
export const useNavCategoryBase_unstable = (
props: NavCategoryBaseProps,
ref: React.Ref<HTMLDivElement>,
): NavCategoryBaseState => {
const { value, children } = props;

const { openCategories } = useNavContext_unstable();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PresenceMotionSlotProps } from '@fluentui/react-motion';
import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';
import type { ComponentProps, ComponentState, DistributiveOmit, Slot } from '@fluentui/react-utilities';
import type { NavDensity } from '../Nav/Nav.types';
import type { NavCategoryItemContextValue } from '../NavCategoryItemContext';

Expand Down Expand Up @@ -35,6 +35,11 @@ export type NavCategoryItemSlots = {
*/
export type NavCategoryItemProps = ComponentProps<Partial<NavCategoryItemSlots>>;

/**
* NavCategoryItem base props — same as NavCategoryItemProps (no design-only props at this level).
*/
export type NavCategoryItemBaseProps = NavCategoryItemProps;

/**
* State used in rendering NavCategoryItem
*/
Expand All @@ -51,3 +56,8 @@ export type NavCategoryItemState = ComponentState<NavCategoryItemSlots> &
*/
density: NavDensity;
};

/**
* NavCategoryItem base state — excludes density design prop.
*/
export type NavCategoryItemBaseState = DistributiveOmit<NavCategoryItemState, 'density'>;
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
export { NavCategoryItem } from './NavCategoryItem';
export type { NavCategoryItemSlots, NavCategoryItemProps, NavCategoryItemState } from './NavCategoryItem.types';
export type {
NavCategoryItemSlots,
NavCategoryItemProps,
NavCategoryItemBaseProps,
NavCategoryItemState,
NavCategoryItemBaseState,
} from './NavCategoryItem.types';
export { renderNavCategoryItem_unstable } from './renderNavCategoryItem';
export { useNavCategoryItem_unstable } from './useNavCategoryItem';
export { useNavCategoryItem_unstable, useNavCategoryItemBase_unstable } from './useNavCategoryItem';
export { useNavCategoryItemStyles_unstable, navCategoryItemClassNames } from './useNavCategoryItem.styles';
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { getIntrinsicElementProps, mergeCallbacks, slot, useEventCallback } from
import { ChevronDown20Regular } from '@fluentui/react-icons';
import { createPresenceComponentVariant, motionTokens, presenceMotionSlot } from '@fluentui/react-motion';

import type { NavCategoryItemProps, NavCategoryItemState } from './NavCategoryItem.types';
import type {
NavCategoryItemBaseProps,
NavCategoryItemBaseState,
NavCategoryItemProps,
NavCategoryItemState,
} from './NavCategoryItem.types';
import { useNavCategoryContext_unstable } from '../NavCategoryContext';
import { useNavContext_unstable } from '../NavContext';
import { Rotate } from '@fluentui/react-motion-components-preview';
Expand All @@ -31,11 +36,31 @@ export const useNavCategoryItem_unstable = (
props: NavCategoryItemProps,
ref: React.Ref<HTMLButtonElement>,
): NavCategoryItemState => {
const { density = 'medium' } = useNavContext_unstable();
const state = useNavCategoryItemBase_unstable(props, ref);

return {
...state,
density,
};
};

/**
* Base hook for NavCategoryItem component. Manages state related to ARIA attributes,
* keyboard interaction, and slot structure — without density design prop.
*
* @param props - props from this instance of NavCategoryItem
* @param ref - reference to root HTMLButtonElement of NavCategoryItem
*/
export const useNavCategoryItemBase_unstable = (
props: NavCategoryItemBaseProps,
ref: React.Ref<HTMLButtonElement>,
): NavCategoryItemBaseState => {
const { onClick, expandIcon, icon } = props;

const { open, value } = useNavCategoryContext_unstable();

const { onRequestNavCategoryItemToggle, selectedCategoryValue, density = 'medium' } = useNavContext_unstable();
const { onRequestNavCategoryItemToggle, selectedCategoryValue } = useNavContext_unstable();

const onNavCategoryItemClick = useEventCallback(
mergeCallbacks(onClick, event =>
Expand Down Expand Up @@ -84,6 +109,5 @@ export const useNavCategoryItem_unstable = (
icon: slot.optional(icon, {
elementType: 'span',
}),
density,
};
};
8 changes: 8 additions & 0 deletions packages/react-components/react-nav/library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,11 @@ export { NavCategoryItemProvider, useNavCategoryItemContext_unstable } from './c
export { useNavCategoryItemContextValues_unstable } from './components/useNavCategoryItemContextValues_unstable';

export { useNavContextValues_unstable } from './components/useNavContextValues';

// Experimental APIs - will be uncommented in the experimental release branch
// export { useNavBase_unstable } from './components/Nav/index';
// export type { NavBaseProps, NavBaseState } from './components/Nav/index';
// export { useNavCategoryBase_unstable } from './components/NavCategory/index';
// export type { NavCategoryBaseProps, NavCategoryBaseState } from './components/NavCategory/index';
// export { useNavCategoryItemBase_unstable } from './components/NavCategoryItem/index';
// export type { NavCategoryItemBaseProps, NavCategoryItemBaseState } from './components/NavCategoryItem/index';