diff --git a/.changeset/eighty-stingrays-type.md b/.changeset/eighty-stingrays-type.md new file mode 100644 index 0000000000..731c401b77 --- /dev/null +++ b/.changeset/eighty-stingrays-type.md @@ -0,0 +1,5 @@ +--- +'@backstage/core': patch +--- + +Add forwardRef to the SidebarItem diff --git a/packages/core/src/layout/Sidebar/Items.tsx b/packages/core/src/layout/Sidebar/Items.tsx index 2eca89f873..9977a7c77b 100644 --- a/packages/core/src/layout/Sidebar/Items.tsx +++ b/packages/core/src/layout/Sidebar/Items.tsx @@ -25,7 +25,13 @@ import { BackstageTheme } from '@backstage/theme'; import { IconComponent } from '@backstage/core-api'; import SearchIcon from '@material-ui/icons/Search'; import clsx from 'clsx'; -import React, { FC, useContext, useState, KeyboardEventHandler } from 'react'; +import React, { + FC, + useContext, + useState, + KeyboardEventHandler, + forwardRef, +} from 'react'; import { NavLink } from 'react-router-dom'; import { sidebarConfig, SidebarContext } from './config'; @@ -117,72 +123,90 @@ type SidebarItemProps = { onClick?: () => void; }; -export const SidebarItem: FC = ({ - icon: Icon, - text, - to, - hasNotifications = false, - onClick, - children, -}) => { - const classes = useStyles(); - // XXX (@koroeskohr): unsure this is optimal. But I just really didn't want to have the item component - // depend on the current location, and at least have it being optionally forced to selected. - // Still waiting on a Q answered to fine tune the implementation - const { isOpen } = useContext(SidebarContext); +export const SidebarItem = forwardRef( + ( + { icon: Icon, text, to, hasNotifications = false, onClick, children }, + ref, + ) => { + const classes = useStyles(); + // XXX (@koroeskohr): unsure this is optimal. But I just really didn't want to have the item component + // depend on the current location, and at least have it being optionally forced to selected. + // Still waiting on a Q answered to fine tune the implementation + const { isOpen } = useContext(SidebarContext); - const itemIcon = ( - - - - ); + const itemIcon = ( + + + + ); - const childProps = { - onClick, - className: clsx(classes.root, isOpen ? classes.open : classes.closed), - }; + const childProps = { + onClick, + className: clsx(classes.root, isOpen ? classes.open : classes.closed), + }; + + if (!isOpen) { + if (to === undefined) { + return ( +
+ {itemIcon} +
+ ); + } + + return ( + + {itemIcon} + + ); + } + + const content = ( + <> +
+ {itemIcon} +
+ {text && ( + + {text} + + )} +
{children}
+ + ); - if (!isOpen) { if (to === undefined) { - return
{itemIcon}
; + return ( +
+ {content} +
+ ); } return ( - - {itemIcon} + + {content} ); - } - - const content = ( - <> -
- {itemIcon} -
- {text && ( - - {text} - - )} -
{children}
- - ); - - if (to === undefined) { - return
{content}
; - } - - return ( - - {content} - - ); -}; + }, +); type SidebarSearchFieldProps = { onSearch: (input: string) => void;