@nethru/ui 1.0.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.
- package/README.md +28 -0
- package/dist/Accordion.js +41 -0
- package/dist/AccordionDetails.js +15 -0
- package/dist/AccordionSummary.js +25 -0
- package/dist/AlertDialog.js +48 -0
- package/dist/AppBar.js +64 -0
- package/dist/Checkbox.js +17 -0
- package/dist/ConfirmDialog.js +54 -0
- package/dist/DataGrid.js +129 -0
- package/dist/Dialog.js +26 -0
- package/dist/FormLabel.js +18 -0
- package/dist/Frame.js +43 -0
- package/dist/GroupSelect.js +65 -0
- package/dist/ListItem.js +19 -0
- package/dist/ListItemDivider.js +13 -0
- package/dist/ListItemGrid.js +12 -0
- package/dist/ListItemText.js +35 -0
- package/dist/MainHeader.js +56 -0
- package/dist/SearchTextField.js +22 -0
- package/dist/Section.js +17 -0
- package/dist/Select.js +40 -0
- package/dist/Slider.js +31 -0
- package/dist/Snackbar.js +44 -0
- package/dist/StatusChip.js +19 -0
- package/dist/Switch.js +32 -0
- package/dist/TextField.js +23 -0
- package/dist/error/Error.js +63 -0
- package/dist/error/HttpError.js +33 -0
- package/dist/index.js +29 -0
- package/dist/samples/global.sample.css +48 -0
- package/dist/samples/menu.sample.json +303 -0
- package/dist/sidebar/MenuToggler.js +18 -0
- package/dist/sidebar/MenuTree.js +95 -0
- package/dist/sidebar/MenuTreeGroup.js +65 -0
- package/dist/sidebar/PrimaryMenu.js +47 -0
- package/dist/sidebar/SecondaryMenu.js +36 -0
- package/dist/sidebar/Sidebar.js +52 -0
- package/dist/sidebar/SidebarContext.js +118 -0
- package/dist/sidebar/css/primary.module.css +80 -0
- package/dist/sidebar/css/sidebar.module.css +50 -0
- package/dist/variables.js +6 -0
- package/package.json +61 -0
|
@@ -0,0 +1,118 @@
|
|
|
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
|
+
export function getMenuGroupStates(states, id) {
|
|
25
|
+
return states.menuGroupsExpanded[id] !== undefined ? states.menuGroupsExpanded[id] : true;
|
|
26
|
+
}
|
|
27
|
+
export function getMenuTreeStates(states, id) {
|
|
28
|
+
return states.menuTrees[id] || emptyState();
|
|
29
|
+
}
|
|
30
|
+
function reducer(states, action) {
|
|
31
|
+
const {
|
|
32
|
+
id,
|
|
33
|
+
type
|
|
34
|
+
} = action;
|
|
35
|
+
switch (type) {
|
|
36
|
+
case 'secondaryMenuToggled':
|
|
37
|
+
return produce(states, draft => {
|
|
38
|
+
draft.menuClosed = !states.menuClosed;
|
|
39
|
+
});
|
|
40
|
+
case 'menuGroupExpanded':
|
|
41
|
+
return produce(states, draft => {
|
|
42
|
+
draft.menuGroupsExpanded[id] = action.expanded;
|
|
43
|
+
});
|
|
44
|
+
case 'treeItemSelected':
|
|
45
|
+
return produce(states, draft => {
|
|
46
|
+
for (const key in draft.menuTrees) {
|
|
47
|
+
draft.menuTrees[key].selected = [];
|
|
48
|
+
}
|
|
49
|
+
if (!(id in draft.menuTrees)) draft.menuTrees[id] = emptyState();
|
|
50
|
+
draft.menuTrees[id].selected = action.ids;
|
|
51
|
+
});
|
|
52
|
+
case 'treeItemExpanded':
|
|
53
|
+
return produce(states, draft => {
|
|
54
|
+
if (!(id in draft.menuTrees)) draft.menuTrees[id] = emptyState();
|
|
55
|
+
draft.menuTrees[id].expanded = [...action.ids];
|
|
56
|
+
});
|
|
57
|
+
case 'updateActiveItems':
|
|
58
|
+
return produce(states, draft => {
|
|
59
|
+
updateActiveItems(draft, action.menu, action.href);
|
|
60
|
+
});
|
|
61
|
+
default:
|
|
62
|
+
throw new Error(`Undefined Sidebar Action Type: ${JSON.stringify(action)}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function emptyState() {
|
|
66
|
+
return {
|
|
67
|
+
selected: [],
|
|
68
|
+
expanded: []
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const initialStates = {
|
|
72
|
+
activePrimaryItem: undefined,
|
|
73
|
+
activeSecondaryItem: undefined,
|
|
74
|
+
menuClosed: false,
|
|
75
|
+
menuGroupsExpanded: {},
|
|
76
|
+
menuTrees: {}
|
|
77
|
+
};
|
|
78
|
+
function updateActiveItems(draft, menu, href) {
|
|
79
|
+
draft.activePrimaryItem = undefined;
|
|
80
|
+
draft.activeSecondaryItem = undefined;
|
|
81
|
+
for (let item of menu) {
|
|
82
|
+
if (item.href === href) {
|
|
83
|
+
draft.activePrimaryItem = item.id;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (updateActiveSection(item.sections)) {
|
|
87
|
+
draft.activePrimaryItem = item.id;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function updateActiveSection(sections) {
|
|
92
|
+
if (!sections) return;
|
|
93
|
+
for (let section of sections) {
|
|
94
|
+
if (section.href === href) {
|
|
95
|
+
draft.activeSecondaryItem = section.id;
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
if (updateActiveSubmenuItems(section.id, section.menu)) {
|
|
99
|
+
draft.menuGroupsExpanded[section.id] = true;
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function updateActiveSubmenuItems(id, submenu) {
|
|
105
|
+
if (!submenu) return;
|
|
106
|
+
for (let item of submenu) {
|
|
107
|
+
if (item.href === href) {
|
|
108
|
+
if (!(id in draft.menuTrees)) draft.menuTrees[id] = emptyState();
|
|
109
|
+
draft.activeSecondaryItem = item.id;
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
if (updateActiveSubmenuItems(id, item.submenu)) {
|
|
113
|
+
draft.menuTrees[id].expanded.push(item.id);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
position: absolute;
|
|
5
|
+
width: var(--primary-menu-width);
|
|
6
|
+
height: 100%;
|
|
7
|
+
border-right: 1px solid #dee2e6;
|
|
8
|
+
z-index: 30;
|
|
9
|
+
transition-property: width background-color;
|
|
10
|
+
transition-duration: .2s;
|
|
11
|
+
}
|
|
12
|
+
.container:hover {
|
|
13
|
+
width: 240px;
|
|
14
|
+
background-color: #fff;
|
|
15
|
+
box-shadow: 1px 1px 12px #dadce0;
|
|
16
|
+
}
|
|
17
|
+
.container a {
|
|
18
|
+
text-decoration: none;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
}
|
|
21
|
+
.container a:first-child {
|
|
22
|
+
padding-top: 10px;
|
|
23
|
+
}
|
|
24
|
+
.container a:last-child {
|
|
25
|
+
padding-bottom: 10px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.nav-item {
|
|
29
|
+
position: relative;
|
|
30
|
+
display: flex;
|
|
31
|
+
height: 48px;
|
|
32
|
+
align-items: center;
|
|
33
|
+
color: #495057;
|
|
34
|
+
}
|
|
35
|
+
.nav-item:hover {
|
|
36
|
+
/*border-radius: 0 48px 48px 0;*/
|
|
37
|
+
background-color: #e9ecef;
|
|
38
|
+
}
|
|
39
|
+
.nav-item.active {
|
|
40
|
+
/*color: #fff;*/
|
|
41
|
+
/*border-left: 5px solid #0d6efd;*/
|
|
42
|
+
}
|
|
43
|
+
.container:hover .nav-item.active {
|
|
44
|
+
/*border-radius: 0 48px 48px 0;*/
|
|
45
|
+
/*background-color: #0d6efd !important;*/
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.highlight {
|
|
49
|
+
position: absolute;
|
|
50
|
+
left: 0px;
|
|
51
|
+
width: 5px;
|
|
52
|
+
height: 36px;
|
|
53
|
+
z-index: 100;
|
|
54
|
+
/*border-radius: 50%;*/
|
|
55
|
+
background-color: #0d6efd;
|
|
56
|
+
transition-property: height;
|
|
57
|
+
transition-duration: .2s;
|
|
58
|
+
}
|
|
59
|
+
.container:hover .highlight {
|
|
60
|
+
height: 48px;
|
|
61
|
+
/*display: none;*/
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.icon {
|
|
65
|
+
margin: 4px 15px 0px 16px;
|
|
66
|
+
}
|
|
67
|
+
.icon > svg {
|
|
68
|
+
width: 24px;
|
|
69
|
+
height: 24px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.text {
|
|
73
|
+
font-size: .9rem;
|
|
74
|
+
display: none;
|
|
75
|
+
white-space: nowrap;
|
|
76
|
+
overflow-x: hidden;
|
|
77
|
+
}
|
|
78
|
+
.container:hover .text {
|
|
79
|
+
display: block;
|
|
80
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
display: flex;
|
|
3
|
+
position: relative;
|
|
4
|
+
background-color: var(--body-background-color);
|
|
5
|
+
transition: width .2s;
|
|
6
|
+
}
|
|
7
|
+
.container.opened {
|
|
8
|
+
width: calc(var(--primary-menu-width) + var(--secondary-menu-width));
|
|
9
|
+
}
|
|
10
|
+
.container.closed {
|
|
11
|
+
width: var(--primary-menu-width);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
.secondary {
|
|
16
|
+
position: absolute;
|
|
17
|
+
left: var(--primary-menu-width);
|
|
18
|
+
height: 100%;
|
|
19
|
+
z-index: 0;
|
|
20
|
+
white-space: nowrap;
|
|
21
|
+
overflow-x: hidden;
|
|
22
|
+
}
|
|
23
|
+
.secondary.opened {
|
|
24
|
+
width: var(--secondary-menu-width);
|
|
25
|
+
}
|
|
26
|
+
.secondary.closed {
|
|
27
|
+
width: 0px;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.toggler {
|
|
32
|
+
position: absolute;
|
|
33
|
+
bottom: 12px;
|
|
34
|
+
width: 24px;
|
|
35
|
+
height: 32px;
|
|
36
|
+
padding-top: 2px;
|
|
37
|
+
z-index: 15;
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
transition: left .2s;
|
|
40
|
+
}
|
|
41
|
+
.toggler.opened {
|
|
42
|
+
left: 264px;
|
|
43
|
+
}
|
|
44
|
+
.toggler.closed {
|
|
45
|
+
left: var(--primary-menu-width);
|
|
46
|
+
background-color: #f1f3f4;
|
|
47
|
+
border: unset;
|
|
48
|
+
border-radius: 0 50% 50% 0/0 50% 50% 0;
|
|
49
|
+
box-shadow: 1px 1px 1px 1px #e8eaed;
|
|
50
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nethru/ui",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"files": [
|
|
6
|
+
"/dist"
|
|
7
|
+
],
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"@emotion/react": "^11.11.1",
|
|
10
|
+
"@emotion/styled": "^11.11.0",
|
|
11
|
+
"@fontsource/roboto": "^5.0.8",
|
|
12
|
+
"@mui/icons-material": "^5.14.18",
|
|
13
|
+
"@mui/material": "^5.14.18",
|
|
14
|
+
"@mui/x-data-grid": "^6.18.2",
|
|
15
|
+
"@mui/x-date-pickers": "^6.18.2",
|
|
16
|
+
"@mui/x-tree-view": "^6.17.0",
|
|
17
|
+
"@testing-library/jest-dom": "^5.17.0",
|
|
18
|
+
"@testing-library/react": "^13.4.0",
|
|
19
|
+
"@testing-library/user-event": "^13.5.0",
|
|
20
|
+
"days": "^1.1.1",
|
|
21
|
+
"immer": "^10.0.3",
|
|
22
|
+
"react": "^18.2.0",
|
|
23
|
+
"react-dom": "^18.2.0",
|
|
24
|
+
"react-router-dom": "^6.20.0",
|
|
25
|
+
"react-scripts": "5.0.1"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"start": "react-scripts start",
|
|
29
|
+
"build": "react-scripts build",
|
|
30
|
+
"test": "react-scripts test",
|
|
31
|
+
"eject": "react-scripts eject",
|
|
32
|
+
"publish:npm": "rm -rf dist && mkdir dist && babel src/lib -d dist --copy-files"
|
|
33
|
+
},
|
|
34
|
+
"babel": {
|
|
35
|
+
"presets": [
|
|
36
|
+
["@babel/preset-react", {"runtime": "automatic"}]
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
"eslintConfig": {
|
|
40
|
+
"extends": [
|
|
41
|
+
"react-app",
|
|
42
|
+
"react-app/jest"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"browserslist": {
|
|
46
|
+
"production": [
|
|
47
|
+
">0.2%",
|
|
48
|
+
"not dead",
|
|
49
|
+
"not op_mini all"
|
|
50
|
+
],
|
|
51
|
+
"development": [
|
|
52
|
+
"last 1 chrome version",
|
|
53
|
+
"last 1 firefox version",
|
|
54
|
+
"last 1 safari version"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@babel/cli": "^7.23.4",
|
|
59
|
+
"@babel/preset-react": "^7.23.3"
|
|
60
|
+
}
|
|
61
|
+
}
|