@buerokratt-ria/menu 0.1.16 → 0.2.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.
- package/.eslintrc.json +18 -18
- package/CHANGELOG.md +73 -70
- package/MAKING_CHANGES.md +8 -8
- package/README.md +49 -49
- package/buerokratt-ria-menu-0.2.1.tgz +0 -0
- package/index.ts +2 -2
- package/package.json +42 -42
- package/project.json +52 -52
- package/src/index.ts +2 -2
- package/src/menu/components/icons/icon/icon.tsx +33 -33
- package/src/menu/components/icons/icon.scss +22 -22
- package/src/menu/components/menuTree/index.tsx +77 -64
- package/src/menu/components/menuTree/isSameRoot.ts +10 -10
- package/src/menu/components/menuTree/menuData.tsx +42 -42
- package/src/menu/data/menu-structure.json +364 -357
- package/src/menu/hooks/useFilteredMenuItems.tsx +39 -33
- package/src/menu/hooks/useMenuItems.tsx +77 -63
- package/src/menu/index.tsx +53 -48
- package/src/menu/main-navigation.scss +129 -129
- package/src/menu/types/countConf.ts +3 -0
- package/src/menu/types/menuItem.ts +14 -13
- package/tsconfig.base.json +21 -21
- package/tsconfig.json +14 -14
- package/tsconfig.spec.json +19 -19
- package/vite.config.ts +67 -67
- package/buerokratt-ria-menu-0.1.16.tgz +0 -0
|
@@ -1,33 +1,39 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import { useQuery } from "@tanstack/react-query";
|
|
3
|
-
import { MenuItem } from "../types/menuItem";
|
|
4
|
-
import useMenuItems from "./useMenuItems";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import { MenuItem } from "../types/menuItem";
|
|
4
|
+
import useMenuItems from "./useMenuItems";
|
|
5
|
+
import { CountConf } from "../types/countConf";
|
|
6
|
+
|
|
7
|
+
const useFilteredMenuItems = (countConf?: CountConf) => {
|
|
8
|
+
const items = useMenuItems(countConf);
|
|
9
|
+
const [menuItems, setMenuItems] = useState<MenuItem[]>([]);
|
|
10
|
+
|
|
11
|
+
const { data } = useQuery<{ response: [] }>({
|
|
12
|
+
queryKey: ['accounts/user-role', 'prod'],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const filteredItems = items.filter((item) => {
|
|
17
|
+
if (!data) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const role: any[] = data.response;
|
|
21
|
+
if (role.includes('ROLE_ADMINISTRATOR'))
|
|
22
|
+
return item.id;
|
|
23
|
+
if (role.includes('ROLE_SERVICE_MANAGER'))
|
|
24
|
+
return item.id != "settings" && item.id != "training";
|
|
25
|
+
if (role.includes('ROLE_CUSTOMER_SUPPORT_AGENT'))
|
|
26
|
+
return item.id != "settings" && item.id != "analytics";
|
|
27
|
+
if (role.includes('ROLE_CHATBOT_TRAINER'))
|
|
28
|
+
return item.id != "settings" && item.id != "conversations";
|
|
29
|
+
if (role.includes('ROLE_ANALYST'))
|
|
30
|
+
return item.id == "analytics" || item.id == "monitoring";
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
setMenuItems(filteredItems ?? []);
|
|
34
|
+
}, [items, data]);
|
|
35
|
+
|
|
36
|
+
return menuItems;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default useFilteredMenuItems;
|
|
@@ -1,63 +1,77 @@
|
|
|
1
|
-
import { useMemo, useState } from "react";
|
|
2
|
-
import { useQuery } from "@tanstack/react-query";
|
|
3
|
-
import menuStructure from '../data/menu-structure.json';
|
|
4
|
-
import { MenuItem } from "../types/menuItem";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
import { useMemo, useState } from "react";
|
|
2
|
+
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import menuStructure from '../data/menu-structure.json';
|
|
4
|
+
import { MenuItem } from "../types/menuItem";
|
|
5
|
+
import { CountConf } from "../types/countConf";
|
|
6
|
+
|
|
7
|
+
const useMenuItems = (count?: CountConf) => {
|
|
8
|
+
const externalMenuItems = import.meta.env.REACT_APP_MENU_JSON;
|
|
9
|
+
const cachedMenu = getMenuCache();
|
|
10
|
+
const [mainMenuItems, setMainMenuItems] = useState<MenuItem[] | null>(cachedMenu ?? []);
|
|
11
|
+
|
|
12
|
+
useQuery({
|
|
13
|
+
enabled: !externalMenuItems && !cachedMenu,
|
|
14
|
+
queryKey: [import.meta.env.REACT_APP_MENU_URL + import.meta.env.REACT_APP_MENU_PATH],
|
|
15
|
+
onSuccess: (res: any) => {
|
|
16
|
+
try {
|
|
17
|
+
setMainMenuItems(res);
|
|
18
|
+
setCache(res);
|
|
19
|
+
} catch (e) {
|
|
20
|
+
console.error(e);
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
onError: () => {
|
|
24
|
+
setMainMenuItems(cachedMenu);
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const items = useMemo(() => {
|
|
29
|
+
let externals;
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
if (externalMenuItems) {
|
|
33
|
+
externals = JSON.parse(externalMenuItems);
|
|
34
|
+
if (!Array.isArray(externals)) {
|
|
35
|
+
console.warn('REACT_APP_MENU_JSON was ignored becuase it wasn\'t an array');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
} catch (e) {
|
|
39
|
+
console.warn(e);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const addCountToPathFields = (item: MenuItem) => {
|
|
43
|
+
if (count && item.path in count) {
|
|
44
|
+
item.count = count[item.path]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (item.children) {
|
|
48
|
+
item.children.forEach(child => addCountToPathFields(child));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const finalMenu = externals ?? mainMenuItems ?? menuStructure ?? [];
|
|
53
|
+
finalMenu.forEach((item: MenuItem) => addCountToPathFields(item))
|
|
54
|
+
|
|
55
|
+
return finalMenu;
|
|
56
|
+
}, [externalMenuItems, mainMenuItems, menuStructure, count]);
|
|
57
|
+
|
|
58
|
+
return items;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getMenuCache(): any {
|
|
62
|
+
const cached = getCache();
|
|
63
|
+
if (Array.isArray(cached) && cached.length > 0)
|
|
64
|
+
return cached;
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getCache(): any {
|
|
69
|
+
const cache = localStorage.getItem('mainmenu-cache') ?? '[]';
|
|
70
|
+
return JSON.parse(cache);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function setCache(res: any) {
|
|
74
|
+
localStorage.setItem('mainmenu-cache', JSON.stringify(res));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default useMenuItems;
|
package/src/menu/index.tsx
CHANGED
|
@@ -1,48 +1,53 @@
|
|
|
1
|
-
import React, { FC, MouseEvent, useState, useMemo } from 'react';
|
|
2
|
-
import clsx from 'clsx';
|
|
3
|
-
import { MdClose } from 'react-icons/md';
|
|
4
|
-
import Icon from './components/icons/icon/icon';
|
|
5
|
-
import { useTranslation } from "react-i18next";
|
|
6
|
-
import MenuTree from './components/menuTree';
|
|
7
|
-
import useFilteredMenuItems from './hooks/useFilteredMenuItems';
|
|
8
|
-
import './main-navigation.scss';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
1
|
+
import React, { FC, MouseEvent, useState, useMemo } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { MdClose } from 'react-icons/md';
|
|
4
|
+
import Icon from './components/icons/icon/icon';
|
|
5
|
+
import { useTranslation } from "react-i18next";
|
|
6
|
+
import MenuTree from './components/menuTree';
|
|
7
|
+
import useFilteredMenuItems from './hooks/useFilteredMenuItems';
|
|
8
|
+
import './main-navigation.scss';
|
|
9
|
+
import { CountConf } from "./types/countConf";
|
|
10
|
+
|
|
11
|
+
interface MainNavigationProps {
|
|
12
|
+
countConf?: CountConf
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const MainNavigation: FC<MainNavigationProps> = ({countConf}) => {
|
|
16
|
+
const { t } = useTranslation();
|
|
17
|
+
const menuItems = useFilteredMenuItems(countConf);
|
|
18
|
+
const serviceId = useMemo(() => import.meta.env.REACT_APP_SERVICE_ID.split(','), []);
|
|
19
|
+
|
|
20
|
+
const [navCollapsed, setNavCollapsed] = useState(false);
|
|
21
|
+
|
|
22
|
+
const handleNavToggle = (event: MouseEvent) => {
|
|
23
|
+
setNavCollapsed(false);
|
|
24
|
+
const isExpanded = event.currentTarget.getAttribute('aria-expanded') === 'true';
|
|
25
|
+
event.currentTarget.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const handleCloseButtonClick = () => {
|
|
29
|
+
const doesMenuHasExpandedItem = !!document.querySelector('button[aria-expanded="true"]');
|
|
30
|
+
if(doesMenuHasExpandedItem)
|
|
31
|
+
setNavCollapsed(!navCollapsed);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!menuItems) return null;
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<nav className={clsx('nav', { 'collapsed': navCollapsed })}>
|
|
38
|
+
<button className='nav__menu-toggle close-button-item' onClick={handleCloseButtonClick}>
|
|
39
|
+
<Icon icon={<MdClose />} />
|
|
40
|
+
<span className='menu-item-title'>{t(navCollapsed ? 'mainMenu.openMenu' : 'mainMenu.closeMenu' )}</span>
|
|
41
|
+
</button>
|
|
42
|
+
<ul className='nav__menu'>
|
|
43
|
+
<MenuTree
|
|
44
|
+
menuItems={menuItems}
|
|
45
|
+
serviceId={serviceId}
|
|
46
|
+
handleNavToggle={handleNavToggle}
|
|
47
|
+
/>
|
|
48
|
+
</ul>
|
|
49
|
+
</nav>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default MainNavigation;
|
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
@import '@buerokratt-ria/styles/styles/tools/spacing';
|
|
2
|
-
@import '@buerokratt-ria/styles/styles/tools/color';
|
|
3
|
-
@import '@buerokratt-ria/styles/styles/settings/variables/typography';
|
|
4
|
-
|
|
5
|
-
.nav {
|
|
6
|
-
$self: &;
|
|
7
|
-
width: 208px;
|
|
8
|
-
background-color: get-color(sapphire-blue-10);
|
|
9
|
-
overflow: auto;
|
|
10
|
-
scrollbar-width: none;
|
|
11
|
-
transition: width .1s ease-out;
|
|
12
|
-
|
|
13
|
-
&::-webkit-scrollbar {
|
|
14
|
-
display: none;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
li, a, .nav__toggle, .nav__menu-toggle {
|
|
18
|
-
font-size: 14px;
|
|
19
|
-
line-height: 1.5;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
&__menu-toggle {
|
|
23
|
-
display: flex;
|
|
24
|
-
align-items: center;
|
|
25
|
-
|
|
26
|
-
&:hover {
|
|
27
|
-
background-color: get-color(sapphire-blue-8);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
&:active {
|
|
31
|
-
background-color: get-color(sapphire-blue-7);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
a, .nav__toggle {
|
|
36
|
-
width: 100%;
|
|
37
|
-
display: flex;
|
|
38
|
-
align-items: center;
|
|
39
|
-
gap: get-spacing(paldiski);
|
|
40
|
-
color: get-color(black-coral-0);
|
|
41
|
-
padding: 14px 8px 14px 32px;
|
|
42
|
-
box-shadow: inset 0 -1px 0 get-color(sapphire-blue-14);
|
|
43
|
-
|
|
44
|
-
span:not(.icon) {
|
|
45
|
-
flex: 1;
|
|
46
|
-
display: block;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
&:hover {
|
|
50
|
-
background-color: get-color(sapphire-blue-8);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
&:active {
|
|
54
|
-
background-color: get-color(sapphire-blue-7);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
&.active {
|
|
58
|
-
font-weight: 700;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
&__toggle {
|
|
63
|
-
&[aria-expanded=true] {
|
|
64
|
-
font-weight: 700;
|
|
65
|
-
|
|
66
|
-
.icon {
|
|
67
|
-
transform: rotate(180deg);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
+ ul {
|
|
71
|
-
display: block;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
&.nav__toggle--icon {
|
|
76
|
-
padding-left: 8px;
|
|
77
|
-
|
|
78
|
-
.icon:first-child {
|
|
79
|
-
transform: none;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
&__toggle-icon {
|
|
85
|
-
margin-left: auto;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
&__menu-toggle {
|
|
89
|
-
display: flex;
|
|
90
|
-
align-items: center;
|
|
91
|
-
gap: get-spacing(paldiski);
|
|
92
|
-
width: 100%;
|
|
93
|
-
color: get-color(white);
|
|
94
|
-
padding: 14px 8px;
|
|
95
|
-
box-shadow: inset 0 -1px 0 get-color(sapphire-blue-14);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
&__submenu {
|
|
99
|
-
display: none;
|
|
100
|
-
|
|
101
|
-
a, .nav__toggle {
|
|
102
|
-
background-color: get-color(sapphire-blue-14);
|
|
103
|
-
box-shadow: inset 0 -1px 0 get-color(sapphire-blue-17);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
#{$self} {
|
|
107
|
-
&__submenu {
|
|
108
|
-
a {
|
|
109
|
-
background-color: get-color(sapphire-blue-17);
|
|
110
|
-
box-shadow: inset 0 -1px 0 get-color(black);
|
|
111
|
-
padding: 14px 48px 14px 40px;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.collapsed {
|
|
119
|
-
.nav__submenu {
|
|
120
|
-
visibility: hidden;
|
|
121
|
-
height: 0;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
button[aria-expanded=true] {
|
|
125
|
-
.icon {
|
|
126
|
-
transform: rotate(0deg);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
1
|
+
@import '@buerokratt-ria/styles/styles/tools/spacing';
|
|
2
|
+
@import '@buerokratt-ria/styles/styles/tools/color';
|
|
3
|
+
@import '@buerokratt-ria/styles/styles/settings/variables/typography';
|
|
4
|
+
|
|
5
|
+
.nav {
|
|
6
|
+
$self: &;
|
|
7
|
+
width: 208px;
|
|
8
|
+
background-color: get-color(sapphire-blue-10);
|
|
9
|
+
overflow: auto;
|
|
10
|
+
scrollbar-width: none;
|
|
11
|
+
transition: width .1s ease-out;
|
|
12
|
+
|
|
13
|
+
&::-webkit-scrollbar {
|
|
14
|
+
display: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
li, a, .nav__toggle, .nav__menu-toggle {
|
|
18
|
+
font-size: 14px;
|
|
19
|
+
line-height: 1.5;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&__menu-toggle {
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
|
|
26
|
+
&:hover {
|
|
27
|
+
background-color: get-color(sapphire-blue-8);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&:active {
|
|
31
|
+
background-color: get-color(sapphire-blue-7);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
a, .nav__toggle {
|
|
36
|
+
width: 100%;
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
gap: get-spacing(paldiski);
|
|
40
|
+
color: get-color(black-coral-0);
|
|
41
|
+
padding: 14px 8px 14px 32px;
|
|
42
|
+
box-shadow: inset 0 -1px 0 get-color(sapphire-blue-14);
|
|
43
|
+
|
|
44
|
+
span:not(.icon) {
|
|
45
|
+
flex: 1;
|
|
46
|
+
display: block;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&:hover {
|
|
50
|
+
background-color: get-color(sapphire-blue-8);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&:active {
|
|
54
|
+
background-color: get-color(sapphire-blue-7);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&.active {
|
|
58
|
+
font-weight: 700;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&__toggle {
|
|
63
|
+
&[aria-expanded=true] {
|
|
64
|
+
font-weight: 700;
|
|
65
|
+
|
|
66
|
+
.icon {
|
|
67
|
+
transform: rotate(180deg);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
+ ul {
|
|
71
|
+
display: block;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&.nav__toggle--icon {
|
|
76
|
+
padding-left: 8px;
|
|
77
|
+
|
|
78
|
+
.icon:first-child {
|
|
79
|
+
transform: none;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
&__toggle-icon {
|
|
85
|
+
margin-left: auto;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
&__menu-toggle {
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
gap: get-spacing(paldiski);
|
|
92
|
+
width: 100%;
|
|
93
|
+
color: get-color(white);
|
|
94
|
+
padding: 14px 8px;
|
|
95
|
+
box-shadow: inset 0 -1px 0 get-color(sapphire-blue-14);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&__submenu {
|
|
99
|
+
display: none;
|
|
100
|
+
|
|
101
|
+
a, .nav__toggle {
|
|
102
|
+
background-color: get-color(sapphire-blue-14);
|
|
103
|
+
box-shadow: inset 0 -1px 0 get-color(sapphire-blue-17);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#{$self} {
|
|
107
|
+
&__submenu {
|
|
108
|
+
a {
|
|
109
|
+
background-color: get-color(sapphire-blue-17);
|
|
110
|
+
box-shadow: inset 0 -1px 0 get-color(black);
|
|
111
|
+
padding: 14px 48px 14px 40px;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.collapsed {
|
|
119
|
+
.nav__submenu {
|
|
120
|
+
visibility: hidden;
|
|
121
|
+
height: 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
button[aria-expanded=true] {
|
|
125
|
+
.icon {
|
|
126
|
+
transform: rotate(0deg);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
export interface TranslatedLabel {
|
|
3
|
-
[lang: string] : string;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export interface MenuItem {
|
|
7
|
-
id?: string;
|
|
8
|
-
label: TranslatedLabel;
|
|
9
|
-
path?: string;
|
|
10
|
-
target?: '_blank' | '_self';
|
|
11
|
-
children?: MenuItem[];
|
|
12
|
-
hidden?: boolean;
|
|
13
|
-
|
|
1
|
+
|
|
2
|
+
export interface TranslatedLabel {
|
|
3
|
+
[lang: string] : string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface MenuItem {
|
|
7
|
+
id?: string;
|
|
8
|
+
label: TranslatedLabel;
|
|
9
|
+
path?: string;
|
|
10
|
+
target?: '_blank' | '_self';
|
|
11
|
+
children?: MenuItem[];
|
|
12
|
+
hidden?: boolean;
|
|
13
|
+
count?: number
|
|
14
|
+
}
|
package/tsconfig.base.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compileOnSave": false,
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"rootDir": ".",
|
|
5
|
-
"sourceMap": true,
|
|
6
|
-
"declaration": false,
|
|
7
|
-
"moduleResolution": "node",
|
|
8
|
-
"emitDecoratorMetadata": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"experimentalDecorators": true,
|
|
11
|
-
"allowSyntheticDefaultImports": true,
|
|
12
|
-
"importHelpers": true,
|
|
13
|
-
"target": "es2015",
|
|
14
|
-
"module": "esnext",
|
|
15
|
-
"lib": ["es2017", "dom", "dom.Iterable"],
|
|
16
|
-
"skipLibCheck": true,
|
|
17
|
-
"skipDefaultLibCheck": true,
|
|
18
|
-
"baseUrl": ".",
|
|
19
|
-
},
|
|
20
|
-
"exclude": ["node_modules", "tmp"]
|
|
21
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compileOnSave": false,
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": ".",
|
|
5
|
+
"sourceMap": true,
|
|
6
|
+
"declaration": false,
|
|
7
|
+
"moduleResolution": "node",
|
|
8
|
+
"emitDecoratorMetadata": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"experimentalDecorators": true,
|
|
11
|
+
"allowSyntheticDefaultImports": true,
|
|
12
|
+
"importHelpers": true,
|
|
13
|
+
"target": "es2015",
|
|
14
|
+
"module": "esnext",
|
|
15
|
+
"lib": ["es2017", "dom", "dom.Iterable"],
|
|
16
|
+
"skipLibCheck": true,
|
|
17
|
+
"skipDefaultLibCheck": true,
|
|
18
|
+
"baseUrl": ".",
|
|
19
|
+
},
|
|
20
|
+
"exclude": ["node_modules", "tmp"]
|
|
21
|
+
}
|