fix(sidebar): fix various styling
Signed-off-by: Phil Kuang <pkuang@factset.com>
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -1084,8 +1084,8 @@ export type SidebarSubmenuItemDropdownItem = {
|
||||
// @public
|
||||
export type SidebarSubmenuItemProps = {
|
||||
title: string;
|
||||
to: string;
|
||||
icon: IconComponent;
|
||||
to?: string;
|
||||
icon?: IconComponent;
|
||||
dropdownItems?: SidebarSubmenuItemDropdownItem[];
|
||||
};
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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<BackstageTheme>(
|
||||
margin: 14,
|
||||
marginLeft: 7,
|
||||
fontSize: 14,
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
'text-overflow': 'ellipsis',
|
||||
},
|
||||
dropdownArrow: {
|
||||
position: 'absolute',
|
||||
@@ -68,16 +72,19 @@ const useStyles = makeStyles<BackstageTheme>(
|
||||
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 (
|
||||
<div className={classes.itemContainer}>
|
||||
<button
|
||||
onClick={handleClickDropdown}
|
||||
onTouchStart={e => e.stopPropagation()}
|
||||
className={classnames(
|
||||
classes.item,
|
||||
isActive ? classes.selected : undefined,
|
||||
)}
|
||||
>
|
||||
<Icon fontSize="small" />
|
||||
<Typography variant="subtitle1" className={classes.label}>
|
||||
{title}
|
||||
</Typography>
|
||||
{showDropDown ? (
|
||||
<ArrowDropUpIcon className={classes.dropdownArrow} />
|
||||
) : (
|
||||
<ArrowDropDownIcon className={classes.dropdownArrow} />
|
||||
)}
|
||||
</button>
|
||||
<Tooltip title={title} enterDelay={500} enterNextDelay={500}>
|
||||
<button
|
||||
onClick={handleClickDropdown}
|
||||
onTouchStart={e => e.stopPropagation()}
|
||||
className={classnames(
|
||||
classes.item,
|
||||
isActive ? classes.selected : undefined,
|
||||
)}
|
||||
>
|
||||
{Icon && <Icon fontSize="small" />}
|
||||
<Typography variant="subtitle1" className={classes.label}>
|
||||
{title}
|
||||
</Typography>
|
||||
{showDropDown ? (
|
||||
<ArrowDropUpIcon className={classes.dropdownArrow} />
|
||||
) : (
|
||||
<ArrowDropDownIcon className={classes.dropdownArrow} />
|
||||
)}
|
||||
</button>
|
||||
</Tooltip>
|
||||
{dropdownItems && showDropDown && (
|
||||
<div className={classes.dropdown}>
|
||||
{dropdownItems.map((object, key) => (
|
||||
<Link
|
||||
to={object.to}
|
||||
underline="none"
|
||||
className={classes.dropdownItem}
|
||||
onClick={closeSubmenu}
|
||||
onTouchStart={e => e.stopPropagation()}
|
||||
<Tooltip
|
||||
key={key}
|
||||
title={object.title}
|
||||
enterDelay={500}
|
||||
enterNextDelay={500}
|
||||
>
|
||||
<Typography className={classes.textContent}>
|
||||
{object.title}
|
||||
</Typography>
|
||||
</Link>
|
||||
<Link
|
||||
to={object.to}
|
||||
underline="none"
|
||||
className={classes.dropdownItem}
|
||||
onClick={closeSubmenu}
|
||||
onTouchStart={e => e.stopPropagation()}
|
||||
>
|
||||
<Typography className={classes.textContent}>
|
||||
{object.title}
|
||||
</Typography>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
@@ -181,21 +196,23 @@ export const SidebarSubmenuItem = (props: SidebarSubmenuItemProps) => {
|
||||
|
||||
return (
|
||||
<div className={classes.itemContainer}>
|
||||
<Link
|
||||
to={to}
|
||||
underline="none"
|
||||
className={classnames(
|
||||
classes.item,
|
||||
isActive ? classes.selected : undefined,
|
||||
)}
|
||||
onClick={closeSubmenu}
|
||||
onTouchStart={e => e.stopPropagation()}
|
||||
>
|
||||
<Icon fontSize="small" />
|
||||
<Typography variant="subtitle1" className={classes.label}>
|
||||
{title}
|
||||
</Typography>
|
||||
</Link>
|
||||
<Tooltip title={title} enterDelay={500} enterNextDelay={500}>
|
||||
<Link
|
||||
to={to!}
|
||||
underline="none"
|
||||
className={classnames(
|
||||
classes.item,
|
||||
isActive ? classes.selected : undefined,
|
||||
)}
|
||||
onClick={closeSubmenu}
|
||||
onTouchStart={e => e.stopPropagation()}
|
||||
>
|
||||
{Icon && <Icon fontSize="small" />}
|
||||
<Typography variant="subtitle1" className={classes.label}>
|
||||
{title}
|
||||
</Typography>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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 (
|
||||
<SidebarItem icon={icon} to="catalog" text={pluralTitle}>
|
||||
<SidebarItem icon={icon} text={pluralTitle}>
|
||||
<SidebarSubmenu title={pluralTitle}>
|
||||
{groups?.map(function groupsMap(group) {
|
||||
return (
|
||||
<SidebarSubmenuItem
|
||||
title={group.metadata.title || group.metadata.name}
|
||||
title={
|
||||
group.metadata.title ||
|
||||
humanizeEntityRef(group, { defaultKind: 'group' })
|
||||
}
|
||||
to={catalogEntityRoute(getCompoundEntityRef(group))}
|
||||
icon={icon}
|
||||
key={group.metadata.name}
|
||||
key={stringifyEntityRef(group)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user