@nethru/ui 1.0.82 → 2.0.1

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.
Files changed (141) hide show
  1. package/base/AddableFormList.js +56 -0
  2. package/base/Alert.js +27 -0
  3. package/base/Checkbox.js +20 -0
  4. package/base/CircularProgressButton.js +36 -0
  5. package/base/ColumnedSection.js +44 -0
  6. package/base/DropdownButton.js +74 -0
  7. package/base/MainHeader.js +56 -0
  8. package/base/MenuItem.js +92 -0
  9. package/base/PropertyTable.js +69 -0
  10. package/base/SearchTextField.js +44 -0
  11. package/base/SearchableSelect.js +64 -0
  12. package/base/Select.js +33 -0
  13. package/{dist → base}/Slider.js +12 -13
  14. package/base/Snackbar.js +33 -0
  15. package/base/Switch.js +20 -0
  16. package/base/assets/icons.js +390 -0
  17. package/base/assets/images.js +1 -0
  18. package/{dist → base}/colors/blue.js +3 -1
  19. package/{dist → base}/colors/blueGrey.js +1 -1
  20. package/base/datagrid/DataGrid.js +57 -0
  21. package/base/datagrid/Footer.js +51 -0
  22. package/base/datagrid/Pagination.js +24 -0
  23. package/base/dialog/AlertDialog.js +21 -0
  24. package/base/dialog/ConfirmDialog.js +29 -0
  25. package/base/dialog/Dialog.js +56 -0
  26. package/base/dialog/SimpleDialog.js +33 -0
  27. package/{dist → base}/error/Error.js +1 -2
  28. package/base/frame/AppBar.js +54 -0
  29. package/base/frame/Brand.js +36 -0
  30. package/base/frame/Frame.js +49 -0
  31. package/{dist → base/frame}/sidebar/MenuToggler.js +14 -3
  32. package/{dist → base/frame}/sidebar/PrimaryMenu.js +15 -20
  33. package/base/frame/sidebar/SecondaryMenu.js +41 -0
  34. package/{dist → base/frame}/sidebar/Sidebar.js +21 -10
  35. package/base/frame/sidebar/SidebarContext.js +74 -0
  36. package/base/frame/sidebar/css/primary.module.css +69 -0
  37. package/base/frame/sidebar/css/sidebar.module.css +63 -0
  38. package/base/index.js +53 -0
  39. package/{dist → base}/samples/menu.sample.json +2 -2
  40. package/base/styles/borderRadius.js +7 -0
  41. package/base/styles/button.js +199 -0
  42. package/base/styles/createTheme.js +90 -0
  43. package/base/styles/globalStyles.js +47 -0
  44. package/base/styles/mui/alert.js +40 -0
  45. package/base/styles/mui/appBar.js +17 -0
  46. package/base/styles/mui/autocomplete.js +46 -0
  47. package/base/styles/mui/avatar.js +14 -0
  48. package/base/styles/mui/button.js +276 -0
  49. package/base/styles/mui/buttonBase.js +10 -0
  50. package/base/styles/mui/checkbox.js +37 -0
  51. package/base/styles/mui/chip.js +83 -0
  52. package/base/styles/mui/cssBaseline.js +12 -0
  53. package/base/styles/mui/dataGrid.js +101 -0
  54. package/base/styles/mui/dialog.js +13 -0
  55. package/base/styles/mui/dialogActions.js +8 -0
  56. package/base/styles/mui/dialogContent.js +10 -0
  57. package/base/styles/mui/dialogTitle.js +11 -0
  58. package/base/styles/mui/formControl.js +8 -0
  59. package/base/styles/mui/formControlLabel.js +9 -0
  60. package/base/styles/mui/formHelperText.js +10 -0
  61. package/base/styles/mui/grid.js +15 -0
  62. package/base/styles/mui/icon.js +12 -0
  63. package/base/styles/mui/iconButton.js +79 -0
  64. package/base/styles/mui/inputLabel.js +13 -0
  65. package/base/styles/mui/list.js +11 -0
  66. package/base/styles/mui/menuItem.js +83 -0
  67. package/base/styles/mui/outlinedInput.js +53 -0
  68. package/base/styles/mui/paginationItem.js +25 -0
  69. package/base/styles/mui/paper.js +8 -0
  70. package/base/styles/mui/popover.js +11 -0
  71. package/base/styles/mui/select.js +11 -0
  72. package/base/styles/mui/slider.js +15 -0
  73. package/base/styles/mui/snackbar.js +24 -0
  74. package/base/styles/mui/switch.js +33 -0
  75. package/base/styles/mui/tab.js +23 -0
  76. package/base/styles/mui/tablePagination.js +8 -0
  77. package/base/styles/mui/tabs.js +20 -0
  78. package/base/styles/mui/textField.js +11 -0
  79. package/base/styles/mui/toggleButton.js +96 -0
  80. package/base/styles/mui/tooltip.js +22 -0
  81. package/base/styles/palette.js +40 -0
  82. package/base/styles/shadow.js +8 -0
  83. package/base/styles/typography.js +131 -0
  84. package/package.json +6 -5
  85. package/dist/AlertDialog.js +0 -55
  86. package/dist/AppBar.js +0 -68
  87. package/dist/Checkbox.js +0 -27
  88. package/dist/ColumnedSection.js +0 -64
  89. package/dist/ConfirmDialog.js +0 -65
  90. package/dist/DataGrid.js +0 -150
  91. package/dist/Dialog.js +0 -42
  92. package/dist/DropdownButton.js +0 -59
  93. package/dist/Frame.js +0 -47
  94. package/dist/MainHeader.js +0 -59
  95. package/dist/PropertyTable.js +0 -141
  96. package/dist/SearchTextField.js +0 -24
  97. package/dist/SearchableSelect.js +0 -41
  98. package/dist/Select.js +0 -48
  99. package/dist/Snackbar.js +0 -51
  100. package/dist/Switch.js +0 -37
  101. package/dist/index.js +0 -44
  102. package/dist/samples/global.sample.css +0 -59
  103. package/dist/sidebar/MenuTree.js +0 -95
  104. package/dist/sidebar/MenuTreeGroup.js +0 -65
  105. package/dist/sidebar/SecondaryMenu.js +0 -36
  106. package/dist/sidebar/SidebarContext.js +0 -122
  107. package/dist/sidebar/css/primary.module.css +0 -80
  108. package/dist/sidebar/css/sidebar.module.css +0 -50
  109. package/dist/variables.js +0 -6
  110. /package/{dist → base}/colors/green.js +0 -0
  111. /package/{dist → base}/colors/grey.js +0 -0
  112. /package/{dist → base}/colors/index.js +0 -0
  113. /package/{dist → base}/colors/lime.js +0 -0
  114. /package/{dist → base}/colors/orange.js +0 -0
  115. /package/{dist → base}/colors/purple.js +0 -0
  116. /package/{dist → base}/colors/red.js +0 -0
  117. /package/{dist → base}/colors/yellow.js +0 -0
  118. /package/{dist → base/deprecated}/Accordion.js +0 -0
  119. /package/{dist → base/deprecated}/AccordionDetails.js +0 -0
  120. /package/{dist → base/deprecated}/AccordionSummary.js +0 -0
  121. /package/{dist → base/deprecated}/AppendableFormList.js +0 -0
  122. /package/{dist → base/deprecated}/AvatarDropdown.js +0 -0
  123. /package/{dist → base/deprecated}/Button.js +0 -0
  124. /package/{dist → base/deprecated}/CircularProgress.js +0 -0
  125. /package/{dist → base/deprecated}/FormLabel.js +0 -0
  126. /package/{dist → base/deprecated}/GroupSelect.js +0 -0
  127. /package/{dist → base/deprecated}/ListItem.js +0 -0
  128. /package/{dist → base/deprecated}/ListItemDivider.js +0 -0
  129. /package/{dist → base/deprecated}/ListItemGrid.js +0 -0
  130. /package/{dist → base/deprecated}/ListItemText.js +0 -0
  131. /package/{dist → base/deprecated}/ReferenceChipList.js +0 -0
  132. /package/{dist → base/deprecated}/Section.js +0 -0
  133. /package/{dist → base/deprecated}/ShadowedSection.js +0 -0
  134. /package/{dist → base/deprecated}/StatusChip.js +0 -0
  135. /package/{dist → base/deprecated}/TabbedSection.js +0 -0
  136. /package/{dist → base/deprecated}/Tabs.js +0 -0
  137. /package/{dist → base/deprecated}/TextField.js +0 -0
  138. /package/{dist → base}/editor/Editor.js +0 -0
  139. /package/{dist → base}/editor/nScript.js +0 -0
  140. /package/{dist → base}/editor/nScriptKeywords.js +0 -0
  141. /package/{dist → base}/error/HttpError.js +0 -0
