From b89a6f1acb7939cfbf3680002993f1ede6ba6eef Mon Sep 17 00:00:00 2001 From: Josh Black Date: Wed, 12 Aug 2026 10:19:55 -0500 Subject: [PATCH 1/4] Migrate navigation roots to mergeProps Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 84a0d8ca-13d3-4cb2-ab24-18fa2d9a8a14 --- ...underline-panels-controlled-panel-props.md | 5 + packages/react/src/ActionBar/ActionBar.tsx | 104 +++++----- .../react/src/Breadcrumbs/Breadcrumbs.tsx | 13 +- packages/react/src/NavList/NavList.tsx | 81 +++++--- packages/react/src/PageHeader/PageHeader.tsx | 183 ++++++++++++------ packages/react/src/Pagehead/Pagehead.tsx | 13 +- packages/react/src/SideNav.tsx | 11 +- .../src/SplitPageLayout/SplitPageLayout.tsx | 114 ++++++++--- packages/react/src/SubNav/SubNav.tsx | 29 ++- packages/react/src/TabNav/TabNav.tsx | 29 ++- .../deprecated/UnderlineNav/UnderlineNav.tsx | 19 +- .../UnderlinePanels/UnderlinePanels.tsx | 37 +++- .../UnderlinePanels.types.test.tsx | 19 ++ .../components/UnderlineTabbedInterface.tsx | 8 +- 14 files changed, 473 insertions(+), 192 deletions(-) create mode 100644 .changeset/underline-panels-controlled-panel-props.md create mode 100644 packages/react/src/experimental/UnderlinePanels/UnderlinePanels.types.test.tsx diff --git a/.changeset/underline-panels-controlled-panel-props.md b/.changeset/underline-panels-controlled-panel-props.md new file mode 100644 index 00000000000..c52f1dceee0 --- /dev/null +++ b/.changeset/underline-panels-controlled-panel-props.md @@ -0,0 +1,5 @@ +--- +'@primer/react': major +--- + +UnderlinePanels: Remove unsupported panel attributes that are controlled by the component. diff --git a/packages/react/src/ActionBar/ActionBar.tsx b/packages/react/src/ActionBar/ActionBar.tsx index 4e5324b65fd..4ba42585c0b 100644 --- a/packages/react/src/ActionBar/ActionBar.tsx +++ b/packages/react/src/ActionBar/ActionBar.tsx @@ -13,6 +13,7 @@ import {useMergedRefs} from '../hooks' import {createDescendantRegistry} from '../utils/descendant-registry' import {OverflowObserverProvider} from '../internal/components/OverflowObserverProvider' import {useIsClipped} from '../internal/hooks/useOverflowObserver' +import {mergeProps} from '../utils/mergeProps' type ChildProps = | { @@ -332,12 +333,11 @@ function useActionBarItem(ref: React.RefObject, registryProp } export const ActionBarIconButton = forwardRef( - ({disabled, onClick, ...props}: ActionBarIconButtonProps, forwardedRef) => { + ({disabled, onClick, className, ...props}: ActionBarIconButtonProps, forwardedRef) => { const ref = useRef(null) const mergedRef = useMergedRefs(forwardedRef, ref) const {size} = React.useContext(ActionBarContext) - const {['aria-label']: ariaLabel, icon} = props const {dataOverflowingAttr} = useActionBarItem( @@ -364,11 +364,16 @@ export const ActionBarIconButton = forwardRef( return ( @@ -376,50 +381,57 @@ export const ActionBarIconButton = forwardRef( }, ) -export const ActionBarButton = forwardRef(({disabled, onClick, ...props}: ActionBarButtonProps, forwardedRef) => { - const ref = useRef(null) - const mergedRef = useMergedRefs(forwardedRef, ref) - - const {size} = React.useContext(ActionBarContext) +export const ActionBarButton = forwardRef( + ({disabled, onClick, className, children, leadingVisual, ...props}: ActionBarButtonProps, forwardedRef) => { + const ref = useRef(null) + const mergedRef = useMergedRefs(forwardedRef, ref) - const {children, leadingVisual} = props + const {size} = React.useContext(ActionBarContext) - const {dataOverflowingAttr} = useActionBarItem( - ref, - useMemo( - (): ChildProps => ({ - type: 'action', - label: children, - // Only forward the leading visual to the overflow menu when it is a component - // that can be rendered as an icon (e.g. an octicon), matching ActionBar.IconButton. - icon: typeof leadingVisual === 'function' ? (leadingVisual as ActionBarIconButtonProps['icon']) : undefined, - disabled: !!disabled, - onClick: onClick as MouseEventHandler, - }), - [children, leadingVisual, disabled, onClick], - ), - ) + const {dataOverflowingAttr} = useActionBarItem( + ref, + useMemo( + (): ChildProps => ({ + type: 'action', + label: children, + // Only forward the leading visual to the overflow menu when it is a component + // that can be rendered as an icon (e.g. an octicon), matching ActionBar.IconButton. + icon: typeof leadingVisual === 'function' ? (leadingVisual as ActionBarIconButtonProps['icon']) : undefined, + disabled: !!disabled, + onClick: onClick as MouseEventHandler, + }), + [children, leadingVisual, disabled, onClick], + ), + ) - const clickHandler = useCallback( - (event: React.MouseEvent) => { - if (disabled) return - onClick?.(event) - }, - [disabled, onClick], - ) + const clickHandler = useCallback( + (event: React.MouseEvent) => { + if (disabled) return + onClick?.(event) + }, + [disabled, onClick], + ) - return ( -