@cullsin/lnc-menu 5.1.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,114 +6,52 @@ import List from "@mui/material/List";
6
6
  import ListItem from "@mui/material/ListItem";
7
7
  import ListItemIcon from "@mui/material/ListItemIcon";
8
8
  import ListItemText from "@mui/material/ListItemText";
9
- import Menu from "@mui/material/Menu";
10
- import MenuItem from "@mui/material/MenuItem";
11
9
  import Tooltip from "@mui/material/Tooltip";
12
10
  import * as React from "react";
13
11
  import { getTranslations } from "./translations";
14
12
  function SideMenu({ useDrawer, SampleMgmtIcon, location, language = 'en' }) {
15
13
  const [selectedMainMenu, setSelectedMainMenu] = React.useState(null);
16
- const [selectedSubMenuPath, setSelectedSubMenuPath] = React.useState(null);
17
- const [openMenuIndex, setOpenMenuIndex] = React.useState(null);
18
- const { isDrawerOpen, toggleDrawer } = useDrawer();
19
- const [anchorEl, setAnchorEl] = React.useState(null);
14
+ const { isDrawerOpen } = useDrawer();
20
15
  const t = React.useMemo(() => getTranslations(language), [language]);
21
16
  const menuItems = React.useMemo(() => [
22
17
  {
23
18
  text: t.menu.patientManagement,
24
19
  icon: _jsx(RecentActorsOutlinedIcon, {}),
25
- subMenu: [
26
- { text: t.menu.patient, path: `/patient/${language}/patient-listing` }
27
- ],
20
+ path: `/patient/${language}/patient-listing`,
28
21
  },
29
22
  {
30
23
  text: t.menu.sampleManagement,
31
24
  icon: _jsx(SampleMgmtIcon, {}),
32
- subMenu: [
33
- { text: t.menu.sampleListing, path: `/sample/${language}/sample-listing` }
34
- ],
25
+ path: `/sample/${language}/sample-listing`,
35
26
  },
36
27
  ], [SampleMgmtIcon, t, language]);
37
- // 🔁 Sync selection with current path
28
+ // Sync selection with current path
38
29
  React.useEffect(() => {
39
30
  const currentPath = location.pathname;
40
- for (const mainItem of menuItems) {
41
- if (mainItem.subMenu) {
42
- for (const sub of mainItem.subMenu) {
43
- if (currentPath.startsWith(sub.path)) {
44
- setSelectedMainMenu(mainItem.text);
45
- setSelectedSubMenuPath(sub.path);
46
- return;
47
- }
48
- }
49
- }
50
- else if (mainItem.path && currentPath.startsWith(mainItem.path)) {
51
- setSelectedMainMenu(mainItem.text);
52
- setSelectedSubMenuPath(null);
31
+ for (const item of menuItems) {
32
+ if (currentPath.startsWith(item.path)) {
33
+ setSelectedMainMenu(item.text);
53
34
  return;
54
35
  }
55
36
  }
56
37
  setSelectedMainMenu(null);
57
- setSelectedSubMenuPath(null);
58
- handleMenuClose();
59
38
  }, [location.pathname, menuItems]);
60
- const handleMenuOpen = (event, index) => {
61
- setAnchorEl(event.currentTarget);
62
- setOpenMenuIndex(index);
63
- };
64
- const handleMenuClose = () => {
65
- setAnchorEl(null);
66
- setOpenMenuIndex(null);
67
- };
68
- const handleSubMenuItemClick = (path, parentText) => {
69
- setSelectedMainMenu(parentText);
70
- setSelectedSubMenuPath(path);
71
- handleMenuClose();
72
- if (isDrawerOpen)
73
- toggleDrawer();
74
- window.location.href = path;
39
+ const handleMenuClick = (item) => {
40
+ setSelectedMainMenu(item.text);
41
+ window.location.href = item.path;
75
42
  };
76
- return (_jsx(Box, { sx: { display: "flex", height: "100%" }, children: _jsx(Drawer, { open: isDrawerOpen, variant: "permanent", className: "parent-container", sx: {
43
+ return (_jsx(Box, { className: "side-menu-container", children: _jsx(Drawer, { variant: "permanent", className: "parent-container", sx: {
77
44
  width: isDrawerOpen ? 230 : 64,
78
45
  flexShrink: 0,
79
46
  "& .MuiDrawer-paper": {
80
47
  width: isDrawerOpen ? 230 : 64,
81
48
  transition: "width 0.3s ease",
82
- position: "relative",
83
- height: "100%",
49
+ position: "sticky",
50
+ top: "65px",
51
+ height: "calc(100vh - 65px)",
84
52
  borderRight: "1px solid #B1BECB",
85
53
  overflowY: "auto",
86
54
  },
87
- }, children: _jsx(List, { children: menuItems.map((item, index) => (_jsxs(React.Fragment, { children: [_jsx(Tooltip, { title: item.text, placement: "right", disableHoverListener: isDrawerOpen, children: _jsxs(ListItem, { button: true, selected: selectedMainMenu === item.text, className: selectedMainMenu === item.text ? "selected" : "", onClick: (event) => {
88
- if (item.subMenu) {
89
- if (openMenuIndex === index) {
90
- handleMenuClose();
91
- }
92
- else {
93
- handleMenuOpen(event, index);
94
- }
95
- }
96
- else if (item.path) {
97
- setSelectedMainMenu(item.text);
98
- setSelectedSubMenuPath(null);
99
- if (isDrawerOpen)
100
- toggleDrawer();
101
- window.location.href = item.path;
102
- }
103
- else if (item.onClick) {
104
- item.onClick();
105
- setSelectedMainMenu(item.text);
106
- }
107
- }, children: [_jsx(ListItemIcon, { children: item.icon }), isDrawerOpen && _jsx(ListItemText, { primary: item.text })] }) }), item.subMenu && anchorEl && openMenuIndex === index && (_jsxs(Menu, { className: `app-menu-item ${!isDrawerOpen ? 'collapsed-menu' : ''}`, anchorEl: anchorEl, open: Boolean(anchorEl), onClose: handleMenuClose, anchorOrigin: {
108
- vertical: "top",
109
- horizontal: "right",
110
- }, transformOrigin: {
111
- vertical: "top",
112
- horizontal: "left",
113
- }, PaperProps: {
114
- style: {
115
- marginLeft: 8,
116
- },
117
- }, children: [!isDrawerOpen && (_jsx("span", { className: "submenu-title", children: item.text })), item.subMenu.map((subItem) => (_jsx(MenuItem, { selected: selectedSubMenuPath === subItem.path, onClick: () => handleSubMenuItemClick(subItem.path, item.text), children: subItem.text }, subItem.text)))] }))] }, index))) }) }) }));
55
+ }, children: _jsx(List, { children: menuItems.map((item, index) => (_jsx(Tooltip, { title: item.text, placement: "right", disableHoverListener: isDrawerOpen, children: _jsxs(ListItem, { button: true, selected: selectedMainMenu === item.text, className: selectedMainMenu === item.text ? "selected" : "", onClick: () => handleMenuClick(item), children: [_jsx(ListItemIcon, { children: item.icon }), isDrawerOpen && _jsx(ListItemText, { primary: item.text })] }) }, index))) }) }) }));
118
56
  }
119
57
  export default SideMenu;
@@ -1,16 +1,27 @@
1
1
  //overwritten the default MUI css
2
2
 
3
+ // Sticky side menu container
4
+ .side-menu-container {
5
+ position: sticky;
6
+ top: 65px;
7
+ height: calc(100vh - 65px);
8
+ display: flex;
9
+ flex-shrink: 0;
10
+ }
11
+
3
12
  .MuiBox-root .MuiList-root {
4
13
  background: linear-gradient(to bottom, #1e2f97, #0b1659) !important;
5
14
  color: #fff;
6
15
  height: 100%;
7
- bottom: 0; // Ensure drawer stretches till bottom
16
+ bottom: 0;
8
17
  padding: 20px 0;
9
18
  }
10
19
 
11
20
  .MuiList-root {
12
21
  .MuiListItem-root {
13
22
  padding: 15px;
23
+
24
+ // Selected state - capsule style with icon and text combined
14
25
  &.selected {
15
26
  padding: 7px;
16
27
 
@@ -19,51 +30,63 @@
19
30
  color: #1e2f97;
20
31
  padding: 10px;
21
32
  min-width: 25px;
22
- border-top-left-radius: 5px;
23
- border-bottom-left-radius: 5px;
24
-
25
- &:only-of-type {
26
- border-top-right-radius: 5px;
27
- border-bottom-right-radius: 5px;
33
+ border-top-left-radius: 20px;
34
+ border-bottom-left-radius: 20px;
35
+ border-top-right-radius: 0;
36
+ border-bottom-right-radius: 0;
37
+
38
+ // When collapsed (icon only), make full capsule
39
+ &:only-child {
40
+ border-radius: 20px;
28
41
  }
29
42
  }
30
43
 
31
44
  .MuiListItemText-root {
45
+ margin: 0;
46
+
32
47
  span {
33
48
  background: linear-gradient(to bottom, #7ad4f7, #20a9ef) !important;
34
- padding: 10px 0;
49
+ padding: 10px 15px 10px 5px;
35
50
  min-width: 25px;
36
- border-top-right-radius: 5px;
37
- border-bottom-right-radius: 5px;
51
+ border-top-right-radius: 20px;
52
+ border-bottom-right-radius: 20px;
53
+ display: inline-block;
38
54
  }
39
55
  }
40
56
  }
41
57
 
58
+ // Hover state - capsule style
42
59
  &:hover:not(.selected) {
43
- padding: 5px 7px;
60
+ padding: 7px;
44
61
 
45
62
  .MuiListItemIcon-root {
46
63
  background: linear-gradient(to bottom, #7ad4f7, #20a9ef) !important;
47
64
  color: #1e2f97;
48
65
  padding: 10px;
49
66
  min-width: 25px;
50
- border-top-left-radius: 5px;
51
- border-bottom-left-radius: 5px;
52
-
53
- &:only-of-type {
54
- border-top-right-radius: 5px;
55
- border-bottom-right-radius: 5px;
67
+ border-top-left-radius: 20px;
68
+ border-bottom-left-radius: 20px;
69
+ border-top-right-radius: 0;
70
+ border-bottom-right-radius: 0;
71
+
72
+ // When collapsed (icon only), make full capsule
73
+ &:only-child {
74
+ border-radius: 20px;
56
75
  }
57
76
  }
58
77
 
59
78
  .MuiListItemText-root {
79
+ margin: 0;
80
+
60
81
  span {
61
82
  background: linear-gradient(to bottom, #7ad4f7, #20a9ef) !important;
62
- padding: 10px 0;
83
+ padding: 10px 15px 10px 5px;
63
84
  min-width: 25px;
64
- border-top-right-radius: 5px;
65
- border-bottom-right-radius: 5px;
85
+ border-top-right-radius: 20px;
86
+ border-bottom-right-radius: 20px;
87
+ display: inline-block;
66
88
  }
89
+
67
90
  .MuiTypography-root {
68
91
  color: #1e2f97;
69
92
  }
@@ -79,6 +102,7 @@
79
102
  .MuiListItemText-root {
80
103
  margin-top: 0;
81
104
  margin-bottom: 0;
105
+
82
106
  .MuiTypography-root {
83
107
  font: 14px/24px "OpenSans-SemiBold";
84
108
  color: #fff;
@@ -89,59 +113,6 @@
89
113
  }
90
114
  }
91
115
 
92
- .app-menu-item {
93
- .MuiList-root {
94
- &.MuiMenu-list {
95
- background: linear-gradient(to bottom, #586d81, #3e4f60) !important;
96
- color: #fff;
97
- width: 200px;
98
- padding: 10px;
99
- position: relative;
100
- overflow: visible;
101
- .submenu-title {
102
- text-transform: uppercase;
103
- font: 12px / 18px "OpenSans-Regular";
104
- color: #efffff;
105
- padding: 0 0 5px 10px;
106
- display: block;
107
- border-bottom: 1px solid rgba(255, 255, 255, 0.2);
108
- margin-bottom: 5px;
109
- }
110
- .MuiMenuItem-root {
111
- &.Mui-focusVisible {
112
- background-color: transparent;
113
- }
114
-
115
- &:hover {
116
- font: 16px/24px "OpenSans-SemiBold";
117
- background: #374451;
118
- border-radius: 6px;
119
- }
120
- }
121
- }
122
- }
123
-
124
- &.collapsed-menu {
125
- .MuiList-root {
126
- &.MuiMenu-list {
127
- &::before {
128
- content: "";
129
- position: absolute;
130
- top: 15px;
131
- left: -8px;
132
- width: 0;
133
- height: 0;
134
- border-top: 8px solid transparent;
135
- border-bottom: 8px solid transparent;
136
- border-right: 8px solid #516578;
137
- z-index: 2;
138
- }
139
- }
140
- }
141
- }
142
- }
143
-
144
-
145
116
  .MuiPopover-root {
146
117
  .MuiPaper-root {
147
118
  overflow: visible;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cullsin/lnc-menu",
3
- "version": "5.1.0",
3
+ "version": "5.2.0",
4
4
  "description": "Reusable SideMenu component for MedGenome LNC platform using MUI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",