@@ -0,0 +1,21 @@
1
+ import { Button } from "@mui/material";
2
+ import { forwardRef } from "react";
3
+ import SimpleDialog from "./SimpleDialog";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ const AlertDialog = /*#__PURE__*/forwardRef(({
6
+ onClose,
7
+ closeText = '확인',
8
+ ...props
9
+ }, ref) => {
10
+ return /*#__PURE__*/_jsx(SimpleDialog, {
11
+ ref: ref,
12
+ onClose: onClose,
13
+ ...props,
14
+ children: /*#__PURE__*/_jsx(Button, {
15
+ variant: "contained",
16
+ onClick: onClose,
17
+ children: closeText
18
+ })
19
+ });
20
+ });
21
+ export default AlertDialog;
@@ -0,0 +1,29 @@
1
+ import { forwardRef } from "react";
2
+ import { Button } from "@mui/material";
3
+ import SimpleDialog from "./SimpleDialog";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ import { jsxs as _jsxs } from "react/jsx-runtime";
6
+ const ConfirmDialog = /*#__PURE__*/forwardRef(({
7
+ onConfirm,
8
+ onCancel,
9
+ confirmText = '예',
10
+ cancelText = '아니오',
11
+ ...props
12
+ }, ref) => {
13
+ return /*#__PURE__*/_jsxs(SimpleDialog, {
14
+ ref: ref,
15
+ onClose: onCancel,
16
+ ...props,
17
+ children: [/*#__PURE__*/_jsx(Button, {
18
+ variant: "contained",
19
+ onClick: onConfirm,
20
+ autoFocus: true,
21
+ children: confirmText
22
+ }), /*#__PURE__*/_jsx(Button, {
23
+ variant: "outlined",
24
+ onClick: onCancel,
25
+ children: cancelText
26
+ })]
27
+ });
28
+ });
29
+ export default ConfirmDialog;
@@ -0,0 +1,56 @@
1
+ import { forwardRef, useMemo } from "react";
2
+ import { DialogTitle, IconButton, Slide, Zoom } from "@mui/material";
3
+ import MuiDialog from "@mui/material/Dialog";
4
+ import CloseIcon from '@mui/icons-material/Close';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+ const ZoomTransition = /*#__PURE__*/forwardRef(function (props, ref) {
8
+ return /*#__PURE__*/_jsx(Zoom, {
9
+ ref: ref,
10
+ ...props
11
+ });
12
+ });
13
+ const SlideTransition = /*#__PURE__*/forwardRef(function (props, ref) {
14
+ return /*#__PURE__*/_jsx(Slide, {
15
+ direction: "down",
16
+ ref: ref,
17
+ ...props
18
+ });
19
+ });
20
+ const Dialog = /*#__PURE__*/forwardRef(({
21
+ title,
22
+ showCloseIcon,
23
+ center = true,
24
+ children,
25
+ sx,
26
+ ...props
27
+ }, ref) => {
28
+ const styles = useMemo(() => ({
29
+ '& .MuiDialog-container': {
30
+ alignItems: center ? 'center' : 'flex-start'
31
+ }
32
+ }), [center]);
33
+ const iconButtonStyles = useMemo(() => ({
34
+ position: 'absolute',
35
+ right: 20,
36
+ top: 24,
37
+ color: theme => theme.palette.grey[700]
38
+ }), []);
39
+ return /*#__PURE__*/_jsxs(MuiDialog, {
40
+ ref: ref,
41
+ TransitionComponent: center ? ZoomTransition : SlideTransition,
42
+ sx: {
43
+ ...styles,
44
+ sx
45
+ },
46
+ ...props,
47
+ children: [title && /*#__PURE__*/_jsx(DialogTitle, {
48
+ children: title
49
+ }), showCloseIcon && /*#__PURE__*/_jsx(IconButton, {
50
+ onClick: props.onClose,
51
+ sx: iconButtonStyles,
52
+ children: /*#__PURE__*/_jsx(CloseIcon, {})
53
+ }), children]
54
+ });
55
+ });
56
+ export default Dialog;
@@ -0,0 +1,33 @@
1
+ import DialogContent from "@mui/material/DialogContent";
2
+ import DialogActions from "@mui/material/DialogActions";
3
+ import Dialog from "./Dialog";
4
+ import Alert from "../Alert";
5
+ import { forwardRef } from "react";
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ import { jsxs as _jsxs } from "react/jsx-runtime";
8
+ const SimpleDialog = /*#__PURE__*/forwardRef(({
9
+ severity,
10
+ content,
11
+ subcontent,
12
+ children,
13
+ open,
14
+ onClose,
15
+ ...props
16
+ }, ref) => {
17
+ return /*#__PURE__*/_jsxs(Dialog, {
18
+ ref: ref,
19
+ open: open,
20
+ onClose: onClose,
21
+ ...props,
22
+ children: [/*#__PURE__*/_jsx(DialogContent, {
23
+ children: /*#__PURE__*/_jsx(Alert, {
24
+ severity: severity,
25
+ subcontent: subcontent,
26
+ children: content
27
+ })
28
+ }), /*#__PURE__*/_jsx(DialogActions, {
29
+ children: children
30
+ })]
31
+ });
32
+ });
33
+ export default SimpleDialog;
@@ -1,7 +1,6 @@
1
1
  import { Box, Button, Paper, Stack, Typography } from "@mui/material";
