diff --git a/.changeset/famous-walls-yell.md b/.changeset/famous-walls-yell.md new file mode 100644 index 0000000000..8a4e988f5b --- /dev/null +++ b/.changeset/famous-walls-yell.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Fix issue where component types are not recognized causing the `MobileSidebar` to not render as intended. diff --git a/packages/core-components/src/layout/Sidebar/Items.tsx b/packages/core-components/src/layout/Sidebar/Items.tsx index b16c9ad302..fc97fdc0ce 100644 --- a/packages/core-components/src/layout/Sidebar/Items.tsx +++ b/packages/core-components/src/layout/Sidebar/Items.tsx @@ -284,6 +284,8 @@ function isButtonItem( return (props as SidebarItemLinkProps).to === undefined; } +const sidebarSubmenuType = React.createElement(SidebarSubmenu).type; + // TODO(Rugvip): Remove this once NavLink is updated in react-router-dom. // This is needed because react-router doesn't handle the path comparison // properly yet, matching for example /foobar with /foo. @@ -486,7 +488,11 @@ const SidebarItemWithSubmenu = ({ export const SidebarItem = forwardRef((props, ref) => { // Filter children for SidebarSubmenu components const [submenu] = useElementFilter(props.children, elements => - elements.getElements().filter(child => child.type === SidebarSubmenu), + // Directly comparing child.type with SidebarSubmenu will not work with in + // combination with react-hot-loader + // + // https://github.com/gaearon/react-hot-loader/issues/304#issuecomment-456569720 + elements.getElements().filter(child => child.type === sidebarSubmenuType), ); if (submenu) { diff --git a/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx b/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx index 3819f21a02..95947f9274 100644 --- a/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx +++ b/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx @@ -102,6 +102,8 @@ const sortSidebarGroupsForPriority = (children: React.ReactElement[]) => 'desc', ); +const sidebarGroupType = React.createElement(SidebarGroup).type; + const OverlayMenu = ({ children, label = 'Menu', @@ -162,8 +164,13 @@ export const MobileSidebar = (props: MobileSidebarProps) => { }, [location.pathname]); // Filter children for SidebarGroups + // + // Directly comparing child.type with SidebarSubmenu will not work with in + // combination with react-hot-loader + // + // https://github.com/gaearon/react-hot-loader/issues/304#issuecomment-456569720 let sidebarGroups = useElementFilter(children, elements => - elements.getElements().filter(child => child.type === SidebarGroup), + elements.getElements().filter(child => child.type === sidebarGroupType), ); if (!children) {