Skip to content

Commit

Permalink
Refactor topnav menu items (#983)
Browse files Browse the repository at this point in the history
* refactor topnav menu items

* fix exports
  • Loading branch information
hidden4003 authored Aug 15, 2024
1 parent ea67a2f commit 49bced5
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 106 deletions.
27 changes: 27 additions & 0 deletions src/components/Layout/ExternalLinkMenuItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { Icon } from '@mdi/react';

type ExternalLinkMenuItemProps = {
url: string;
name: string;
icon: string;
};

const ExternalLinkMenuItem = React.memo(({
icon,
name,
url,
}: ExternalLinkMenuItemProps) => (
<a
href={url}
target="_blank"
rel="noreferrer noopener"
aria-label={`Open ${name}`}
data-tooltip-id="tooltip"
data-tooltip-content={name}
>
<Icon className="text-topnav-icon" path={icon} size={1} />
</a>
));

export default ExternalLinkMenuItem;
34 changes: 34 additions & 0 deletions src/components/Layout/LinkMenuItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { NavLink } from 'react-router-dom';
import { Icon } from '@mdi/react';
import cx from 'classnames';

type LinkMenuItemProps = {
icon: string;
onClick: () => void;
path: string;
text: string;
};

const LinkMenuItem = React.memo((props: LinkMenuItemProps) => {
const {
icon,
onClick,
path,
text,
} = props;
return (
<NavLink
to={path}
key={path.split('/')
.pop()}
className={({ isActive }) => cx('flex items-center gap-x-3', isActive && 'text-topnav-text-primary')}
onClick={onClick}
>
<Icon path={icon} size={1} />
{text}
</NavLink>
);
});

export default LinkMenuItem;
62 changes: 15 additions & 47 deletions src/components/Layout/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,24 @@
import React from 'react';
import {
mdiCogOutline,
mdiFormatListBulletedSquare,
mdiLayersTripleOutline,
mdiTabletDashboard,
mdiTextBoxOutline,
mdiTools,
} from '@mdi/js';
import { Icon } from '@mdi/react';
import cx from 'classnames';

const iconMap = {
dashboard: mdiTabletDashboard,
collection: mdiLayersTripleOutline,
utilities: mdiTools,
actions: mdiFormatListBulletedSquare,
log: mdiTextBoxOutline,
settings: mdiCogOutline,
};

enum IconType {
dashboard = 'dashboard',
collection = 'collection',
utilities = 'utilities',
actions = 'actions',
log = 'log',
settings = 'settings',
}

export type MenuItemProps = {
icon: IconType;
label: string;
className?: string;
onClick: React.MouseEventHandler<HTMLDivElement>;
id: string;
text: string;
icon: string;
onClick: () => void;
isHighlighted: boolean;
};

function MenuItem(props: MenuItemProps) {
const {
className,
icon,
label,
onClick,
} = props;

return (
<div className={cx(className, 'text-lg flex items-center')} onClick={onClick}>
<div className="flex w-5 content-center justify-center">
<Icon path={iconMap[icon]} size={1} horizontal vertical rotate={180} />
</div>
<div className="pl-4 font-semibold">{label}</div>
</div>
);
}
const MenuItem = React.memo(({ icon, id, isHighlighted, onClick, text }: MenuItemProps) => (
<div
key={id}
className={cx('flex items-center gap-x-3 cursor-pointer', isHighlighted && 'text-topnav-text-primary')}
onClick={onClick}
>
<Icon path={icon} size={1} />
{text}
</div>
));

export default MenuItem;
64 changes: 5 additions & 59 deletions src/components/Layout/TopNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ import {
} from '@mdi/js';
import { Icon } from '@mdi/react';
import cx from 'classnames';
import { startsWith } from 'lodash';
import semver from 'semver';
import { siDiscord } from 'simple-icons';

import DashboardSettingsModal from '@/components/Dashboard/DashboardSettingsModal';
import ActionsModal from '@/components/Dialogs/ActionsModal';
import Button from '@/components/Input/Button';
import ExternalLinkMenuItem from '@/components/Layout/ExternalLinkMenuItem';
import LinkMenuItem from '@/components/Layout/LinkMenuItem';
import MenuItem from '@/components/Layout/MenuItem';
import ShokoIcon from '@/components/ShokoIcon';
import toast from '@/components/Toast';
import Events from '@/core/events';
Expand All @@ -48,64 +52,6 @@ import type { RootState } from '@/core/store';

const { DEV, VITE_APPVERSION } = import.meta.env;

const MenuItem = React.memo((
{ icon, id, isHighlighted, onClick, text }: {
id: string;
text: string;
icon: string;
onClick: () => void;
isHighlighted: boolean;
},
) => {
const handleClick = useEventCallback((event: React.MouseEvent) => {
event.preventDefault();
onClick();
});

return (
<NavLink
to={id}
key={id}
className={({ isActive }) =>
cx('flex items-center gap-x-3', (isActive || isHighlighted) && 'text-topnav-text-primary')}
onClick={handleClick}
>
<Icon path={icon} size={1} />
{text}
</NavLink>
);
});

const LinkMenuItem = React.memo((
props: { icon: string, onClick: () => void, path: string, text: string },
) => {
const { icon, onClick, path, text } = props;
return (
<NavLink
to={path}
key={path.split('/').pop()}
className={({ isActive }) => cx('flex items-center gap-x-3', isActive && 'text-topnav-text-primary')}
onClick={onClick}
>
<Icon path={icon} size={1} />
{text}
</NavLink>
);
});

const ExternalLinkMenuItem = React.memo(({ icon, name, url }: { url: string, name: string, icon: string }) => (
<a
href={url}
target="_blank"
rel="noreferrer noopener"
aria-label={`Open ${name}`}
data-tooltip-id="tooltip"
data-tooltip-content={name}
>
<Icon className="text-topnav-icon" path={icon} size={1} />
</a>
));

const QueueCount = () => {
const queue = useSelector((state: RootState) => state.mainpage.queueStatus);

Expand Down Expand Up @@ -276,7 +222,7 @@ function TopNav() {
closeModalsAndSubmenus(undefined, 'utilities');
setShowUtilitiesMenu(prev => !prev);
}}
isHighlighted={showUtilitiesMenu}
isHighlighted={showUtilitiesMenu || startsWith(pathname, '/webui/utilities/')}
/>
<LinkMenuItem
onClick={closeModalsAndSubmenus}
Expand Down

0 comments on commit 49bced5

Please sign in to comment.