2
2
  import CampaignIcon from '@mui/icons-material/Campaign';
3
3
  import { useNavigate } from "react-router-dom";
4
- import { variables } from "../variables";
5
4
  import { useCallback } from "react";
6
5
  import { jsx as _jsx } from "react/jsx-runtime";
7
6
  import { jsxs as _jsxs } from "react/jsx-runtime";
@@ -22,7 +21,7 @@ export default function Error({
22
21
  justifyContent: "center",
23
22
  alignItems: "center",
24
23
  sx: {
25
- backgroundColor: variables.bodyBackgroundColor
24
+ backgroundColor: 'red'
26
25
  },
27
26
  children: [/*#__PURE__*/_jsxs(Paper, {
28
27
  variant: "outlined",
@@ -0,0 +1,54 @@
1
+ import React, { forwardRef, useMemo } from "react";
2
+ import { Box, Stack, Toolbar } from "@mui/material";
3
+ import MuiAppBar from "@mui/material/AppBar";
4
+ import { useSidebarContext } from "./sidebar/SidebarContext";
5
+ import { appbarBackground } from "../assets/images";
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ import { jsxs as _jsxs } from "react/jsx-runtime";
8
+ const AppBar = /*#__PURE__*/forwardRef(({
9
+ mode,
10
+ appsSlot,
11
+ brandSlot,
12
+ avatarSlot,
13
+ children,
14
+ ...props
15
+ }, ref) => {
16
+ const {
17
+ states
18
+ } = useSidebarContext();
19
+ const styles = useMemo(() => ({
20
+ position: 'absolute',
21
+ right: 0,
22
+ top: 'calc(var(--gnb-height) - 10px)',
23
+ width: `calc(100% - var(--primary-menu-width) - ${states.menuClosed ? 'var(--secondary-menu-collapsed-width) - 3px' : 'var(--secondary-menu-width)'} )`,
24
+ height: 10,
25
+ backgroundImage: appbarBackground,
26
+ backgroundRepeat: 'repeat-x',
27
+ backgroundPositionY: 'bottom'
28
+ }), [states.menuClosed]);
29
+ return /*#__PURE__*/_jsxs(MuiAppBar, {
30
+ ref: ref,
31
+ className: mode === 'preview' ? 'MuiAppBar-preview' : '',
32
+ ...props,
33
+ children: [/*#__PURE__*/_jsx(Toolbar, {
34
+ children: /*#__PURE__*/_jsxs(Stack, {
35
+ direction: "row",
36
+ justifyContent: "space-between",
37
+ alignItems: "center",
38
+ flexGrow: 1,
39
+ gap: 5.5,
40
+ children: [appsSlot, brandSlot, /*#__PURE__*/_jsxs(Stack, {
41
+ direction: "row",
42
+ justifyContent: "space-between",
43
+ alignItems: "center",
44
+ flexGrow: 1,
45
+ gap: 6,
46
+ children: [children, !children && /*#__PURE__*/_jsx(Box, {}), avatarSlot]
47
+ })]
48
+ })
49
+ }), /*#__PURE__*/_jsx(Box, {
50
+ sx: styles
51
+ })]
52
+ });
53
+ });
54
+ export default AppBar;
@@ -0,0 +1,36 @@
1
+ import React, { forwardRef, useMemo } from "react";
2
+ import { Box, Stack, Typography } from "@mui/material";
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ import { jsxs as _jsxs } from "react/jsx-runtime";
5
+ const Brand = /*#__PURE__*/forwardRef(({
6
+ title,
7
+ logoUri,
8
+ onLogoClick,
9
+ ...props
10
+ }, ref) => {
11
+ const logoStyles = useMemo(() => ({
12
+ cursor: onLogoClick ? 'pointer' : 'default'
13
+ }), [onLogoClick]);
14
+ const titleStyles = useMemo(() => ({
15
+ cursor: 'default'
16
+ }), []);
17
+ return /*#__PURE__*/_jsxs(Stack, {
18
+ gap: 1.5,
19
+ direction: "row",
20
+ alignItems: "center",
21
+ ...props,
22
+ children: [/*#__PURE__*/_jsx(Box, {
23
+ component: "img",
24
+ src: logoUri,
25
+ onClick: onLogoClick,
26
+ sx: logoStyles,
27
+ alt: "logo"
28
+ }), /*#__PURE__*/_jsx(Typography, {
29
+ variant: "logo",
30
+ noWrap: true,
31
+ sx: titleStyles,
32
+ children: title
33
+ })]
34
+ });
35
+ });
36
+ export default Brand;
@@ -0,0 +1,49 @@
1
+ import { forwardRef, useMemo } from "react";
2
+ import { Box } from '@mui/material';
3
+ import { SidebarContextProvider } from '../frame/sidebar/SidebarContext';
4
+ import { blueGrey } from "../colors";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+ const Frame = /*#__PURE__*/forwardRef(({
8
+ appBar,
9
+ sideBar,
10
+ menu,
11
+ menuIcons = {},
12
+ children,
13
+ footer,
14
+ mainRef,
15
+ onScroll
16
+ }, ref) => {
17
+ const containerStyles = useMemo(() => ({
18
+ display: 'flex',
19
+ flexGrow: 1,
20
+ overflow: 'auto',
21
+ marginTop: 'var(--gnb-height)'
22
+ }), []);
23
+ const contentStyles = useMemo(() => ({
24
+ flexGrow: 1,
25
+ overflow: 'auto',
26
+ padding: '24px 28px',
27
+ backgroundColor: blueGrey.contentBg
28
+ }), []);
29
+ return /*#__PURE__*/_jsx(Box, {
30
+ ref: ref,
31
+ children: /*#__PURE__*/_jsxs(SidebarContextProvider, {
32
+ menu: menu,
33
+ icons: menuIcons,
34
+ children: [appBar, /*#__PURE__*/_jsxs(Box, {
35
+ sx: containerStyles,
36
+ children: [sideBar, /*#__PURE__*/_jsxs(Box, {
37
+ ref: mainRef,
38
+ component: "section",
39
+ sx: contentStyles,
40
+ onScroll: onScroll,
41
+ children: [/*#__PURE__*/_jsx("main", {
42
+ children: children
43
+ }), footer]
44
+ })]
45
+ })]
46
+ })
47
+ });
48
+ });
49
+ export default Frame;
@@ -1,7 +1,6 @@
1
1
  import { Box } from '@mui/material';
2
- import NavigateBeforeIcon from '@mui/icons-material/NavigateBefore';
3
- import NavigateNextIcon from '@mui/icons-material/NavigateNext';
4
2
  import styles from './css/sidebar.module.css';
3
+ import { CollapseIcon, ExpandIcon } from "../../assets/icons";
5
4
  import { jsx as _jsx } from "react/jsx-runtime";
6
5
  import { jsxs as _jsxs } from "react/jsx-runtime";
7
6
  export default function MenuToggler({
@@ -11,8 +10,20 @@ export default function MenuToggler({
11
10
  return /*#__PURE__*/_jsx(Box, {
12
11
  className: `${styles.toggler} ${closed ? styles.closed : styles.opened}`,
13
12
  children: /*#__PURE__*/_jsxs(Box, {
13
+ display: "flex",
14
+ justifyContent: "center",
15
+ alignItems: "center",
16
+ height: "100%",
14
17
  onClick: onClick,
15
- children: [!closed && /*#__PURE__*/_jsx(NavigateBeforeIcon, {}), closed && /*#__PURE__*/_jsx(NavigateNextIcon, {})]
18
+ children: [!closed && /*#__PURE__*/_jsx(CollapseIcon, {
19
+ sx: {
20
+ fontSize: 24
21
+ }
22
+ }), closed && /*#__PURE__*/_jsx(ExpandIcon, {
23
+ sx: {
24
+ fontSize: 24
25
+ }
26
+ })]
16
27
  })
17
28
  });
18
29
  }
@@ -1,11 +1,11 @@
1
- import { Link } from 'react-router-dom';
2
1
  import { Box, Stack } from '@mui/material';
3
2
  import { useSidebarContext } from "./SidebarContext";
4
3
  import styles from './css/primary.module.css';
5
4
  import { jsx as _jsx } from "react/jsx-runtime";
6
5
  import { jsxs as _jsxs } from "react/jsx-runtime";
7
6
  export default function PrimaryMenu({
8
- items
7
+ items,
8
+ onClick
9
9
  }) {
10
10
  const {
11
11
  states,
@@ -13,10 +13,11 @@ export default function PrimaryMenu({
13
13
  } = useSidebarContext();
14
14
  return /*#__PURE__*/_jsx(Stack, {
15
15
  className: styles.container,
16
+ gap: 4,
16
17
  children: items.map(item => /*#__PURE__*/_jsx(MenuItem, {
17
18
  icon: icons[item.href],
18
19
  active: item.id === states.activePrimaryItem,
19
- last: item.last,
20
+ onClick: _ => onClick(item),
20
21
  ...item
21
22
  }, item.href))
22
23
  });
@@ -24,24 +25,18 @@ export default function PrimaryMenu({
24
25
  function MenuItem({
25
26
  name,
26
27
  icon,
27
- href,
28
28
  active,
29
- last
29
+ onClick
30
30
  }) {
31
- return /*#__PURE__*/_jsx(Link, {
32
- to: href,
33
- className: last ? 'mt-auto' : '',
34
- children: /*#__PURE__*/_jsxs(Box, {
35
- className: `${styles['nav-item']} ${active && styles.active}`,
36
- children: [active && /*#__PURE__*/_jsx(Box, {
37
- className: styles.highlight
38
- }), /*#__PURE__*/_jsx(Box, {
39
- className: styles.icon,
40
- children: icon
41
- }), /*#__PURE__*/_jsx(Box, {
42
- className: styles.text,
43
- children: name
44
- })]
45
- })
31
+ return /*#__PURE__*/_jsxs(Box, {
32
+ className: `${styles['nav-item']} ${active && styles.active}`,
33
+ onClick: onClick,
34
+ children: [/*#__PURE__*/_jsx(Box, {
35
+ className: styles.icon,
36
+ children: icon instanceof Array ? icon[active ? 1 : 0] : icon
37
+ }), /*#__PURE__*/_jsx(Box, {
38
+ className: styles.text,
39
+ children: name
40
+ })]
46
41
  });
47
42
  }
@@ -0,0 +1,41 @@
1
+ import { MenuList, Stack } from '@mui/material';
2
+ import styles from './css/sidebar.module.css';
3
+ import MenuItem from "../../MenuItem";
4
+ import { useSidebarContext } from "./SidebarContext";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ export default function SecondaryMenu({
7
+ sections,
8
+ closed,
9
+ onClick
10
+ }) {
11
+ const {
12
+ states
13
+ } = useSidebarContext();
14
+ return /*#__PURE__*/_jsx(Stack, {
15
+ className: `${styles.secondary} ${closed ? styles.closed : styles.opened}`,
16
+ children: /*#__PURE__*/_jsx(MenuList, {
17
+ sx: {
18
+ visibility: closed ? 'hidden' : 'visible'
19
+ },
20
+ children: sections.map((section, index) => {
21
+ let jsx = [];
22
+ if (section.name) jsx.push( /*#__PURE__*/_jsx(MenuItem, {
23
+ variant: "menusection",
24
+ children: section.name
25
+ }, section.id));
26
+ section.menu.forEach(item => {
27
+ jsx.push( /*#__PURE__*/_jsx(MenuItem, {
28
+ variant: "menuitem",
29
+ selected: item.id === states.activeSecondaryItem,
30
+ onClick: _ => onClick(item),
31
+ children: item.name
32
+ }, item.id));
33
+ });
34
+ jsx.push( /*#__PURE__*/_jsx(MenuItem, {
35
+ variant: "spacer"
36
+ }, `${index}-${section.menu?.length}`));
37
+ return jsx;
38
+ })
39
+ })
40
+ });
41
+ }
@@ -1,14 +1,14 @@
1
- import { useEffect, useState } from "react";
2
- import { useLocation } from "react-router-dom";
3
- import { useSidebarContext } from "./SidebarContext";
1
+ import { forwardRef, useCallback, useEffect, useState } from "react";
2
+ import { useLocation, useNavigate } from "react-router-dom";
4
3
  import { Stack } from "@mui/material";
4
+ import { useSidebarContext } from "./SidebarContext";
5
5
  import PrimaryMenu from "./PrimaryMenu";
6
6
  import SecondaryMenu from "./SecondaryMenu";
7
7
  import MenuToggler from "./MenuToggler";
8
8
  import styles from './css/sidebar.module.css';
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
10
  import { jsxs as _jsxs } from "react/jsx-runtime";
11
- export default function Sidebar() {
11
+ const Sidebar = /*#__PURE__*/forwardRef((props, ref) => {
12
12
  const [sections, setSections] = useState();
13
13
  const {
14
14
  menu,
@@ -19,6 +19,15 @@ export default function Sidebar() {
19
19
  menuClosed: closed
20
20
  } = states;
21
21
  const location = useLocation();
22
+ const navigate = useNavigate();
23
+ const handleClick = useCallback(item => {
24
+ navigate(item.href);
25
+ }, [navigate]);
26
+ const handleToggle = useCallback(_ => {
27
+ dispatch({
28
+ type: 'secondaryMenuToggled'
29
+ });
30
+ }, [dispatch]);
22
31
  useEffect(() => {
23
32
  dispatch({
24
33
  type: 'updateActiveItems',
@@ -33,20 +42,22 @@ export default function Sidebar() {
33
42
  // eslint-disable-next-line react-hooks/exhaustive-deps
34
43
  }, [states]);
35
44
  return /*#__PURE__*/_jsxs(Stack, {
45
+ ref: ref,
36
46
  className: `${styles.container} ${closed || isEmpty(sections) ? styles.closed : styles.opened}`,
37
47
  children: [/*#__PURE__*/_jsx(PrimaryMenu, {
38
- items: menu
48
+ items: menu,
49
+ onClick: handleClick
39
50
  }), /*#__PURE__*/_jsx(SecondaryMenu, {
40
51
  sections: sections ? sections : [],
41
- closed: !isEmpty(sections) ? closed : true
52
+ closed: !isEmpty(sections) ? closed : true,
53
+ onClick: handleClick
42
54
  }), !isEmpty(sections) && /*#__PURE__*/_jsx(MenuToggler, {
43
55
  closed: closed,
44
- onClick: () => dispatch({
45
- type: "secondaryMenuToggled"
46
- })
56
+ onClick: handleToggle
47
57
  })]
48
58
  });
49
- }
59
+ });
60
+ export default Sidebar;
50
61
  function isEmpty(list) {
51
62
  return list && list.length === 0;
52
63
  }
@@ -0,0 +1,74 @@
1
+ import { createContext, useContext, useReducer } from "react";
2
+ import { produce } from "immer";
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ const SidebarContext = /*#__PURE__*/createContext();
5
+ export function SidebarContextProvider({
6
+ menu,
7
+ icons,
8
+ children
9
+ }) {
10
+ const [states, dispatch] = useReducer(reducer, initialStates);
11
+ return /*#__PURE__*/_jsx(SidebarContext.Provider, {
12
+ value: {
13
+ menu,
14
+ icons,
15
+ states,
16
+ dispatch
17
+ },
18
+ children: children
19
+ });
20
+ }
21
+ export function useSidebarContext() {
22
+ return useContext(SidebarContext);
23
+ }
24
+ function reducer(states, action) {
25
+ const {
26
+ type
27
+ } = action;
28
+ switch (type) {
29
+ case 'secondaryMenuToggled':
30
+ return produce(states, draft => {
31
+ draft.menuClosed = !states.menuClosed;
32
+ });
33
+ case 'updateActiveItems':
34
+ return produce(states, draft => {
35
+ updateActiveItems(draft, action.menu, action.href);
36
+ });
37
+ default:
38
+ throw new Error(`Undefined Sidebar Action Type: ${JSON.stringify(action)}`);
39
+ }
40
+ }
41
+ const initialStates = {
42
+ activePrimaryItem: undefined,
43
+ activeSecondaryItem: undefined,
44
+ menuClosed: false
45
+ };
46
+ function updateActiveItems(draft, menu, href) {
47
+ draft.activePrimaryItem = undefined;
48
+ draft.activeSecondaryItem = undefined;
49
+ for (let item of menu) {
50
+ if (item.href === href) {
51
+ draft.activePrimaryItem = item.id;
52
+ return;
53
+ }
54
+ if (updateActiveMenuItem(item.sections)) {
55
+ draft.activePrimaryItem = item.id;
56
+ return;
57
+ }
58
+ }
59
+ function updateActiveMenuItem(sections) {
60
+ if (!sections) return;
61
+ for (let section of sections) {
62
+ for (let item of section.menu) {
63
+ if (startsWith(item.href)) {
64
+ draft.activeSecondaryItem = item.id;
65
+ return true;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ function startsWith(hrefs) {
71
+ const menuHrefs = hrefs instanceof Array ? hrefs : [hrefs];
72
+ return menuHrefs.some(menuHref => href.startsWith(menuHref));
73
+ }
74
+ }
@@ -0,0 +1,69 @@
1
+ .container {
2
+ position: fixed;
3
+ display: flex;
4
+ flex-direction: column;
5
+ width: calc(var(--primary-menu-width) + 10px);
6
+ padding-right: 10px;
7
+ height: 100%;
8
+ background-color: var(--frame-background-color);
9
+ }
10
+ .container a {
11
+ text-decoration: none;
12
+ cursor: pointer;
13
+ }
14
+ .container a:first-child {
15
+ padding-top: 10px;
16
+ }
17
+ .container a:last-child {
18
+ padding-bottom: 10px;
19
+ }
20
+
21
+ .nav-item {
22
+ display: flex;
23
+ flex-direction: column;
24
+ height: 50px;
25
+ align-items: center;
26
+ color: #656565;
27
+ cursor: pointer;
28
+ }
29
+ .nav-item .icon {
30
+ display: flex;
31
+ justify-content: center;
32
+ align-items: center;
33
+ width: 36px;
34
+ height: 36px;
35
+ border-radius: 6px;
36
+ }
37
+ .nav-item:hover .icon {
38
+ background-color: rgba(51,51,51,0.05);
39
+ }
40
+ .nav-item.active .icon {
41
+ color: #333;
42
+ background-color: rgba(51,51,51,0.1);
43
+ }
44
+ .nav-item.active .text {
45
+ font-weight: 600;
46
+ }
47
+ .container:hover .nav-item.active {
48
+ /*border-radius: 0 48px 48px 0;*/
49
+ /*background-color: #0d6efd !important;*/
50
+ }
51
+
52
+
53
+ .icon {
54
+ margin: 4px 15px 0px 16px;
55
+ }
56
+ .icon > svg {
57
+ width: 24px;
58
+ height: 24px;
59
+ }
60
+
61
+ .text {
62
+ color: #333;
63
+ font-size: 10px;
64
+ font-weight: 500;
65
+ line-height: 1.4;
66
+ letter-spacing: 0;
67
+ white-space: nowrap;
68
+ overflow-x: hidden;
69
+ }