@servicetitan/navigation 8.2.1 → 9.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.
- package/dist/components/counter-tag.d.ts +2 -4
- package/dist/components/counter-tag.d.ts.map +1 -1
- package/dist/components/counter-tag.js +3 -4
- package/dist/components/counter-tag.js.map +1 -1
- package/dist/components/header-navigation/header-navigation-content.d.ts +2 -2
- package/dist/components/header-navigation/header-navigation-content.d.ts.map +1 -1
- package/dist/components/header-navigation/header-navigation-content.js +4 -4
- package/dist/components/header-navigation/header-navigation-content.js.map +1 -1
- package/dist/components/header-navigation/header-navigation-extra.stories.js +3 -3
- package/dist/components/header-navigation/header-navigation-extra.stories.js.map +1 -1
- package/dist/components/header-navigation/header-navigation-links.js +4 -4
- package/dist/components/header-navigation/header-navigation-links.js.map +1 -1
- package/dist/components/header-navigation/header-navigation-stacked.stories.js +1 -1
- package/dist/components/header-navigation/header-navigation-stacked.stories.js.map +1 -1
- package/dist/components/header-navigation/header-navigation.module.less +2 -1
- package/dist/components/header-navigation/header-navigation.stories.js +1 -1
- package/dist/components/header-navigation/header-navigation.stories.js.map +1 -1
- package/dist/components/layout.stories.js +2 -2
- package/dist/components/layout.stories.js.map +1 -1
- package/dist/components/left-navigation/header-navigation-tiny-links.d.ts +1 -1
- package/dist/components/left-navigation/header-navigation-tiny-links.d.ts.map +1 -1
- package/dist/components/left-navigation/header-navigation-tiny-links.js +6 -6
- package/dist/components/left-navigation/header-navigation-tiny-links.js.map +1 -1
- package/dist/components/left-navigation/header-navigation-tiny.stories.js +2 -2
- package/dist/components/left-navigation/header-navigation-tiny.stories.js.map +1 -1
- package/dist/components/left-navigation/side-navigation.d.ts +8 -4
- package/dist/components/left-navigation/side-navigation.d.ts.map +1 -1
- package/dist/components/left-navigation/side-navigation.js +30 -20
- package/dist/components/left-navigation/side-navigation.js.map +1 -1
- package/dist/components/left-navigation/side-navigation.module.less +20 -12
- package/dist/components/left-navigation/side-navigation.stories.d.ts.map +1 -1
- package/dist/components/left-navigation/side-navigation.stories.js +7 -7
- package/dist/components/left-navigation/side-navigation.stories.js.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.d.ts +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.js +3 -3
- package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
- package/dist/test/data.d.ts +1 -0
- package/dist/test/data.d.ts.map +1 -1
- package/dist/test/data.js +10 -8
- package/dist/test/data.js.map +1 -1
- package/dist/utils/navigation.d.ts +9 -5
- package/dist/utils/navigation.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/components/counter-tag.tsx +12 -9
- package/src/components/header-navigation/header-navigation-content.tsx +7 -7
- package/src/components/header-navigation/header-navigation-extra.stories.tsx +3 -3
- package/src/components/header-navigation/header-navigation-links.tsx +4 -4
- package/src/components/header-navigation/header-navigation-stacked.stories.tsx +2 -2
- package/src/components/header-navigation/header-navigation.module.less +2 -1
- package/src/components/header-navigation/header-navigation.stories.tsx +2 -2
- package/src/components/layout.stories.tsx +2 -2
- package/src/components/left-navigation/header-navigation-tiny-links.tsx +8 -8
- package/src/components/left-navigation/header-navigation-tiny.stories.tsx +2 -2
- package/src/components/left-navigation/side-navigation.module.less +20 -12
- package/src/components/left-navigation/side-navigation.module.less.d.ts +1 -0
- package/src/components/left-navigation/side-navigation.stories.tsx +14 -8
- package/src/components/left-navigation/side-navigation.tsx +56 -43
- package/src/components/profile-dropdown/profile-dropdown.tsx +6 -9
- package/src/test/data.tsx +24 -12
- package/src/utils/navigation.ts +10 -5
|
@@ -12,7 +12,6 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
|
|
|
12
12
|
to,
|
|
13
13
|
hint,
|
|
14
14
|
tooltip,
|
|
15
|
-
counter,
|
|
16
15
|
className,
|
|
17
16
|
icon,
|
|
18
17
|
iconActive,
|
|
@@ -22,6 +21,7 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
|
|
|
22
21
|
isActive,
|
|
23
22
|
label,
|
|
24
23
|
labelClassName,
|
|
24
|
+
tag,
|
|
25
25
|
target,
|
|
26
26
|
...rest
|
|
27
27
|
}) => {
|
|
@@ -43,7 +43,7 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
|
|
|
43
43
|
target={target}
|
|
44
44
|
>
|
|
45
45
|
<HeaderNavigationItemContent
|
|
46
|
-
|
|
46
|
+
tag={tag}
|
|
47
47
|
iconComponent={iconComponent}
|
|
48
48
|
iconClassName={iconClassName}
|
|
49
49
|
iconName={iconName}
|
|
@@ -59,7 +59,6 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
|
|
|
59
59
|
export const HeaderNavigationTrigger: FC<HeaderNavigationTriggerProps> = ({
|
|
60
60
|
id,
|
|
61
61
|
className,
|
|
62
|
-
counter,
|
|
63
62
|
iconClassName,
|
|
64
63
|
iconComponent,
|
|
65
64
|
iconName,
|
|
@@ -67,6 +66,7 @@ export const HeaderNavigationTrigger: FC<HeaderNavigationTriggerProps> = ({
|
|
|
67
66
|
label,
|
|
68
67
|
labelClassName,
|
|
69
68
|
hint,
|
|
69
|
+
tag,
|
|
70
70
|
tooltip,
|
|
71
71
|
...rest
|
|
72
72
|
}) => {
|
|
@@ -87,7 +87,7 @@ export const HeaderNavigationTrigger: FC<HeaderNavigationTriggerProps> = ({
|
|
|
87
87
|
)}
|
|
88
88
|
>
|
|
89
89
|
<HeaderNavigationItemContent
|
|
90
|
-
|
|
90
|
+
tag={tag}
|
|
91
91
|
iconComponent={iconComponent}
|
|
92
92
|
iconClassName={iconClassName}
|
|
93
93
|
iconName={iconName}
|
|
@@ -96,7 +96,7 @@ export const WithAllMonolithData = () => (
|
|
|
96
96
|
<HeaderNavigationTrigger
|
|
97
97
|
id="dialpad"
|
|
98
98
|
iconName="phone"
|
|
99
|
-
|
|
99
|
+
tag={2}
|
|
100
100
|
icon={SvgIcon}
|
|
101
101
|
iconActive={SvgIcon}
|
|
102
102
|
/>
|
|
@@ -122,7 +122,7 @@ export const WithAllMonolithData = () => (
|
|
|
122
122
|
/>
|
|
123
123
|
|
|
124
124
|
<ProfileDropdown>
|
|
125
|
-
<ProfileDropdown.Link id="tasks" to="https://googgle.com"
|
|
125
|
+
<ProfileDropdown.Link id="tasks" to="https://googgle.com" tag={10}>
|
|
126
126
|
Task Management
|
|
127
127
|
</ProfileDropdown.Link>
|
|
128
128
|
<ProfileDropdown.Divider />
|
|
@@ -219,7 +219,8 @@
|
|
|
219
219
|
.navigation-item-counter {
|
|
220
220
|
color: @color-white;
|
|
221
221
|
font-weight: @font-weight-semibold;
|
|
222
|
-
min-width: 12px;
|
|
222
|
+
min-width: 12px !important;
|
|
223
|
+
min-height: 12px !important;
|
|
223
224
|
}
|
|
224
225
|
|
|
225
226
|
&:not(.navigation-item-overflow) .navigation-item-counter {
|
|
@@ -108,7 +108,7 @@ export const WithAllMonolithData = () => (
|
|
|
108
108
|
<HeaderNavigationTrigger
|
|
109
109
|
id="dialpad"
|
|
110
110
|
iconName="phone"
|
|
111
|
-
|
|
111
|
+
tag={2}
|
|
112
112
|
icon={SvgIcon}
|
|
113
113
|
iconActive={SvgIcon}
|
|
114
114
|
/>
|
|
@@ -145,7 +145,7 @@ export const WithAllMonolithData = () => (
|
|
|
145
145
|
/>
|
|
146
146
|
|
|
147
147
|
<ProfileDropdown>
|
|
148
|
-
<ProfileDropdown.Link id="tasks" to="https://googgle.com"
|
|
148
|
+
<ProfileDropdown.Link id="tasks" to="https://googgle.com" tag={10}>
|
|
149
149
|
Task Management
|
|
150
150
|
</ProfileDropdown.Link>
|
|
151
151
|
<ProfileDropdown.Divider />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Page, Sidebar } from '@servicetitan/design-system';
|
|
2
|
-
import { LocationInfo, withAnvil, withMemoryRouter } from '../test/data';
|
|
2
|
+
import { LocationInfo, withAnvil, withDefaultRedirects, withMemoryRouter } from '../test/data';
|
|
3
3
|
import {
|
|
4
4
|
WithAllMonolithData,
|
|
5
5
|
WithAllMonolithDataCommercial,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
export default {
|
|
14
14
|
title: 'Navigation/Layout',
|
|
15
15
|
parameters: {},
|
|
16
|
-
decorators: [withMemoryRouter, withAnvil],
|
|
16
|
+
decorators: [withDefaultRedirects, withMemoryRouter, withAnvil],
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export const LeftNavLayout = () => {
|
|
@@ -9,13 +9,13 @@ import { withTooltip } from './with-tooltip';
|
|
|
9
9
|
|
|
10
10
|
/** Content for navigation items */
|
|
11
11
|
export const HeaderNavigationItemContent: FC<{
|
|
12
|
-
|
|
12
|
+
tag?: CounterTagPropsType;
|
|
13
13
|
counterClassName?: string;
|
|
14
14
|
icon: IconProps['svg'] | undefined;
|
|
15
15
|
iconActive: IconProps['svg'] | undefined;
|
|
16
16
|
label?: string;
|
|
17
17
|
labelClassName?: string;
|
|
18
|
-
}> = ({
|
|
18
|
+
}> = ({ counterClassName, icon, iconActive, label, labelClassName, tag }) => {
|
|
19
19
|
return (
|
|
20
20
|
<Fragment>
|
|
21
21
|
{!!icon && <Icon svg={icon} className={Styles.navigationIcon} />}
|
|
@@ -32,9 +32,9 @@ export const HeaderNavigationItemContent: FC<{
|
|
|
32
32
|
</span>
|
|
33
33
|
)}
|
|
34
34
|
|
|
35
|
-
{!!
|
|
35
|
+
{!!tag && (
|
|
36
36
|
<CounterTag
|
|
37
|
-
data={
|
|
37
|
+
data={tag}
|
|
38
38
|
className={classNames(Styles.navigationItemCounter, counterClassName)}
|
|
39
39
|
longClassName={Styles.navigationItemCounterLong}
|
|
40
40
|
/>
|
|
@@ -49,13 +49,13 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
|
|
|
49
49
|
to,
|
|
50
50
|
hint,
|
|
51
51
|
tooltip,
|
|
52
|
-
counter,
|
|
53
52
|
className,
|
|
54
53
|
icon,
|
|
55
54
|
iconActive,
|
|
56
55
|
isActive,
|
|
57
56
|
label,
|
|
58
57
|
labelClassName,
|
|
58
|
+
tag,
|
|
59
59
|
target,
|
|
60
60
|
...rest
|
|
61
61
|
}) => {
|
|
@@ -78,7 +78,7 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
|
|
|
78
78
|
target={target}
|
|
79
79
|
>
|
|
80
80
|
<HeaderNavigationItemContent
|
|
81
|
-
|
|
81
|
+
tag={tag}
|
|
82
82
|
icon={icon}
|
|
83
83
|
iconActive={iconActive}
|
|
84
84
|
label={label}
|
|
@@ -93,13 +93,13 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
|
|
|
93
93
|
export const HeaderNavigationTrigger: FC<HeaderNavigationTriggerProps> = ({
|
|
94
94
|
id,
|
|
95
95
|
className,
|
|
96
|
-
counter,
|
|
97
96
|
icon,
|
|
98
97
|
iconActive,
|
|
99
98
|
isActive,
|
|
100
99
|
hint,
|
|
101
100
|
label,
|
|
102
101
|
labelClassName,
|
|
102
|
+
tag,
|
|
103
103
|
tooltip,
|
|
104
104
|
title,
|
|
105
105
|
titleClassName,
|
|
@@ -122,7 +122,7 @@ export const HeaderNavigationTrigger: FC<HeaderNavigationTriggerProps> = ({
|
|
|
122
122
|
)}
|
|
123
123
|
>
|
|
124
124
|
<HeaderNavigationItemContent
|
|
125
|
-
|
|
125
|
+
tag={tag}
|
|
126
126
|
icon={icon}
|
|
127
127
|
iconActive={iconActive}
|
|
128
128
|
label={label}
|
|
@@ -86,7 +86,7 @@ export const WithAllMonolithData = () => (
|
|
|
86
86
|
/>
|
|
87
87
|
|
|
88
88
|
<ProfileDropdown>
|
|
89
|
-
<ProfileDropdown.Link id="tasks" to="https://googgle.com"
|
|
89
|
+
<ProfileDropdown.Link id="tasks" to="https://googgle.com" tag={10}>
|
|
90
90
|
Task Management
|
|
91
91
|
</ProfileDropdown.Link>
|
|
92
92
|
<ProfileDropdown.Divider />
|
|
@@ -152,7 +152,7 @@ export const WithAllMonolithDataCommercial = () => (
|
|
|
152
152
|
/>
|
|
153
153
|
|
|
154
154
|
<ProfileDropdown>
|
|
155
|
-
<ProfileDropdown.Link id="tasks" to="https://googgle.com"
|
|
155
|
+
<ProfileDropdown.Link id="tasks" to="https://googgle.com" tag={10}>
|
|
156
156
|
Task Management
|
|
157
157
|
</ProfileDropdown.Link>
|
|
158
158
|
<ProfileDropdown.Divider />
|
|
@@ -73,7 +73,6 @@
|
|
|
73
73
|
|
|
74
74
|
.navigation-item {
|
|
75
75
|
flex-direction: row;
|
|
76
|
-
margin-bottom: @spacing-half;
|
|
77
76
|
margin-left: @spacing-1;
|
|
78
77
|
margin-right: @spacing-1;
|
|
79
78
|
|
|
@@ -85,9 +84,13 @@
|
|
|
85
84
|
.navigation-item-text {
|
|
86
85
|
font-family: @base-font-family;
|
|
87
86
|
font-size: @typescale-3;
|
|
88
|
-
padding-left: @spacing-
|
|
87
|
+
padding-left: @spacing-1;
|
|
89
88
|
flex: 1;
|
|
90
89
|
}
|
|
90
|
+
|
|
91
|
+
.navigation-item-counter {
|
|
92
|
+
margin-right: @spacing-1;
|
|
93
|
+
}
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
.options-item {
|
|
@@ -189,6 +192,8 @@
|
|
|
189
192
|
.navigation-item-counter {
|
|
190
193
|
color: @color-white;
|
|
191
194
|
font-weight: @font-weight-semibold;
|
|
195
|
+
min-width: 12px !important;
|
|
196
|
+
min-height: 12px !important;
|
|
192
197
|
}
|
|
193
198
|
|
|
194
199
|
.navigation-item-group-toggle[data-anv][data-anv] {
|
|
@@ -215,16 +220,6 @@
|
|
|
215
220
|
margin-bottom: @spacing-1;
|
|
216
221
|
position: relative;
|
|
217
222
|
|
|
218
|
-
&:before {
|
|
219
|
-
content: '';
|
|
220
|
-
position: absolute;
|
|
221
|
-
border-left: 1px solid @color-neutral-100;
|
|
222
|
-
width: 1px;
|
|
223
|
-
top: @spacing-2;
|
|
224
|
-
bottom: @spacing-1;
|
|
225
|
-
left: 0;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
223
|
.submenu-group-header[data-anv][data-anv] {
|
|
229
224
|
padding-top: @spacing-2;
|
|
230
225
|
padding-bottom: @spacing-half;
|
|
@@ -305,12 +300,25 @@
|
|
|
305
300
|
color: @text-color;
|
|
306
301
|
font-size: @typescale-2;
|
|
307
302
|
border-radius: @border-radius-2;
|
|
303
|
+
display: flex;
|
|
304
|
+
flex-direction: row;
|
|
305
|
+
justify-content: space-between;
|
|
306
|
+
align-items: center;
|
|
308
307
|
}
|
|
309
308
|
|
|
310
309
|
.submenu-link-active {
|
|
311
310
|
color: @text-color-active;
|
|
312
311
|
}
|
|
313
312
|
|
|
313
|
+
.submenu-link-counter {
|
|
314
|
+
min-height: 19px !important;
|
|
315
|
+
min-width: 19px !important;
|
|
316
|
+
|
|
317
|
+
> span:first-child {
|
|
318
|
+
color: @color-black;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
314
322
|
.submenu-link:hover:not(.submenu-link-active) {
|
|
315
323
|
background-color: @bg-color-hover;
|
|
316
324
|
}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import { Page
|
|
1
|
+
import { Page } from '@servicetitan/design-system';
|
|
2
2
|
import { ComponentType, useState } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
LocationInfo,
|
|
5
|
+
items,
|
|
6
|
+
withAnvil,
|
|
7
|
+
withDefaultRedirects,
|
|
8
|
+
withMemoryRouter,
|
|
9
|
+
} from '../../test/data';
|
|
10
|
+
import { SideNavigation, SideNavigationExpandedState } from './';
|
|
5
11
|
|
|
6
12
|
const layout = (Story: ComponentType) => {
|
|
7
13
|
return (
|
|
8
14
|
<div className="d-f border" style={{ height: '800px' }}>
|
|
9
15
|
<Story />
|
|
10
16
|
<div className="flex-grow-1 flex-basis-0">
|
|
11
|
-
<Page
|
|
17
|
+
<Page>
|
|
12
18
|
<LocationInfo />
|
|
13
19
|
</Page>
|
|
14
20
|
</div>
|
|
@@ -18,12 +24,12 @@ const layout = (Story: ComponentType) => {
|
|
|
18
24
|
export default {
|
|
19
25
|
title: 'Navigation/SideNavigation',
|
|
20
26
|
component: SideNavigation,
|
|
21
|
-
decorators: [layout, withMemoryRouter, withAnvil],
|
|
27
|
+
decorators: [layout, withDefaultRedirects, withMemoryRouter, withAnvil],
|
|
22
28
|
parameters: {},
|
|
23
29
|
};
|
|
24
30
|
|
|
25
31
|
export const DefaultSideNavigation = () => {
|
|
26
|
-
const [expanded, setExpanded] = useState(
|
|
32
|
+
const [expanded, setExpanded] = useState<SideNavigationExpandedState | undefined>(undefined);
|
|
27
33
|
return (
|
|
28
34
|
<SideNavigation
|
|
29
35
|
expanded={expanded}
|
|
@@ -50,7 +56,7 @@ export const DefaultSideNavigation = () => {
|
|
|
50
56
|
};
|
|
51
57
|
|
|
52
58
|
export const SideNavigationLinksOnly = () => {
|
|
53
|
-
const [expanded, setExpanded] = useState(
|
|
59
|
+
const [expanded, setExpanded] = useState<SideNavigationExpandedState | undefined>(undefined);
|
|
54
60
|
return (
|
|
55
61
|
<SideNavigation
|
|
56
62
|
expanded={expanded}
|
|
@@ -76,7 +82,7 @@ export const SideNavigationLinksOnly = () => {
|
|
|
76
82
|
};
|
|
77
83
|
|
|
78
84
|
export const SideNavigationWithSubmenu = () => {
|
|
79
|
-
const [expanded, setExpanded] = useState(
|
|
85
|
+
const [expanded, setExpanded] = useState<SideNavigationExpandedState | undefined>(undefined);
|
|
80
86
|
return (
|
|
81
87
|
<SideNavigation
|
|
82
88
|
expanded={expanded}
|
|
@@ -14,12 +14,11 @@ import {
|
|
|
14
14
|
ReactElement,
|
|
15
15
|
useCallback,
|
|
16
16
|
useContext,
|
|
17
|
-
useState,
|
|
18
17
|
} from 'react';
|
|
19
18
|
import {
|
|
20
19
|
HeaderNavigationItemData,
|
|
21
|
-
HeaderNavigationItemLinkProps,
|
|
22
20
|
HeaderNavigationItemSubmenu,
|
|
21
|
+
HeaderNavigationItemSubmenuLink,
|
|
23
22
|
NavLinkComponentProps,
|
|
24
23
|
} from '../../utils/navigation';
|
|
25
24
|
import { NavigationComponentContext } from '../../utils/navigation-context';
|
|
@@ -27,6 +26,11 @@ import { CounterTag } from '../counter-tag';
|
|
|
27
26
|
import * as Styles from './side-navigation.module.less';
|
|
28
27
|
import { withTooltip } from './with-tooltip';
|
|
29
28
|
|
|
29
|
+
export interface SideNavigationExpandedState {
|
|
30
|
+
bar: boolean;
|
|
31
|
+
submenus?: string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
30
34
|
export interface SideNavigationProps {
|
|
31
35
|
/** container class name */
|
|
32
36
|
className?: string;
|
|
@@ -37,9 +41,9 @@ export interface SideNavigationProps {
|
|
|
37
41
|
/** top navigation items */
|
|
38
42
|
itemsTop?: HeaderNavigationItemData[];
|
|
39
43
|
/** is menu expanded */
|
|
40
|
-
expanded?:
|
|
44
|
+
expanded?: SideNavigationExpandedState;
|
|
41
45
|
/** expand change handler */
|
|
42
|
-
onExpandedChange(expanded:
|
|
46
|
+
onExpandedChange?(expanded: SideNavigationExpandedState): void;
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
export const SideNavigation: FC<SideNavigationProps> = ({
|
|
@@ -55,7 +59,7 @@ export const SideNavigation: FC<SideNavigationProps> = ({
|
|
|
55
59
|
<div
|
|
56
60
|
className={classNames(
|
|
57
61
|
Styles.sideNav,
|
|
58
|
-
expanded ? Styles.sideNavExpanded : Styles.sideNavSlim,
|
|
62
|
+
expanded?.bar ? Styles.sideNavExpanded : Styles.sideNavSlim,
|
|
59
63
|
className
|
|
60
64
|
)}
|
|
61
65
|
id={id}
|
|
@@ -82,6 +86,7 @@ export const SideNavigation: FC<SideNavigationProps> = ({
|
|
|
82
86
|
<SideNavigationGroupItem
|
|
83
87
|
key={item.id}
|
|
84
88
|
expanded={expanded}
|
|
89
|
+
onExpandedChange={onExpandedChange}
|
|
85
90
|
navigationComponent={NavigationComponent}
|
|
86
91
|
{...item}
|
|
87
92
|
/>
|
|
@@ -111,18 +116,14 @@ interface NavigationComponentProps {
|
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
interface SideNavigationItemProps extends HeaderNavigationItemData, NavigationComponentProps {
|
|
114
|
-
expanded?:
|
|
115
|
-
submenuExpanded?: boolean;
|
|
119
|
+
expanded?: SideNavigationExpandedState;
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
/** Side Navigation menu item */
|
|
119
123
|
const SideNavigationItem: FC<SideNavigationItemProps> = ({
|
|
120
124
|
id,
|
|
121
|
-
submenuExpanded,
|
|
122
125
|
to,
|
|
123
126
|
title,
|
|
124
|
-
hint,
|
|
125
|
-
counter,
|
|
126
127
|
className,
|
|
127
128
|
iconClassName,
|
|
128
129
|
iconComponent: IconComponent,
|
|
@@ -130,10 +131,12 @@ const SideNavigationItem: FC<SideNavigationItemProps> = ({
|
|
|
130
131
|
iconActive,
|
|
131
132
|
isActive,
|
|
132
133
|
navigationComponent: NavigationComponent,
|
|
134
|
+
tag,
|
|
133
135
|
expanded,
|
|
136
|
+
submenu,
|
|
134
137
|
}) => {
|
|
135
138
|
const iconSwitch = !!icon && !!iconActive && !IconComponent;
|
|
136
|
-
const hasSubmenu =
|
|
139
|
+
const hasSubmenu = !!submenu;
|
|
137
140
|
|
|
138
141
|
return (
|
|
139
142
|
<NavigationComponent
|
|
@@ -141,7 +144,6 @@ const SideNavigationItem: FC<SideNavigationItemProps> = ({
|
|
|
141
144
|
data-pendo={`navigation-item-${id}`}
|
|
142
145
|
key={id}
|
|
143
146
|
to={to}
|
|
144
|
-
title={hint}
|
|
145
147
|
className={classNames(Styles.navigationItem, className, {
|
|
146
148
|
[Styles.navigationItemActive]: isActive === true,
|
|
147
149
|
[Styles.navigationItemIconSwitch]: iconSwitch,
|
|
@@ -179,19 +181,17 @@ const SideNavigationItem: FC<SideNavigationItemProps> = ({
|
|
|
179
181
|
</Fragment>
|
|
180
182
|
)}
|
|
181
183
|
|
|
182
|
-
{!!expanded && <div className={Styles.navigationItemText}>{title}</div>}
|
|
183
|
-
{!!
|
|
184
|
-
|
|
185
|
-
)}
|
|
186
|
-
{hasSubmenu && !!expanded && (
|
|
184
|
+
{!!expanded?.bar && <div className={Styles.navigationItemText}>{title}</div>}
|
|
185
|
+
{!!tag && <CounterTag data={tag} className={Styles.navigationItemCounter} />}
|
|
186
|
+
{hasSubmenu && !!expanded?.bar && (
|
|
187
187
|
<Icon
|
|
188
|
-
svg={
|
|
188
|
+
svg={expanded?.submenus?.includes(id) ? SvgGroupCollapse : SvgGroupExpand}
|
|
189
189
|
className={Styles.navigationItemGroupToggle}
|
|
190
190
|
/>
|
|
191
191
|
)}
|
|
192
192
|
</div>
|
|
193
193
|
|
|
194
|
-
{!expanded && (
|
|
194
|
+
{!expanded?.bar && (
|
|
195
195
|
<div
|
|
196
196
|
className={classNames(Styles.navigationItemText, {
|
|
197
197
|
[Styles.navigationItemTextSmall]: title.length >= 10,
|
|
@@ -207,26 +207,38 @@ const SideNavigationItem: FC<SideNavigationItemProps> = ({
|
|
|
207
207
|
const submenuPopoverStyles = { '--background-color-strong': '#24323C' } as CSSProperties;
|
|
208
208
|
|
|
209
209
|
/** Side Navigation menu item */
|
|
210
|
-
const SideNavigationGroupItem: FC<
|
|
211
|
-
|
|
210
|
+
const SideNavigationGroupItem: FC<
|
|
211
|
+
SideNavigationItemProps & {
|
|
212
|
+
onExpandedChange: undefined | ((expanded: SideNavigationExpandedState) => void);
|
|
213
|
+
}
|
|
214
|
+
> = ({ onExpandedChange, ...props }) => {
|
|
212
215
|
const triggerClick = useCallback(
|
|
213
216
|
(e: MouseEvent<HTMLDivElement>) => {
|
|
214
217
|
e.stopPropagation();
|
|
215
218
|
e.preventDefault();
|
|
216
219
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
const isSubmenuExpanded = props.expanded?.submenus?.includes(props.id);
|
|
221
|
+
onExpandedChange?.({
|
|
222
|
+
bar: !!props.expanded?.bar,
|
|
223
|
+
submenus: [
|
|
224
|
+
...(props.expanded?.submenus?.filter(id => id !== props.id) ?? []),
|
|
225
|
+
...(isSubmenuExpanded ? [] : [props.id]),
|
|
226
|
+
],
|
|
227
|
+
});
|
|
220
228
|
},
|
|
221
|
-
[props.expanded]
|
|
229
|
+
[props.id, props.expanded, onExpandedChange]
|
|
222
230
|
);
|
|
223
231
|
|
|
224
|
-
|
|
232
|
+
const tag = props.submenu?.groups.some(group => group.links.some(link => !!link.tag))
|
|
233
|
+
? true
|
|
234
|
+
: props.tag;
|
|
235
|
+
|
|
236
|
+
return props.expanded?.bar ? (
|
|
225
237
|
<Fragment>
|
|
226
238
|
<div onClickCapture={triggerClick}>
|
|
227
|
-
<SideNavigationItem {...props}
|
|
239
|
+
<SideNavigationItem {...props} tag={tag} />
|
|
228
240
|
</div>
|
|
229
|
-
<Collapsible open={
|
|
241
|
+
<Collapsible open={props.expanded?.submenus?.includes(props.id)} animate>
|
|
230
242
|
<div className={Styles.submenu}>
|
|
231
243
|
<SideNavigationGroupContent
|
|
232
244
|
groups={props.submenu?.groups ?? []}
|
|
@@ -239,8 +251,8 @@ const SideNavigationGroupItem: FC<SideNavigationItemProps> = ({ ...props }) => {
|
|
|
239
251
|
<Popover placement="right-start" openOnHover>
|
|
240
252
|
<Popover.Trigger>
|
|
241
253
|
{(triggerProps: PopoverTriggerProps) => (
|
|
242
|
-
<div {...triggerProps}
|
|
243
|
-
<SideNavigationItem {...props} />
|
|
254
|
+
<div {...triggerProps}>
|
|
255
|
+
<SideNavigationItem {...props} tag={tag} />
|
|
244
256
|
</div>
|
|
245
257
|
)}
|
|
246
258
|
</Popover.Trigger>
|
|
@@ -264,17 +276,14 @@ const SideNavigationGroupContent: FC<HeaderNavigationItemSubmenu & NavigationCom
|
|
|
264
276
|
}) => {
|
|
265
277
|
return (
|
|
266
278
|
<Fragment>
|
|
267
|
-
{groups.reduce((out, group) => {
|
|
279
|
+
{groups.reduce((out, group, index) => {
|
|
268
280
|
if (!group.links.length) {
|
|
269
281
|
return out;
|
|
270
282
|
}
|
|
271
283
|
|
|
284
|
+
const key = `:group:${index}:title`;
|
|
272
285
|
out.push(
|
|
273
|
-
<Text
|
|
274
|
-
key=":group:title"
|
|
275
|
-
variant="eyebrow"
|
|
276
|
-
className={Styles.submenuGroupHeader}
|
|
277
|
-
>
|
|
286
|
+
<Text key={key} variant="eyebrow" className={Styles.submenuGroupHeader}>
|
|
278
287
|
{group.title}
|
|
279
288
|
</Text>
|
|
280
289
|
);
|
|
@@ -293,8 +302,9 @@ const SideNavigationGroupContent: FC<HeaderNavigationItemSubmenu & NavigationCom
|
|
|
293
302
|
</Fragment>
|
|
294
303
|
);
|
|
295
304
|
};
|
|
296
|
-
const SideNavigationGroupLink: FC<
|
|
305
|
+
const SideNavigationGroupLink: FC<HeaderNavigationItemSubmenuLink & NavigationComponentProps> = ({
|
|
297
306
|
id,
|
|
307
|
+
tag,
|
|
298
308
|
title,
|
|
299
309
|
to,
|
|
300
310
|
isActive,
|
|
@@ -312,29 +322,32 @@ const SideNavigationGroupLink: FC<HeaderNavigationItemLinkProps & NavigationComp
|
|
|
312
322
|
isActive={typeof isActive === 'function' ? isActive : undefined}
|
|
313
323
|
activeClassName={Styles.submenuLinkActive}
|
|
314
324
|
>
|
|
315
|
-
{title}
|
|
325
|
+
<span>{title}</span>
|
|
326
|
+
{!!tag && <CounterTag data={tag} className={Styles.submenuLinkCounter} />}
|
|
316
327
|
</NavigationComponent>
|
|
317
328
|
);
|
|
318
329
|
};
|
|
319
330
|
|
|
320
331
|
/** Side Navigation options toggle */
|
|
321
332
|
export const SideNavigationOptionsToggle: FC<{
|
|
322
|
-
expanded?:
|
|
323
|
-
onExpandedChange(expanded:
|
|
333
|
+
expanded?: SideNavigationExpandedState;
|
|
334
|
+
onExpandedChange?(expanded: SideNavigationExpandedState): void;
|
|
324
335
|
}> = ({ expanded, onExpandedChange }) =>
|
|
325
336
|
withTooltip(
|
|
326
337
|
<div
|
|
327
338
|
data-cy="navigation-left-options"
|
|
328
339
|
data-pendo="navigation-left-options"
|
|
329
340
|
className={classNames(Styles.optionsItem)}
|
|
330
|
-
onClick={() =>
|
|
341
|
+
onClick={() =>
|
|
342
|
+
onExpandedChange?.({ bar: !expanded?.bar, submenus: expanded?.submenus })
|
|
343
|
+
}
|
|
331
344
|
>
|
|
332
345
|
<div className={Styles.optionsIconWrapper}>
|
|
333
346
|
<Icon className={Styles.optionsIcon} svg={expanded ? SvgCollapse : SvgExpand} />
|
|
334
347
|
</div>
|
|
335
348
|
|
|
336
|
-
{!!expanded && <span className={Styles.optionsItemText}>Collapse Menu</span>}
|
|
349
|
+
{!!expanded?.bar && <span className={Styles.optionsItemText}>Collapse Menu</span>}
|
|
337
350
|
</div>,
|
|
338
|
-
expanded ? undefined : 'Expand Menu',
|
|
351
|
+
expanded?.bar ? undefined : 'Expand Menu',
|
|
339
352
|
'right'
|
|
340
353
|
);
|
|
@@ -192,7 +192,7 @@ export interface ProfileDropdownLinkPropsStrict {
|
|
|
192
192
|
external?: boolean;
|
|
193
193
|
target?: HTMLAttributeAnchorTarget;
|
|
194
194
|
to?: string;
|
|
195
|
-
|
|
195
|
+
tag?: CounterTagPropsType;
|
|
196
196
|
onClick?: () => void;
|
|
197
197
|
}
|
|
198
198
|
|
|
@@ -203,9 +203,9 @@ export interface ProfileDropdownLinkProps extends ProfileDropdownLinkPropsStrict
|
|
|
203
203
|
export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
|
|
204
204
|
children,
|
|
205
205
|
className,
|
|
206
|
-
counter,
|
|
207
206
|
external,
|
|
208
207
|
id,
|
|
208
|
+
tag,
|
|
209
209
|
target,
|
|
210
210
|
to,
|
|
211
211
|
onClick,
|
|
@@ -220,10 +220,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
|
|
|
220
220
|
|
|
221
221
|
const isExternalLink = external ?? to?.startsWith('http');
|
|
222
222
|
|
|
223
|
-
const
|
|
224
|
-
() => <CounterTag data={counter} className={Styles.counter} />,
|
|
225
|
-
[counter]
|
|
226
|
-
);
|
|
223
|
+
const tagElement = useMemo(() => <CounterTag data={tag} className={Styles.counter} />, [tag]);
|
|
227
224
|
|
|
228
225
|
return isExternalLink ? (
|
|
229
226
|
<a
|
|
@@ -235,7 +232,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
|
|
|
235
232
|
{...rest}
|
|
236
233
|
>
|
|
237
234
|
{children}
|
|
238
|
-
{
|
|
235
|
+
{tagElement}
|
|
239
236
|
</a>
|
|
240
237
|
) : to ? (
|
|
241
238
|
<NavigationComponent
|
|
@@ -247,7 +244,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
|
|
|
247
244
|
{...rest}
|
|
248
245
|
>
|
|
249
246
|
{children}
|
|
250
|
-
{
|
|
247
|
+
{tagElement}
|
|
251
248
|
</NavigationComponent>
|
|
252
249
|
) : (
|
|
253
250
|
<a
|
|
@@ -258,7 +255,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
|
|
|
258
255
|
{...rest}
|
|
259
256
|
>
|
|
260
257
|
{children}
|
|
261
|
-
{
|
|
258
|
+
{tagElement}
|
|
262
259
|
</a>
|
|
263
260
|
);
|
|
264
261
|
};
|