Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rename Menu components #2996

Draft
wants to merge 1 commit into
base: next
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { Close, Hamburger, HamburgerClose, HamburgerOpen } from "@comet/admin-icons";
import { ComponentsOverrides, css, IconButton, IconButtonClassKey, IconButtonProps, Theme, useThemeProps } from "@mui/material";
import { MainNavigationContext } from "mui/mainNavigation/Context";
import { ReactNode, useContext } from "react";

import { createComponentSlot } from "../../helpers/createComponentSlot";
import { MenuContext } from "../../mui/menu/Context";

export type AppHeaderMenuButtonProps = IconButtonProps;

export type AppHeaderMenuButtonClassKey = IconButtonClassKey;

export const AppHeaderMenuButton = (inProps: AppHeaderMenuButtonProps) => {
const { children: propChildren, ...restProps } = useThemeProps({ props: inProps, name: "CometAdminAppHeaderMenuButton" });
const { toggleOpen, open, drawerVariant } = useContext(MenuContext);
const { toggleOpen, open, drawerVariant } = useContext(MainNavigationContext);

const closeIcons: Record<typeof drawerVariant, ReactNode> = {
temporary: <Close />,
Expand Down
20 changes: 10 additions & 10 deletions packages/admin/admin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,18 @@ export { useStoredState } from "./hooks/useStoredState";
export { InputWithPopper, InputWithPopperComponents, InputWithPopperProps } from "./inputWithPopper/InputWithPopper";
export { InputWithPopperClassKey } from "./inputWithPopper/InputWithPopper.slots";
export { messages } from "./messages";
export { MainNavigationCollapsibleItem, MainNavigationCollapsibleItemProps } from "./mui/mainNavigation/CollapsibleItem";
export { MainNavigationCollapsibleItemClassKey } from "./mui/mainNavigation/CollapsibleItem.styles";
export { IMainNavigationContext, IWithMainNavigation, MainNavigationContext, withMenu } from "./mui/mainNavigation/Context";
export { MainNavigationItem, MainNavigationItemProps } from "./mui/mainNavigation/Item";
export { MainNavigationItemClassKey } from "./mui/mainNavigation/Item.styles";
export { MainNavigationItemAnchorLink, MainNavigationItemAnchorLinkProps } from "./mui/mainNavigation/ItemAnchorLink";
export { MainNavigationItemGroup, MainNavigationItemGroupClassKey, MainNavigationItemGroupProps } from "./mui/mainNavigation/ItemGroup";
export { MainNavigationItemRouterLink, MainNavigationItemRouterLinkProps } from "./mui/mainNavigation/ItemRouterLink";
export { MainNavigation, MainNavigationProps } from "./mui/mainNavigation/MainNavigation";
export { MainNavigationClassKey } from "./mui/mainNavigation/MainNavigation.styles";
export { MasterLayout, MasterLayoutClassKey, MasterLayoutProps } from "./mui/MasterLayout";
export { MasterLayoutContext } from "./mui/MasterLayoutContext";
export { MenuCollapsibleItem, MenuCollapsibleItemProps } from "./mui/menu/CollapsibleItem";
export { MenuCollapsibleItemClassKey } from "./mui/menu/CollapsibleItem.styles";
export { IMenuContext, IWithMenu, MenuContext, withMenu } from "./mui/menu/Context";
export { MenuItem, MenuItemProps } from "./mui/menu/Item";
export { MenuItemClassKey } from "./mui/menu/Item.styles";
export { MenuItemAnchorLink, MenuItemAnchorLinkProps } from "./mui/menu/ItemAnchorLink";
export { MenuItemGroup, MenuItemGroupClassKey, MenuItemGroupProps } from "./mui/menu/ItemGroup";
export { MenuItemRouterLink, MenuItemRouterLinkProps } from "./mui/menu/ItemRouterLink";
export { Menu, MenuProps } from "./mui/menu/Menu";
export { MenuClassKey } from "./mui/menu/Menu.styles";
export { MuiThemeProvider } from "./mui/ThemeProvider";
export { RouterBrowserRouter } from "./router/BrowserRouter";
export { RouterConfirmationDialog, RouterConfirmationDialogClassKey, RouterConfirmationDialogProps } from "./router/ConfirmationDialog";
Expand Down
6 changes: 3 additions & 3 deletions packages/admin/admin/src/mui/MasterLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { AppHeader } from "../appHeader/AppHeader";
import { AppHeaderMenuButton } from "../appHeader/menuButton/AppHeaderMenuButton";
import { createComponentSlot } from "../helpers/createComponentSlot";
import { ThemedComponentBaseProps } from "../helpers/ThemedComponentBaseProps";
import { MainNavigationContext } from "./mainNavigation/Context";
import { MasterLayoutContext } from "./MasterLayoutContext";
import { MenuContext } from "./menu/Context";

export type MasterLayoutClassKey = "root" | "header" | "contentWrapper";

Expand Down Expand Up @@ -71,7 +71,7 @@ export function MasterLayout(inProps: MasterLayoutProps) {
};

return (
<MenuContext.Provider value={{ open, toggleOpen, drawerVariant, setDrawerVariant }}>
<MainNavigationContext.Provider value={{ open, toggleOpen, drawerVariant, setDrawerVariant }}>
<MasterLayoutContext.Provider value={{ headerHeight }}>
<CssBaseline />
<Root {...slotProps?.root} {...restProps}>
Expand All @@ -93,7 +93,7 @@ export function MasterLayout(inProps: MasterLayoutProps) {
</ContentWrapper>
</Root>
</MasterLayoutContext.Provider>
</MenuContext.Provider>
</MainNavigationContext.Provider>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ import { Typography } from "@mui/material";
import { css } from "@mui/material/styles";

import { createComponentSlot } from "../../helpers/createComponentSlot";
import { IMenuContext } from "./Context";
import { MenuItem as CometMenuItem, MenuItemLevel } from "./Item";
import { IMainNavigationContext } from "./Context";
import { MainNavigationItem, MainNavigationItemLevel } from "./Item";

export type MenuCollapsibleItemClassKey = "root" | "open" | "childSelected" | "menuItem" | "itemTitle" | "collapsibleIndicator";
export type MainNavigationCollapsibleItemClassKey = "root" | "open" | "childSelected" | "menuItem" | "itemTitle" | "collapsibleIndicator";

export type OwnerState = {
childSelected: boolean;
open: boolean;
menuOpen: boolean;
subMenuOpen: boolean;
level: MenuItemLevel;
variant: IMenuContext["drawerVariant"];
level: MainNavigationItemLevel;
variant: IMainNavigationContext["drawerVariant"];
};

export const Root = createComponentSlot("div")<MenuCollapsibleItemClassKey, OwnerState>({
componentName: "MenuCollapsibleItem",
export const Root = createComponentSlot("div")<MainNavigationCollapsibleItemClassKey, OwnerState>({
componentName: "MainNavigationCollapsibleItem",
slotName: "root",
classesResolver: (ownerState) => {
return [ownerState.open && "open", ownerState.childSelected && "childSelected"];
Expand All @@ -32,8 +32,8 @@ export const Root = createComponentSlot("div")<MenuCollapsibleItemClassKey, Owne
`,
);

export const MenuItem = createComponentSlot(CometMenuItem)<MenuCollapsibleItemClassKey, OwnerState>({
componentName: "MenuCollapsibleItem",
export const MenuItem = createComponentSlot(MainNavigationItem)<MainNavigationCollapsibleItemClassKey, OwnerState>({
componentName: "MainNavigationCollapsibleItem",
slotName: "menuItem",
})(
({ theme, ownerState }) => css`
Expand All @@ -59,12 +59,12 @@ export const MenuItem = createComponentSlot(CometMenuItem)<MenuCollapsibleItemCl

${ownerState.childSelected &&
css`
.CometAdminMenuItem-text,
.CometAdminMenuItem-icon {
.CometAdminMainNavigationItem-text,
.CometAdminMainNavigationItem-icon {
color: ${theme.palette.primary.main};
}

.CometAdminMenuItem-primary {
.CometAdminMainNavigationItem-primary {
${(ownerState.level === 2 || ownerState.level === 3) &&
css`
font-weight: 600;
Expand All @@ -74,8 +74,8 @@ export const MenuItem = createComponentSlot(CometMenuItem)<MenuCollapsibleItemCl
`,
);

export const ItemTitle = createComponentSlot(Typography)<MenuCollapsibleItemClassKey>({
componentName: "MenuCollapsibleItem",
export const ItemTitle = createComponentSlot(Typography)<MainNavigationCollapsibleItemClassKey>({
componentName: "MainNavigationCollapsibleItem",
slotName: "itemTitle",
})(
({ theme }) => css`
Expand All @@ -87,8 +87,8 @@ export const ItemTitle = createComponentSlot(Typography)<MenuCollapsibleItemClas
`,
);

export const CollapsibleIndicator = createComponentSlot("div")<MenuCollapsibleItemClassKey, OwnerState>({
componentName: "MenuCollapsibleItem",
export const CollapsibleIndicator = createComponentSlot("div")<MainNavigationCollapsibleItemClassKey, OwnerState>({
componentName: "MainNavigationCollapsibleItem",
slotName: "collapsibleIndicator",
})(
({ theme, ownerState }) => css`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ import { Children, cloneElement, MouseEvent, ReactElement, ReactNode, useContext
import { matchPath, useLocation } from "react-router";

import { ThemedComponentBaseProps } from "../../helpers/ThemedComponentBaseProps";
import { CollapsibleIndicator, ItemTitle, MenuCollapsibleItemClassKey, MenuItem, OwnerState, Root } from "./CollapsibleItem.styles";
import { MenuContext } from "./Context";
import { MenuItem as CometMenuItem, MenuItemLevel, MenuItemProps } from "./Item";
import { MenuItemRouterLinkProps } from "./ItemRouterLink";
import { CollapsibleIndicator, ItemTitle, MainNavigationCollapsibleItemClassKey, MenuItem, OwnerState, Root } from "./CollapsibleItem.styles";
import { MainNavigationContext } from "./Context";
import { MainNavigationItem, MainNavigationItemLevel, MainNavigationItemProps } from "./Item";
import { MainNavigationItemRouterLinkProps } from "./ItemRouterLink";

export type MenuChild = ReactElement<MenuCollapsibleItemProps | MenuItemRouterLinkProps | MenuItemProps>;
export type MainNavigationChild = ReactElement<MainNavigationCollapsibleItemProps | MainNavigationItemRouterLinkProps | MainNavigationItemProps>;

export interface MenuCollapsibleItemProps
extends Omit<MenuItemProps, "slotProps">,
export interface MainNavigationCollapsibleItemProps
extends Omit<MainNavigationItemProps, "slotProps">,
ThemedComponentBaseProps<{
root: "div";
menuItem: typeof CometMenuItem;
menuItem: typeof MainNavigationItem;
itemTitle: typeof Typography;
collapsibleIndicator: "div";
}> {
children: MenuChild | MenuChild[];
children: MainNavigationChild | MainNavigationChild[];
openByDefault?: boolean;
isMenuOpen?: boolean;
iconMapping?: {
Expand All @@ -30,7 +30,7 @@ export interface MenuCollapsibleItemProps
};
}

export const MenuCollapsibleItem = (inProps: MenuCollapsibleItemProps) => {
export const MainNavigationCollapsibleItem = (inProps: MainNavigationCollapsibleItemProps) => {
const {
classes,
level = 1,
Expand All @@ -55,8 +55,8 @@ export const MenuCollapsibleItem = (inProps: MenuCollapsibleItemProps) => {
secondLevelHoverIndicator: secondLevelHoverIndicatorIcon = <ChevronRight color="inherit" fontSize="inherit" />,
} = iconMapping ?? {};

const { drawerVariant } = useContext(MenuContext);
const itemLevel: MenuItemLevel = level ?? 1;
const { drawerVariant } = useContext(MainNavigationContext);
const itemLevel: MainNavigationItemLevel = level ?? 1;
const hasSelectedChild = useRef(false);
const location = useLocation();

Expand All @@ -69,12 +69,14 @@ export const MenuCollapsibleItem = (inProps: MenuCollapsibleItemProps) => {
}, [isMenuOpen]);

const childElements = useMemo(() => {
function checkIfPathInLocation(child: ReactElement<MenuCollapsibleItemProps | MenuItemRouterLinkProps | MenuItemProps>) {
function checkIfPathInLocation(
child: ReactElement<MainNavigationCollapsibleItemProps | MainNavigationItemRouterLinkProps | MainNavigationItemProps>,
) {
return "to" in child.props && matchPath(location.pathname, { path: child.props.to, strict: true });
}
hasSelectedChild.current = false;

return Children.map(children, (child: MenuChild) => {
return Children.map(children, (child: MainNavigationChild) => {
// child is selected
if (checkIfPathInLocation(child)) {
hasSelectedChild.current = true;
Expand All @@ -83,15 +85,17 @@ export const MenuCollapsibleItem = (inProps: MenuCollapsibleItemProps) => {

// sub child is selected
const subChildElements =
"children" in child.props ? Children.map(child?.props?.children, (child: MenuChild) => child) : ([] as MenuChild[]);
if (subChildElements?.some((child: MenuChild) => child.props && checkIfPathInLocation(child))) {
"children" in child.props
? Children.map(child?.props?.children, (child: MainNavigationChild) => child)
: ([] as MainNavigationChild[]);
if (subChildElements?.some((child: MainNavigationChild) => child.props && checkIfPathInLocation(child))) {
hasSelectedChild.current = true;
setIsSubmenuOpen(true);
}

const newItemLevel = itemLevel + 1;

return cloneElement<MenuCollapsibleItemProps | MenuItemRouterLinkProps | MenuItemProps>(child, {
return cloneElement<MainNavigationCollapsibleItemProps | MainNavigationItemRouterLinkProps | MainNavigationItemProps>(child, {
level: newItemLevel === 1 || newItemLevel === 2 || newItemLevel === 3 ? newItemLevel : undefined,
isMenuOpen,
isCollapsibleOpen: isSubmenuOpen,
Expand Down Expand Up @@ -215,11 +219,11 @@ export const MenuCollapsibleItem = (inProps: MenuCollapsibleItemProps) => {

declare module "@mui/material/styles" {
interface ComponentNameToClassKey {
CometAdminMenuCollapsibleItem: MenuCollapsibleItemClassKey;
CometAdminMenuCollapsibleItem: MainNavigationCollapsibleItemClassKey;
}

interface ComponentsPropsList {
CometAdminMenuCollapsibleItem: MenuCollapsibleItemProps;
CometAdminMenuCollapsibleItem: MainNavigationCollapsibleItemProps;
}

interface Components {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { ComponentType, createContext, Dispatch, FunctionComponent, SetStateAction } from "react";

export interface IMenuContext {
export interface IMainNavigationContext {
open: boolean;
toggleOpen: () => void;
drawerVariant: "temporary" | "permanent";
setDrawerVariant: Dispatch<SetStateAction<"temporary" | "permanent">>;
}

export interface IWithMenu {
menu: IMenuContext;
export interface IWithMainNavigation {
menu: IMainNavigationContext;
}
export const MenuContext = createContext<IMenuContext>({
export const MainNavigationContext = createContext<IMainNavigationContext>({
open: false,
toggleOpen: () => {
// nothing
Expand All @@ -21,8 +21,8 @@ export const MenuContext = createContext<IMenuContext>({
},
});

export const withMenu = <P extends object>(WrappedComponent: ComponentType<P & IWithMenu>): FunctionComponent<P> => {
export const withMenu = <P extends object>(WrappedComponent: ComponentType<P & IWithMainNavigation>): FunctionComponent<P> => {
return (props: P) => {
return <MenuContext.Consumer>{(value) => <WrappedComponent {...props} menu={value!} />}</MenuContext.Consumer>;
return <MainNavigationContext.Consumer>{(value) => <WrappedComponent {...props} menu={value!} />}</MainNavigationContext.Consumer>;
};
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { css, ListItemButton, ListItemIcon, listItemIconClasses, ListItemText, listItemTextClasses } from "@mui/material";

import { createComponentSlot } from "../../helpers/createComponentSlot";
import { IMenuContext } from "./Context";
import { MenuItemLevel } from "./Item";
import { IMainNavigationContext } from "./Context";
import { MainNavigationItemLevel } from "./Item";

export type MenuItemClassKey =
export type MainNavigationItemClassKey =
| "root"
| "level1"
| "level2"
Expand All @@ -17,17 +17,17 @@ export type MenuItemClassKey =
| "text";

export type OwnerState = {
level: MenuItemLevel;
level: MainNavigationItemLevel;
open: boolean;
collapsibleOpen: boolean;
hasSubItems: boolean;
hasIcon: boolean;
hasSecondaryText: boolean;
hasSecondaryAction: boolean;
variant: IMenuContext["drawerVariant"];
variant: IMainNavigationContext["drawerVariant"];
};

export const Root = createComponentSlot(ListItemButton)<MenuItemClassKey, OwnerState>({
export const Root = createComponentSlot(ListItemButton)<MainNavigationItemClassKey, OwnerState>({
componentName: "MenuItem",
slotName: "root",
classesResolver(ownerState) {
Expand Down Expand Up @@ -321,12 +321,12 @@ export const Root = createComponentSlot(ListItemButton)<MenuItemClassKey, OwnerS
`,
);

export const Icon = createComponentSlot(ListItemIcon)<MenuItemClassKey, OwnerState>({
export const Icon = createComponentSlot(ListItemIcon)<MainNavigationItemClassKey, OwnerState>({
componentName: "MenuItem",
slotName: "icon",
})();

export const Text = createComponentSlot(ListItemText)<MenuItemClassKey, OwnerState>({
export const Text = createComponentSlot(ListItemText)<MainNavigationItemClassKey, OwnerState>({
componentName: "MenuItem",
slotName: "text",
})();
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ import { ComponentsOverrides, ListItemButton, ListItemButtonProps, ListItemIcon,
import { ReactElement, ReactNode, useContext } from "react";

import { ThemedComponentBaseProps } from "../../helpers/ThemedComponentBaseProps";
import { MenuContext } from "./Context";
import { Icon, MenuItemClassKey, OwnerState, Root, Text } from "./Item.styles";
import { MainNavigationContext } from "./Context";
import { Icon, MainNavigationItemClassKey, OwnerState, Root, Text } from "./Item.styles";

export type MenuItemLevel = 1 | 2 | 3;
export type MainNavigationItemLevel = 1 | 2 | 3;

export interface MenuItemProps
export interface MainNavigationItemProps
extends ThemedComponentBaseProps<{
root: typeof ListItemButton;
icon: typeof ListItemIcon;
text: typeof ListItemText;
}>,
ListItemButtonProps {
level?: MenuItemLevel;
level?: MainNavigationItemLevel;
primary: ReactNode;
secondary?: ReactNode;
icon?: ReactElement;
Expand All @@ -24,7 +24,7 @@ export interface MenuItemProps
hasSubitems?: boolean;
}

export const MenuItem = (inProps: MenuItemProps) => {
export const MainNavigationItem = (inProps: MainNavigationItemProps) => {
const {
primary,
secondary,
Expand All @@ -38,7 +38,7 @@ export const MenuItem = (inProps: MenuItemProps) => {
...restProps
} = useThemeProps({ props: inProps, name: "CometAdminMenuItem" });

const { drawerVariant } = useContext(MenuContext);
const { drawerVariant } = useContext(MainNavigationContext);

if (level > 3) throw new Error("Maximum nesting level of 2 exceeded.");

Expand Down Expand Up @@ -70,11 +70,11 @@ export const MenuItem = (inProps: MenuItemProps) => {

declare module "@mui/material/styles" {
interface ComponentsPropsList {
CometAdminMenuItem: MenuItemProps;
CometAdminMenuItem: MainNavigationItemProps;
}

interface ComponentNameToClassKey {
CometAdminMenuItem: MenuItemClassKey;
CometAdminMenuItem: MainNavigationItemClassKey;
}

interface Components {
Expand Down
Loading
Loading