Changed sidebar to accept new props sidebarOptions and submenuOptions
Signed-off-by: Jonathan Ash <jonathan-ash@users.noreply.github.com>
This commit is contained in:
@@ -2,4 +2,4 @@
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
<Sidebar /> now accepts custom configuration options by supplying props sidebarConfig and submenuConfig
|
||||
<Sidebar /> now accepts additional props sidebarOptions and submenuOptions to allow further customization
|
||||
|
||||
@@ -28,6 +28,8 @@ import {
|
||||
SidebarContext,
|
||||
SidebarConfigContext,
|
||||
SubmenuConfig,
|
||||
SidebarOptions,
|
||||
SubmenuOptions,
|
||||
} from './config';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { SidebarPinStateContext, useContent } from './Page';
|
||||
@@ -84,7 +86,7 @@ const useStyles = ({ sidebarConfig }: { sidebarConfig: SidebarConfig }) =>
|
||||
};
|
||||
},
|
||||
{ name: 'BackstageSidebar' },
|
||||
);
|
||||
)
|
||||
|
||||
enum State {
|
||||
Closed,
|
||||
@@ -94,13 +96,17 @@ enum State {
|
||||
|
||||
/** @public */
|
||||
export type SidebarProps = {
|
||||
sidebarConfig?: Partial<SidebarConfig>;
|
||||
submenuConfig?: Partial<SubmenuConfig>;
|
||||
openDelayMs?: number;
|
||||
closeDelayMs?: number;
|
||||
sidebarOptions?: SidebarOptions;
|
||||
submenuOptions?: SubmenuOptions;
|
||||
disableExpandOnHover?: boolean;
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
|
||||
export type DesktopSidebarProps = {
|
||||
openDelayMs?: number;
|
||||
closeDelayMs?: number;
|
||||
disableExpandOnHover?: boolean;
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
@@ -117,10 +123,12 @@ export type DesktopSidebarProps = {
|
||||
*/
|
||||
const DesktopSidebar = (props: DesktopSidebarProps) => {
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
const { defaultOpenDelayMs: openDelayMs, defaultCloseDelayMs: closeDelayMs } =
|
||||
sidebarConfig;
|
||||
|
||||
const { disableExpandOnHover, children } = props;
|
||||
const {
|
||||
openDelayMs = sidebarConfig.defaultOpenDelayMs,
|
||||
closeDelayMs = sidebarConfig.defaultCloseDelayMs,
|
||||
disableExpandOnHover,
|
||||
children,
|
||||
} = props;
|
||||
|
||||
const classes = useStyles({ sidebarConfig })();
|
||||
const isSmallScreen = useMediaQuery<BackstageTheme>(
|
||||
@@ -216,20 +224,23 @@ const DesktopSidebar = (props: DesktopSidebarProps) => {
|
||||
*/
|
||||
export const Sidebar = (props: SidebarProps) => {
|
||||
const sidebarConfig: SidebarConfig = makeSidebarConfig(
|
||||
props.sidebarConfig ?? {},
|
||||
props.sidebarOptions ?? {},
|
||||
);
|
||||
const submenuConfig: SubmenuConfig = makeSidebarSubmenuConfig(
|
||||
props.submenuConfig ?? {},
|
||||
sidebarConfig,
|
||||
props.submenuOptions ?? {},
|
||||
);
|
||||
const { children, disableExpandOnHover } = props;
|
||||
const { children, disableExpandOnHover, openDelayMs, closeDelayMs } = props;
|
||||
const { isMobile } = useContext(SidebarPinStateContext);
|
||||
|
||||
return isMobile ? (
|
||||
<MobileSidebar>{children}</MobileSidebar>
|
||||
) : (
|
||||
<SidebarConfigContext.Provider value={{ sidebarConfig, submenuConfig }}>
|
||||
<DesktopSidebar disableExpandOnHover={disableExpandOnHover}>
|
||||
<DesktopSidebar
|
||||
openDelayMs={openDelayMs}
|
||||
closeDelayMs={closeDelayMs}
|
||||
disableExpandOnHover={disableExpandOnHover}
|
||||
>
|
||||
{children}
|
||||
</DesktopSidebar>
|
||||
</SidebarConfigContext.Provider>
|
||||
|
||||
@@ -38,7 +38,7 @@ export type SidebarIntroClassKey =
|
||||
| 'introDismissText'
|
||||
| 'introDismissIcon';
|
||||
|
||||
const useStyles = ({sidebarConfig}: { sidebarConfig: SidebarConfig }) =>
|
||||
const useStyles = ({ sidebarConfig }: { sidebarConfig: SidebarConfig }) =>
|
||||
makeStyles<BackstageTheme>(
|
||||
theme => {
|
||||
return {
|
||||
|
||||
@@ -83,7 +83,20 @@ export type SidebarItemClassKey =
|
||||
| 'arrows'
|
||||
| 'selected';
|
||||
|
||||
<<<<<<< HEAD
|
||||
const useStyles = ({ sidebarConfig }: { sidebarConfig: SidebarConfig }) =>
|
||||
=======
|
||||
const useStyles = ({
|
||||
sidebarConfig: {
|
||||
drawerWidthClosed,
|
||||
drawerWidthOpen,
|
||||
iconContainerWidth,
|
||||
selectedIndicatorWidth,
|
||||
},
|
||||
}: {
|
||||
sidebarConfig: SidebarConfig;
|
||||
}) =>
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
makeStyles<BackstageTheme>(
|
||||
theme => {
|
||||
return {
|
||||
@@ -200,7 +213,11 @@ const useStyles = ({ sidebarConfig }: { sidebarConfig: SidebarConfig }) =>
|
||||
};
|
||||
},
|
||||
{ name: 'BackstageSidebarItem' },
|
||||
<<<<<<< HEAD
|
||||
);
|
||||
=======
|
||||
)();
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
|
||||
/**
|
||||
* Evaluates the routes of the SubmenuItems & nested DropdownItems.
|
||||
@@ -354,7 +371,11 @@ const SidebarItemBase = forwardRef<any, SidebarItemProps>((props, ref) => {
|
||||
...navLinkProps
|
||||
} = props;
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
<<<<<<< HEAD
|
||||
const classes = useStyles({ sidebarConfig })();
|
||||
=======
|
||||
const classes = useStyles({ sidebarConfig });
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
// 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
|
||||
@@ -428,7 +449,11 @@ const SidebarItemWithSubmenu = ({
|
||||
children: React.ReactElement<SidebarSubmenuProps>;
|
||||
}) => {
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
<<<<<<< HEAD
|
||||
const classes = useStyles({ sidebarConfig })();
|
||||
=======
|
||||
const classes = useStyles({ sidebarConfig });
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
const [isHoveredOn, setIsHoveredOn] = useState(false);
|
||||
const location = useLocation();
|
||||
const isActive = useLocationMatch(children, location);
|
||||
@@ -518,8 +543,13 @@ type SidebarSearchFieldProps = {
|
||||
|
||||
export function SidebarSearchField(props: SidebarSearchFieldProps) {
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
<<<<<<< HEAD
|
||||
const [input, setInput] = useState('');
|
||||
const classes = useStyles({ sidebarConfig })();
|
||||
=======
|
||||
const classes = useStyles({ sidebarConfig });
|
||||
const [input, setInput] = useState('');
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
const Icon = props.icon ? props.icon : SearchIcon;
|
||||
|
||||
const search = () => {
|
||||
@@ -648,7 +678,11 @@ export const SidebarScrollWrapper = styled('div')(({ theme }) => {
|
||||
*/
|
||||
export const SidebarExpandButton = () => {
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
<<<<<<< HEAD
|
||||
const classes = useStyles({ sidebarConfig })();
|
||||
=======
|
||||
const classes = useStyles({ sidebarConfig });
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
const { isOpen, setOpen } = useContext(SidebarContext);
|
||||
const isSmallScreen = useMediaQuery<BackstageTheme>(
|
||||
theme => theme.breakpoints.down('md'),
|
||||
|
||||
@@ -28,7 +28,11 @@ import { orderBy } from 'lodash';
|
||||
import React, { createContext, useEffect, useState, useContext } from 'react';
|
||||
import { useLocation } from 'react-router';
|
||||
import { SidebarGroup } from './SidebarGroup';
|
||||
<<<<<<< HEAD
|
||||
import { SidebarConfigContext, SidebarContext, SidebarConfig } from './config';
|
||||
=======
|
||||
import { SidebarConfigContext, SidebarConfig } from './config';
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
|
||||
/**
|
||||
* Type of `MobileSidebarContext`
|
||||
@@ -59,7 +63,11 @@ type OverlayMenuProps = {
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
|
||||
<<<<<<< HEAD
|
||||
const useStyles = ({ sidebarConfig }: { sidebarConfig: SidebarConfig }) =>
|
||||
=======
|
||||
const useStyles = ({ sidebarConfig }: { sidebarConfig: SidebarConfig }) =>
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
makeStyles<BackstageTheme>(theme => {
|
||||
return {
|
||||
root: {
|
||||
@@ -99,7 +107,11 @@ const useStyles = ({ sidebarConfig }: { sidebarConfig: SidebarConfig }) =>
|
||||
marginBottom: `${sidebarConfig.mobileSidebarHeight}px`,
|
||||
},
|
||||
};
|
||||
<<<<<<< HEAD
|
||||
})
|
||||
=======
|
||||
})();
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
|
||||
const sortSidebarGroupsForPriority = (children: React.ReactElement[]) =>
|
||||
orderBy(
|
||||
@@ -117,7 +129,11 @@ const OverlayMenu = ({
|
||||
onClose,
|
||||
}: OverlayMenuProps) => {
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
<<<<<<< HEAD
|
||||
const classes = useStyles({ sidebarConfig })();
|
||||
=======
|
||||
const classes = useStyles({ sidebarConfig });
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
@@ -168,7 +184,12 @@ export const MobileSidebarContext = createContext<MobileSidebarContextType>({
|
||||
export const MobileSidebar = (props: MobileSidebarProps) => {
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
const { children } = props;
|
||||
<<<<<<< HEAD
|
||||
const classes = useStyles({ sidebarConfig })();
|
||||
=======
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
const classes = useStyles({ sidebarConfig });
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
const location = useLocation();
|
||||
const [selectedMenuItemIndex, setSelectedMenuItemIndex] =
|
||||
useState<number>(-1);
|
||||
|
||||
@@ -25,17 +25,21 @@ import React, {
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { SidebarConfigContext } from './config';
|
||||
import { SidebarConfigContext, SidebarConfig } from './config';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { LocalStorage } from './localStorage';
|
||||
import useMediaQuery from '@material-ui/core/useMediaQuery';
|
||||
|
||||
export type SidebarPageClassKey = 'root';
|
||||
|
||||
const useStyles = ({ isPinned }: { isPinned: boolean }) => {
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
|
||||
return makeStyles<BackstageTheme>(
|
||||
const useStyles = ({
|
||||
isPinned,
|
||||
sidebarConfig,
|
||||
}: {
|
||||
isPinned: boolean;
|
||||
sidebarConfig: SidebarConfig;
|
||||
}) =>
|
||||
makeStyles<BackstageTheme>(
|
||||
theme => {
|
||||
return {
|
||||
root: {
|
||||
@@ -63,7 +67,6 @@ const useStyles = ({ isPinned }: { isPinned: boolean }) => {
|
||||
},
|
||||
{ name: 'BackstageSidebarPage' },
|
||||
)();
|
||||
};
|
||||
|
||||
/**
|
||||
* Type of `SidebarPinStateContext`
|
||||
@@ -113,6 +116,7 @@ export function SidebarPage(props: SidebarPageProps) {
|
||||
const [isPinned, setIsPinned] = useState(() =>
|
||||
LocalStorage.getSidebarPinState(),
|
||||
);
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
|
||||
const contentRef = useRef(null);
|
||||
|
||||
@@ -136,7 +140,7 @@ export function SidebarPage(props: SidebarPageProps) {
|
||||
|
||||
const toggleSidebarPinState = () => setIsPinned(!isPinned);
|
||||
|
||||
const classes = useStyles({ isPinned });
|
||||
const classes = useStyles({ isPinned, sidebarConfig });
|
||||
|
||||
return (
|
||||
<SidebarPinStateContext.Provider
|
||||
|
||||
@@ -67,7 +67,11 @@ const useStyles = ({ sidebarConfig }: { sidebarConfig: SidebarConfig }) =>
|
||||
display: 'none',
|
||||
},
|
||||
};
|
||||
<<<<<<< HEAD
|
||||
});
|
||||
=======
|
||||
})();
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
|
||||
/**
|
||||
* Returns a MUI `BottomNavigationAction`, which is aware of the current location & the selected item in the `BottomNavigation`,
|
||||
@@ -79,7 +83,11 @@ const useStyles = ({ sidebarConfig }: { sidebarConfig: SidebarConfig }) =>
|
||||
const MobileSidebarGroup = (props: SidebarGroupProps) => {
|
||||
const { to, label, icon, value } = props;
|
||||
const { sidebarConfig } = useContext(SidebarConfigContext);
|
||||
<<<<<<< HEAD
|
||||
const classes = useStyles({ sidebarConfig })();
|
||||
=======
|
||||
const classes = useStyles({ sidebarConfig });
|
||||
>>>>>>> Changed sidebar to accept new props sidebarOptions and submenuOptions
|
||||
const location = useLocation();
|
||||
const { selectedMenuItemIndex, setSelectedMenuItemIndex } =
|
||||
useContext(MobileSidebarContext);
|
||||
|
||||
@@ -20,6 +20,16 @@ const drawerWidthClosed = 72;
|
||||
const iconPadding = 24;
|
||||
const userBadgePadding = 18;
|
||||
|
||||
export type SidebarOptions = {
|
||||
drawerWidthClosed?: number;
|
||||
drawerWidthOpen?: number;
|
||||
};
|
||||
|
||||
export type SubmenuOptions = {
|
||||
drawerWidthClosed?: number;
|
||||
drawerWidthOpen?: number;
|
||||
};
|
||||
|
||||
export type SidebarConfig = {
|
||||
drawerWidthClosed: number;
|
||||
drawerWidthOpen: number;
|
||||
@@ -55,7 +65,7 @@ export const sidebarConfig = {
|
||||
};
|
||||
|
||||
export const makeSidebarConfig = (
|
||||
customSidebarConfig: Partial<SidebarConfig>,
|
||||
customSidebarConfig: Partial<SidebarOptions>,
|
||||
) => ({
|
||||
...sidebarConfig,
|
||||
...customSidebarConfig,
|
||||
@@ -78,12 +88,10 @@ export const submenuConfig = {
|
||||
};
|
||||
|
||||
export const makeSidebarSubmenuConfig = (
|
||||
customSubmenuConfig: Partial<SubmenuConfig>,
|
||||
customSidebarConfig: SidebarConfig,
|
||||
customSubmenuConfig: Partial<SubmenuOptions>,
|
||||
) => ({
|
||||
...submenuConfig,
|
||||
...customSubmenuConfig,
|
||||
defaultOpenDelayMs: customSidebarConfig.defaultOpenDelayMs + 200,
|
||||
});
|
||||
|
||||
export const SIDEBAR_INTRO_LOCAL_STORAGE =
|
||||
|
||||
Reference in New Issue
Block a user