diff --git a/.changeset/shiny-moles-study.md b/.changeset/shiny-moles-study.md new file mode 100644 index 0000000000..59ce7d560b --- /dev/null +++ b/.changeset/shiny-moles-study.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Properly highlight `SidebarSubmenuItem` dropdown items on hover, use ellipsis styling on long labels in `SidebarSubmenu`, allow `icon` and `to` properties to be optional on `SidebarSubmenuItem`, and fix `SidebarPage` padding to be responsive to pinned state diff --git a/.changeset/wise-doors-hammer.md b/.changeset/wise-doors-hammer.md new file mode 100644 index 0000000000..68160a3b64 --- /dev/null +++ b/.changeset/wise-doors-hammer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org': patch +--- + +Include namespace in `MyGroupSidebarItem` if not default and remove root item routing if there are multiple groups diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index a195d62496..727a50926c 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -1084,8 +1084,8 @@ export type SidebarSubmenuItemDropdownItem = { // @public export type SidebarSubmenuItemProps = { title: string; - to: string; - icon: IconComponent; + to?: string; + icon?: IconComponent; dropdownItems?: SidebarSubmenuItemDropdownItem[]; }; diff --git a/packages/core-components/src/layout/Sidebar/Page.tsx b/packages/core-components/src/layout/Sidebar/Page.tsx index 9ce4a9f997..9bf8105f81 100644 --- a/packages/core-components/src/layout/Sidebar/Page.tsx +++ b/packages/core-components/src/layout/Sidebar/Page.tsx @@ -37,20 +37,20 @@ const useStyles = makeStyles< { sidebarConfig: SidebarConfig; isPinned: boolean } >( theme => ({ - root: props => ({ + root: { width: '100%', transition: 'padding-left 0.1s ease-out', isolation: 'isolate', [theme.breakpoints.up('sm')]: { - paddingLeft: () => + paddingLeft: props => props.isPinned ? props.sidebarConfig.drawerWidthOpen : props.sidebarConfig.drawerWidthClosed, }, [theme.breakpoints.down('xs')]: { - paddingBottom: props.sidebarConfig.mobileSidebarHeight, + paddingBottom: props => props.sidebarConfig.mobileSidebarHeight, }, - }), + }, content: { zIndex: 0, isolation: 'isolate', diff --git a/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx b/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx index 5c9dce010d..41f1a1e287 100644 --- a/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx +++ b/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx @@ -16,6 +16,7 @@ import React, { useContext, useState } from 'react'; import { resolvePath, useLocation, useResolvedPath } from 'react-router-dom'; import { makeStyles } from '@material-ui/core/styles'; +import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; import { Link } from '../../components/Link'; import { IconComponent } from '@backstage/core-plugin-api'; @@ -55,6 +56,9 @@ const useStyles = makeStyles( margin: 14, marginLeft: 7, fontSize: 14, + whiteSpace: 'nowrap', + overflow: 'hidden', + 'text-overflow': 'ellipsis', }, dropdownArrow: { position: 'absolute', @@ -68,16 +72,19 @@ const useStyles = makeStyles( dropdownItem: { width: '100%', padding: '10px 0 10px 0', + '&:hover': { + background: '#6f6f6f', + color: theme.palette.navigation.selectedColor, + }, }, textContent: { color: theme.palette.navigation.color, - display: 'flex', - justifyContent: 'center', - [theme.breakpoints.down('xs')]: { - display: 'block', - paddingLeft: theme.spacing(4), - }, + paddingLeft: theme.spacing(4), + paddingRight: theme.spacing(1), fontSize: '14px', + whiteSpace: 'nowrap', + overflow: 'hidden', + 'text-overflow': 'ellipsis', }, }), { name: 'BackstageSidebarSubmenuItem' }, @@ -106,8 +113,8 @@ export type SidebarSubmenuItemDropdownItem = { */ export type SidebarSubmenuItemProps = { title: string; - to: string; - icon: IconComponent; + to?: string; + icon?: IconComponent; dropdownItems?: SidebarSubmenuItemDropdownItem[]; }; @@ -123,7 +130,7 @@ export const SidebarSubmenuItem = (props: SidebarSubmenuItemProps) => { const closeSubmenu = () => { setIsHoveredOn(false); }; - const toLocation = useResolvedPath(to); + const toLocation = useResolvedPath(to ?? ''); const currentLocation = useLocation(); let isActive = isLocationMatch(currentLocation, toLocation); @@ -139,39 +146,47 @@ export const SidebarSubmenuItem = (props: SidebarSubmenuItemProps) => { }); return (
- + + + {dropdownItems && showDropDown && (
{dropdownItems.map((object, key) => ( - e.stopPropagation()} + - - {object.title} - - + e.stopPropagation()} + > + + {object.title} + + + ))}
)} @@ -181,21 +196,23 @@ export const SidebarSubmenuItem = (props: SidebarSubmenuItemProps) => { return (
- e.stopPropagation()} - > - - - {title} - - + + e.stopPropagation()} + > + {Icon && } + + {title} + + +
); }; diff --git a/plugins/org/src/components/MyGroupsSidebarItem/MyGroupsSidebarItem.tsx b/plugins/org/src/components/MyGroupsSidebarItem/MyGroupsSidebarItem.tsx index c2473670cf..5a3cc42628 100644 --- a/plugins/org/src/components/MyGroupsSidebarItem/MyGroupsSidebarItem.tsx +++ b/plugins/org/src/components/MyGroupsSidebarItem/MyGroupsSidebarItem.tsx @@ -15,6 +15,7 @@ */ import React from 'react'; +import { stringifyEntityRef } from '@backstage/catalog-model'; import { SidebarItem, SidebarSubmenu, @@ -31,6 +32,7 @@ import { catalogApiRef, CatalogApi, entityRouteRef, + humanizeEntityRef, } from '@backstage/plugin-catalog-react'; import { getCompoundEntityRef } from '@backstage/catalog-model'; @@ -80,15 +82,18 @@ export const MyGroupsSidebarItem = (props: { // Member of more than one group return ( - + {groups?.map(function groupsMap(group) { return ( ); })}