@servicetitan/navigation 3.0.0 → 3.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.
- package/dist/components/header-navigation/header-navigation-tiny.stories.d.ts +3 -2
- package/dist/components/header-navigation/header-navigation-tiny.stories.d.ts.map +1 -1
- package/dist/components/header-navigation/header-navigation-tiny.stories.js +8 -5
- package/dist/components/header-navigation/header-navigation-tiny.stories.js.map +1 -1
- package/dist/components/header-navigation/header-navigation.module.less +71 -51
- package/dist/components/layout.stories.d.ts +8 -0
- package/dist/components/layout.stories.d.ts.map +1 -0
- package/dist/components/layout.stories.js +14 -0
- package/dist/components/layout.stories.js.map +1 -0
- package/dist/components/logo/logo-company-title.js +1 -1
- package/dist/components/logo/logo-company-title.js.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.d.ts +0 -1
- package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.js +2 -2
- package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
- package/dist/components/profile-dropdown/profile-icon.d.ts +1 -3
- package/dist/components/profile-dropdown/profile-icon.d.ts.map +1 -1
- package/dist/components/profile-dropdown/profile-icon.js +3 -1
- package/dist/components/profile-dropdown/profile-icon.js.map +1 -1
- package/dist/components/side-navigation/icons.d.ts +4 -1
- package/dist/components/side-navigation/icons.d.ts.map +1 -1
- package/dist/components/side-navigation/icons.js +1 -1
- package/dist/components/side-navigation/icons.js.map +1 -1
- package/dist/components/side-navigation/side-navigation.d.ts +10 -3
- package/dist/components/side-navigation/side-navigation.d.ts.map +1 -1
- package/dist/components/side-navigation/side-navigation.js +8 -7
- package/dist/components/side-navigation/side-navigation.js.map +1 -1
- package/dist/components/side-navigation/side-navigation.module.less +38 -23
- package/dist/components/side-navigation/side-navigation.stories.d.ts.map +1 -1
- package/dist/components/side-navigation/side-navigation.stories.js +2 -1
- package/dist/components/side-navigation/side-navigation.stories.js.map +1 -1
- package/package.json +2 -2
- package/src/components/header-navigation/header-navigation-tiny.stories.tsx +75 -17
- package/src/components/header-navigation/header-navigation.module.less +71 -51
- package/src/components/layout.stories.tsx +34 -0
- package/src/components/logo/logo-company-title.tsx +1 -1
- package/src/components/profile-dropdown/profile-dropdown.tsx +2 -4
- package/src/components/profile-dropdown/profile-icon.tsx +5 -5
- package/src/components/side-navigation/icons.tsx +17 -16
- package/src/components/side-navigation/side-navigation.module.less +38 -23
- package/src/components/side-navigation/side-navigation.module.less.d.ts +2 -1
- package/src/components/side-navigation/side-navigation.stories.tsx +2 -0
- package/src/components/side-navigation/side-navigation.tsx +33 -14
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
export const IconSideOptions: FC<{ expanded?: boolean }> = ({ expanded }) => (
|
|
2
4
|
<svg
|
|
3
5
|
width="1em"
|
|
4
6
|
height="1em"
|
|
5
|
-
viewBox="0 0
|
|
7
|
+
viewBox="0 0 24 24"
|
|
6
8
|
fill="none"
|
|
7
9
|
xmlns="http://www.w3.org/2000/svg"
|
|
8
10
|
>
|
|
9
11
|
<path
|
|
10
|
-
d="
|
|
11
|
-
|
|
12
|
-
strokeWidth="2"
|
|
13
|
-
strokeOpacity="1"
|
|
14
|
-
/>
|
|
15
|
-
<rect
|
|
16
|
-
x="1"
|
|
17
|
-
y="1"
|
|
18
|
-
width="16"
|
|
19
|
-
height="16"
|
|
20
|
-
rx="2"
|
|
21
|
-
stroke="currentColor"
|
|
22
|
-
strokeWidth="2"
|
|
23
|
-
strokeOpacity="1"
|
|
12
|
+
d="M5 21C4.45 21 3.98 20.8 3.59 20.41C3.2 20.02 3 19.55 3 19V5C3 4.45 3.2 3.98 3.59 3.59C3.98 3.2 4.45 3 5 3H19C19.55 3 20.02 3.2 20.41 3.59C20.8 3.98 21 4.45 21 5V19C21 19.55 20.8 20.02 20.41 20.41C20.02 20.8 19.55 21 19 21H5ZM8 19V5H5V19H8ZM10 19H19V5H10V19Z"
|
|
13
|
+
fill="currentColor"
|
|
24
14
|
/>
|
|
15
|
+
{expanded ? (
|
|
16
|
+
<path
|
|
17
|
+
d="M16.54 14.19C16.71 14.38 16.71 14.66 16.54 14.85L16 15.46C15.9 15.56 15.77 15.62 15.62 15.62C15.48 15.62 15.35 15.56 15.25 15.46L12.46 12.33C12.29 12.14 12.29 11.86 12.46 11.67L15.25 8.54001C15.44 8.33001 15.81 8.33001 16 8.54001L16.54 9.15001C16.71 9.34001 16.71 9.62001 16.54 9.81001L14.58 12L16.54 14.19Z"
|
|
18
|
+
fill="currentColor"
|
|
19
|
+
/>
|
|
20
|
+
) : (
|
|
21
|
+
<path
|
|
22
|
+
d="M16.54 12.33L13.75 15.46C13.65 15.56 13.52 15.62 13.38 15.62C13.23 15.62 13.1 15.56 13 15.46L12.46 14.85C12.29 14.66 12.29 14.38 12.46 14.19L14.41 12L12.46 9.81001C12.29 9.62001 12.29 9.34001 12.46 9.15001L13 8.54001C13.19 8.33001 13.56 8.33001 13.75 8.54001L16.54 11.67C16.71 11.86 16.71 12.14 16.54 12.33Z"
|
|
23
|
+
fill="currentColor"
|
|
24
|
+
/>
|
|
25
|
+
)}
|
|
25
26
|
</svg>
|
|
26
27
|
);
|
|
27
28
|
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/* stylelint-disable no-descending-specificity */
|
|
2
2
|
@import (reference) '@servicetitan/tokens/core/tokens.less';
|
|
3
3
|
|
|
4
|
-
@text-color:
|
|
5
|
-
@
|
|
4
|
+
@text-color: var(--colorsTextInverted, @color-white);
|
|
5
|
+
@text-color-active: var(--colorsTextPrimarySubdued, @color-blue-300);
|
|
6
|
+
@border-color: var(--colorsTextOnGrey, @color-neutral-200);
|
|
7
|
+
@bg-color: var(--colorsSurfaceInvertedStrong, @color-neutral-400);
|
|
8
|
+
@bg-color-hover: rgba(255, 255, 255, 0.12);
|
|
6
9
|
|
|
7
10
|
.side-nav {
|
|
8
11
|
display: flex;
|
|
@@ -14,20 +17,16 @@
|
|
|
14
17
|
-o-transition: width 100ms ease-in-out;
|
|
15
18
|
transition: width 100ms ease-in-out;
|
|
16
19
|
|
|
17
|
-
background-color:
|
|
18
|
-
border-right: 1px solid @border-color;
|
|
20
|
+
background-color: @bg-color;
|
|
19
21
|
|
|
20
22
|
.side-nav-bottom {
|
|
21
|
-
padding-left:
|
|
22
|
-
padding-right:
|
|
23
|
+
padding-left: @spacing-1;
|
|
24
|
+
padding-right: @spacing-1;
|
|
25
|
+
border-top: 1px solid @border-color;
|
|
23
26
|
|
|
24
27
|
display: flex;
|
|
25
28
|
flex-direction: column;
|
|
26
29
|
justify-content: center;
|
|
27
|
-
|
|
28
|
-
.sideNavBottomDivider {
|
|
29
|
-
border-top: 1px solid @border-color;
|
|
30
|
-
}
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
&.side-nav-slim {
|
|
@@ -42,7 +41,7 @@
|
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
&.side-nav-expanded {
|
|
45
|
-
width:
|
|
44
|
+
width: 204px;
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
.side-nav-content {
|
|
@@ -50,16 +49,24 @@
|
|
|
50
49
|
flex-direction: column;
|
|
51
50
|
align-items: stretch;
|
|
52
51
|
overflow-y: auto;
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
padding-top: @spacing-1;
|
|
53
|
+
padding-bottom: @spacing-1;
|
|
55
54
|
flex-grow: 1;
|
|
56
55
|
flex-basis: 0;
|
|
57
56
|
}
|
|
57
|
+
|
|
58
|
+
.side-nav-top {
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
align-items: stretch;
|
|
62
|
+
padding-top: @spacing-1;
|
|
63
|
+
padding-bottom: @spacing-1;
|
|
64
|
+
}
|
|
58
65
|
}
|
|
59
66
|
|
|
60
67
|
.navigation-item {
|
|
61
68
|
font-family: @base-font-family;
|
|
62
|
-
color:
|
|
69
|
+
color: @text-color;
|
|
63
70
|
position: relative;
|
|
64
71
|
display: flex;
|
|
65
72
|
justify-content: flex-start;
|
|
@@ -73,11 +80,12 @@
|
|
|
73
80
|
border-radius: 12px;
|
|
74
81
|
|
|
75
82
|
&.navigation-item-active {
|
|
76
|
-
background-color:
|
|
83
|
+
background-color: rgba(2, 101, 220, 0.3);
|
|
84
|
+
color: @text-color-active;
|
|
77
85
|
}
|
|
78
86
|
|
|
79
87
|
&:hover:not(.navigation-item-active) {
|
|
80
|
-
|
|
88
|
+
background-color: @bg-color-hover;
|
|
81
89
|
}
|
|
82
90
|
|
|
83
91
|
.navigation-item-counter {
|
|
@@ -109,27 +117,28 @@
|
|
|
109
117
|
flex-wrap: nowrap;
|
|
110
118
|
text-wrap: nowrap;
|
|
111
119
|
cursor: pointer;
|
|
112
|
-
height:
|
|
120
|
+
height: 40px;
|
|
113
121
|
|
|
114
122
|
margin-top: @spacing-1;
|
|
115
123
|
margin-bottom: @spacing-1;
|
|
116
124
|
border-radius: 8px;
|
|
117
125
|
|
|
118
126
|
&:hover {
|
|
119
|
-
background-color: @color-
|
|
127
|
+
background-color: @bg-color-hover;
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
.options-icon {
|
|
123
|
-
height:
|
|
124
|
-
width:
|
|
125
|
-
font-size:
|
|
126
|
-
padding-left:
|
|
131
|
+
height: 24px;
|
|
132
|
+
width: 24px;
|
|
133
|
+
font-size: 24px;
|
|
134
|
+
padding-left: @spacing-1;
|
|
135
|
+
padding-right: @spacing-1;
|
|
127
136
|
}
|
|
128
137
|
|
|
129
138
|
.options-item-text {
|
|
130
139
|
font-family: @base-font-family;
|
|
131
140
|
font-size: @typescale-3;
|
|
132
|
-
padding-left: @spacing-
|
|
141
|
+
padding-left: @spacing-1;
|
|
133
142
|
flex: 1;
|
|
134
143
|
}
|
|
135
144
|
}
|
|
@@ -151,3 +160,9 @@
|
|
|
151
160
|
.options-popover-item-active {
|
|
152
161
|
border-radius: @border-radius-1;
|
|
153
162
|
}
|
|
163
|
+
|
|
164
|
+
.divider {
|
|
165
|
+
border-top: 1px solid @border-color;
|
|
166
|
+
margin-left: 12px;
|
|
167
|
+
margin-right: 12px;
|
|
168
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const __esModule: true;
|
|
2
|
+
export const divider: string;
|
|
2
3
|
export const navigationIcon: string;
|
|
3
4
|
export const navigationItem: string;
|
|
4
5
|
export const navigationItemActive: string;
|
|
@@ -12,8 +13,8 @@ export const optionsPopoverItemClickable: string;
|
|
|
12
13
|
export const optionsPopoverItemInactive: string;
|
|
13
14
|
export const sideNav: string;
|
|
14
15
|
export const sideNavBottom: string;
|
|
15
|
-
export const sideNavBottomDivider: string;
|
|
16
16
|
export const sideNavContent: string;
|
|
17
17
|
export const sideNavExpanded: string;
|
|
18
18
|
export const sideNavSlim: string;
|
|
19
|
+
export const sideNavTop: string;
|
|
19
20
|
|
|
@@ -50,6 +50,7 @@ const items = {
|
|
|
50
50
|
pointOfSale: getItem('pointOfSale', { iconName: 'cash-register' }),
|
|
51
51
|
projects: getItem('projects', { iconName: 'folder_special' }),
|
|
52
52
|
reports: getItem('reports', { iconName: 'poll' }),
|
|
53
|
+
tasks: getItem('tasks', { iconName: 'format_list_bulleted' }),
|
|
53
54
|
};
|
|
54
55
|
|
|
55
56
|
const NavLinkMock: FC<NavLinkComponentProps> = props => (
|
|
@@ -88,6 +89,7 @@ export const DefaultSideNavigation = () => {
|
|
|
88
89
|
items.pointOfSale,
|
|
89
90
|
items.reports,
|
|
90
91
|
]}
|
|
92
|
+
itemsTop={[items.tasks]}
|
|
91
93
|
/>
|
|
92
94
|
);
|
|
93
95
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BodyText, Divider, Eyebrow, Icon, Popover, Stack } from '@servicetitan/design-system';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
|
-
import { FC, useState } from 'react';
|
|
3
|
+
import { FC, Fragment, PropsWithChildren, useState } from 'react';
|
|
4
4
|
import { HeaderNavigationItemData, NavLinkComponentProps } from '../../utils/navigation';
|
|
5
5
|
import {
|
|
6
6
|
DefaultNavLinkComponent,
|
|
@@ -19,6 +19,8 @@ export interface SideNavigationProps {
|
|
|
19
19
|
id?: string;
|
|
20
20
|
/** main navigation items */
|
|
21
21
|
items?: HeaderNavigationItemData[];
|
|
22
|
+
/** top navigation items */
|
|
23
|
+
itemsTop?: HeaderNavigationItemData[];
|
|
22
24
|
/** is menu expanded */
|
|
23
25
|
expanded?: boolean;
|
|
24
26
|
/** navigation component used for routing */
|
|
@@ -32,6 +34,7 @@ export const SideNavigation: FC<SideNavigationProps> = ({
|
|
|
32
34
|
expanded,
|
|
33
35
|
id,
|
|
34
36
|
items,
|
|
37
|
+
itemsTop,
|
|
35
38
|
navigationComponent = DefaultNavLinkComponent,
|
|
36
39
|
onExpandedChange,
|
|
37
40
|
}) => {
|
|
@@ -46,14 +49,23 @@ export const SideNavigation: FC<SideNavigationProps> = ({
|
|
|
46
49
|
id={id}
|
|
47
50
|
data-cy="side-navigation"
|
|
48
51
|
>
|
|
52
|
+
{!!itemsTop?.length && (
|
|
53
|
+
<Fragment>
|
|
54
|
+
<div className={Styles.sideNavTop} data-cy="navigation-items-top">
|
|
55
|
+
{itemsTop.map(item => (
|
|
56
|
+
<SideNavigationItem key={item.id} expanded={expanded} {...item} />
|
|
57
|
+
))}
|
|
58
|
+
</div>
|
|
59
|
+
<div className={Styles.divider} />
|
|
60
|
+
</Fragment>
|
|
61
|
+
)}
|
|
49
62
|
<div className={Styles.sideNavContent} data-cy="navigation-items">
|
|
50
63
|
{items?.map(item => (
|
|
51
64
|
<SideNavigationItem key={item.id} expanded={expanded} {...item} />
|
|
52
65
|
))}
|
|
53
66
|
</div>
|
|
54
67
|
<div className={Styles.sideNavBottom}>
|
|
55
|
-
<
|
|
56
|
-
<SideNavigationOptions
|
|
68
|
+
<SideNavigationOptionsToggle
|
|
57
69
|
expanded={expanded}
|
|
58
70
|
onExpandedChange={onExpandedChange}
|
|
59
71
|
/>
|
|
@@ -115,30 +127,37 @@ export const SideNavigationItem: FC<SideNavigationItemProps> = ({
|
|
|
115
127
|
);
|
|
116
128
|
};
|
|
117
129
|
|
|
118
|
-
/** Side Navigation options
|
|
119
|
-
export const
|
|
130
|
+
/** Side Navigation options toggle */
|
|
131
|
+
export const SideNavigationOptionsToggle: FC<{
|
|
120
132
|
expanded?: boolean;
|
|
121
133
|
onExpandedChange(expanded: boolean): void;
|
|
122
|
-
}> = ({ expanded, onExpandedChange }) =>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const trigger = withTooltip(
|
|
134
|
+
}> = ({ expanded, onExpandedChange }) =>
|
|
135
|
+
withTooltip(
|
|
126
136
|
<div
|
|
127
137
|
data-cy="navigation-left-options"
|
|
128
138
|
data-pendo="navigation-left-options"
|
|
129
139
|
className={classNames(Styles.optionsItem)}
|
|
130
|
-
onClick={() =>
|
|
140
|
+
onClick={() => onExpandedChange(!expanded)}
|
|
131
141
|
>
|
|
132
142
|
<div className={Styles.optionsIcon}>
|
|
133
|
-
<IconSideOptions />
|
|
143
|
+
<IconSideOptions expanded={expanded} />
|
|
134
144
|
</div>
|
|
135
145
|
|
|
136
|
-
{!!expanded && <span className={Styles.optionsItemText}>Menu
|
|
146
|
+
{!!expanded && <span className={Styles.optionsItemText}>Collapse Menu</span>}
|
|
137
147
|
</div>,
|
|
138
|
-
|
|
148
|
+
expanded ? undefined : 'Expand Menu',
|
|
139
149
|
'r'
|
|
140
150
|
);
|
|
141
151
|
|
|
152
|
+
/** Side Navigation options popover */
|
|
153
|
+
export const SideNavigationOptionsPopover: FC<
|
|
154
|
+
PropsWithChildren<{
|
|
155
|
+
expanded?: boolean;
|
|
156
|
+
onExpandedChange(expanded: boolean): void;
|
|
157
|
+
}>
|
|
158
|
+
> = ({ children, expanded, onExpandedChange }) => {
|
|
159
|
+
const [open, setOpen] = useState(false);
|
|
160
|
+
|
|
142
161
|
const onExpand = () => {
|
|
143
162
|
setOpen(false);
|
|
144
163
|
onExpandedChange(true);
|
|
@@ -151,7 +170,7 @@ export const SideNavigationOptions: FC<{
|
|
|
151
170
|
return (
|
|
152
171
|
<Popover
|
|
153
172
|
className="bg-neutral-30"
|
|
154
|
-
trigger={
|
|
173
|
+
trigger={children}
|
|
155
174
|
direction="tr"
|
|
156
175
|
onClickOutside={() => setOpen(false)}
|
|
157
176
|
open={open}
|