diff --git a/change/@fluentui-react-breadcrumb-78372ea0-823d-4939-b9f5-600d215feb68.json b/change/@fluentui-react-breadcrumb-78372ea0-823d-4939-b9f5-600d215feb68.json new file mode 100644 index 0000000000000..07a3955938b1b --- /dev/null +++ b/change/@fluentui-react-breadcrumb-78372ea0-823d-4939-b9f5-600d215feb68.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: make BreadcrumbButtonBaseProps distribute over the ARIA button union so the anchor arm's href stays assignable", + "packageName": "@fluentui/react-breadcrumb", + "email": "array.knight@gmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-breadcrumb/library/etc/react-breadcrumb.api.md b/packages/react-components/react-breadcrumb/library/etc/react-breadcrumb.api.md index 21b597d5eb78d..e16f1f764e21f 100644 --- a/packages/react-components/react-breadcrumb/library/etc/react-breadcrumb.api.md +++ b/packages/react-components/react-breadcrumb/library/etc/react-breadcrumb.api.md @@ -9,6 +9,7 @@ import type { ButtonSlots } from '@fluentui/react-button'; import type { ButtonState } from '@fluentui/react-button'; import type { ComponentProps } from '@fluentui/react-utilities'; import type { ComponentState } from '@fluentui/react-utilities'; +import type { DistributiveOmit } from '@fluentui/react-utilities'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; import type { JSXElement } from '@fluentui/react-utilities'; import * as React_2 from 'react'; @@ -29,7 +30,7 @@ export type BreadcrumbBaseState = Omit; export const BreadcrumbButton: ForwardRefComponent; // @public (undocumented) -export type BreadcrumbButtonBaseProps = Omit; +export type BreadcrumbButtonBaseProps = DistributiveOmit; // @public (undocumented) export type BreadcrumbButtonBaseState = Omit; diff --git a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/BreadcrumbButton.test.tsx b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/BreadcrumbButton.test.tsx index 6e39e8274ceac..5786a541fd44f 100644 --- a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/BreadcrumbButton.test.tsx +++ b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/BreadcrumbButton.test.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; -import { render } from '@testing-library/react'; +import { render, renderHook } from '@testing-library/react'; import { BreadcrumbButton } from './BreadcrumbButton'; +import { useBreadcrumbButtonBase_unstable } from './useBreadcrumbButton'; import type { BreadcrumbButtonProps } from './BreadcrumbButton.types'; import { isConformant } from '../../testing/isConformant'; import { breadcrumbButtonClassNames } from './useBreadcrumbButtonStyles.styles'; @@ -67,4 +68,23 @@ describe('BreadcrumbButton', () => { `); }); + + it('accepts the anchor arm of the ARIA button union in the base hook', () => { + const { result } = renderHook(() => + useBreadcrumbButtonBase_unstable({ as: 'a', href: '/somewhere' }, React.createRef()), + ); + + expect(result.current).toMatchObject({ + root: { as: 'a', href: '/somewhere' }, + }); + }); + + it('keeps an explicit as="button" on the button arm of the base hook', () => { + const { result } = renderHook(() => + useBreadcrumbButtonBase_unstable({ as: 'button' }, React.createRef()), + ); + + expect(result.current.root.as).toBe('button'); + expect(result.current.root.role).toBeUndefined(); + }); }); diff --git a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/BreadcrumbButton.types.ts b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/BreadcrumbButton.types.ts index a9220b965983e..95bf28bd91449 100644 --- a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/BreadcrumbButton.types.ts +++ b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/BreadcrumbButton.types.ts @@ -1,4 +1,4 @@ -import type { ComponentProps, ComponentState } from '@fluentui/react-utilities'; +import type { ComponentProps, ComponentState, DistributiveOmit } from '@fluentui/react-utilities'; import type { ButtonProps, ButtonSlots, ButtonState } from '@fluentui/react-button'; import type { BreadcrumbProps } from '../Breadcrumb/Breadcrumb.types'; @@ -25,6 +25,6 @@ export type BreadcrumbButtonState = ComponentState & Omit & Required>; -export type BreadcrumbButtonBaseProps = Omit; +export type BreadcrumbButtonBaseProps = DistributiveOmit; export type BreadcrumbButtonBaseState = Omit; diff --git a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/useBreadcrumbButton.ts b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/useBreadcrumbButton.ts index 5935f389ded72..d2837d424d52a 100644 --- a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/useBreadcrumbButton.ts +++ b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/useBreadcrumbButton.ts @@ -49,7 +49,7 @@ export const useBreadcrumbButtonBase_unstable = ( ): BreadcrumbButtonBaseState => { const { current = false, as, ...rest } = props; - const controlType = as ?? (props as ARIAButtonProps<'a'>).href ? 'a' : 'button'; + const controlType = as ?? ((props as ARIAButtonProps<'a'>).href ? 'a' : 'button'); const buttonState = useButtonBase_unstable( {