@servicetitan/navigation 3.3.0 → 4.1.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.
Files changed (150) hide show
  1. package/dist/components/header-navigation/header-navigation-content.d.ts.map +1 -1
  2. package/dist/components/header-navigation/header-navigation-content.js +3 -3
  3. package/dist/components/header-navigation/header-navigation-content.js.map +1 -1
  4. package/dist/components/header-navigation/header-navigation-extra.stories.d.ts +3 -3
  5. package/dist/components/header-navigation/header-navigation-extra.stories.d.ts.map +1 -1
  6. package/dist/components/header-navigation/header-navigation-extra.stories.js +8 -22
  7. package/dist/components/header-navigation/header-navigation-extra.stories.js.map +1 -1
  8. package/dist/components/header-navigation/header-navigation-links.d.ts +3 -30
  9. package/dist/components/header-navigation/header-navigation-links.d.ts.map +1 -1
  10. package/dist/components/header-navigation/header-navigation-links.js +8 -5
  11. package/dist/components/header-navigation/header-navigation-links.js.map +1 -1
  12. package/dist/components/header-navigation/header-navigation-stacked.stories.d.ts +1 -0
  13. package/dist/components/header-navigation/header-navigation-stacked.stories.d.ts.map +1 -1
  14. package/dist/components/header-navigation/header-navigation-stacked.stories.js +8 -26
  15. package/dist/components/header-navigation/header-navigation-stacked.stories.js.map +1 -1
  16. package/dist/components/header-navigation/header-navigation.d.ts +1 -28
  17. package/dist/components/header-navigation/header-navigation.d.ts.map +1 -1
  18. package/dist/components/header-navigation/header-navigation.js +5 -8
  19. package/dist/components/header-navigation/header-navigation.js.map +1 -1
  20. package/dist/components/header-navigation/header-navigation.module.less +13 -70
  21. package/dist/components/header-navigation/header-navigation.stories.d.ts +1 -0
  22. package/dist/components/header-navigation/header-navigation.stories.d.ts.map +1 -1
  23. package/dist/components/header-navigation/header-navigation.stories.js +9 -27
  24. package/dist/components/header-navigation/header-navigation.stories.js.map +1 -1
  25. package/dist/components/header-navigation/index.d.ts +0 -1
  26. package/dist/components/header-navigation/index.d.ts.map +1 -1
  27. package/dist/components/header-navigation/index.js +0 -1
  28. package/dist/components/header-navigation/index.js.map +1 -1
  29. package/dist/components/layout.stories.d.ts +1 -0
  30. package/dist/components/layout.stories.d.ts.map +1 -1
  31. package/dist/components/layout.stories.js +4 -2
  32. package/dist/components/layout.stories.js.map +1 -1
  33. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts +16 -0
  34. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts.map +1 -0
  35. package/dist/components/left-navigation/header-navigation-tiny-links.js +43 -0
  36. package/dist/components/left-navigation/header-navigation-tiny-links.js.map +1 -0
  37. package/dist/components/left-navigation/header-navigation-tiny.d.ts +23 -0
  38. package/dist/components/left-navigation/header-navigation-tiny.d.ts.map +1 -0
  39. package/dist/components/left-navigation/header-navigation-tiny.js +7 -0
  40. package/dist/components/left-navigation/header-navigation-tiny.js.map +1 -0
  41. package/dist/components/left-navigation/header-navigation-tiny.module.less +109 -0
  42. package/dist/components/{header-navigation → left-navigation}/header-navigation-tiny.stories.d.ts +2 -2
  43. package/dist/components/left-navigation/header-navigation-tiny.stories.d.ts.map +1 -0
  44. package/dist/components/left-navigation/header-navigation-tiny.stories.js +30 -0
  45. package/dist/components/left-navigation/header-navigation-tiny.stories.js.map +1 -0
  46. package/dist/components/left-navigation/index.d.ts +3 -0
  47. package/dist/components/left-navigation/index.d.ts.map +1 -0
  48. package/dist/components/left-navigation/index.js +3 -0
  49. package/dist/components/left-navigation/index.js.map +1 -0
  50. package/dist/components/{side-navigation → left-navigation}/side-navigation.d.ts +1 -12
  51. package/dist/components/left-navigation/side-navigation.d.ts.map +1 -0
  52. package/dist/components/left-navigation/side-navigation.js +23 -0
  53. package/dist/components/left-navigation/side-navigation.js.map +1 -0
  54. package/dist/components/{side-navigation → left-navigation}/side-navigation.module.less +28 -22
  55. package/dist/components/left-navigation/side-navigation.stories.d.ts +10 -0
  56. package/dist/components/left-navigation/side-navigation.stories.d.ts.map +1 -0
  57. package/dist/components/left-navigation/side-navigation.stories.js +31 -0
  58. package/dist/components/left-navigation/side-navigation.stories.js.map +1 -0
  59. package/dist/components/links.d.ts +5 -0
  60. package/dist/components/links.d.ts.map +1 -0
  61. package/dist/components/links.js +14 -0
  62. package/dist/components/links.js.map +1 -0
  63. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.d.ts +2 -8
  64. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.d.ts.map +1 -1
  65. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.js +5 -43
  66. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.js.map +1 -1
  67. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.d.ts +9 -0
  68. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.d.ts.map +1 -0
  69. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.js +13 -0
  70. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.js.map +1 -0
  71. package/dist/components/profile-dropdown/profile-dropdown.d.ts +2 -1
  72. package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
  73. package/dist/components/profile-dropdown/profile-dropdown.js +16 -7
  74. package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
  75. package/dist/components/profile-dropdown/profile-dropdown.module.less +7 -1
  76. package/dist/components/profile-dropdown/profile-dropdown.stories.d.ts +9 -8
  77. package/dist/components/profile-dropdown/profile-dropdown.stories.d.ts.map +1 -1
  78. package/dist/components/profile-dropdown/profile-dropdown.stories.js +39 -39
  79. package/dist/components/profile-dropdown/profile-dropdown.stories.js.map +1 -1
  80. package/dist/index.d.ts +2 -1
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +2 -1
  83. package/dist/index.js.map +1 -1
  84. package/dist/test/data-stories.module.less +8 -0
  85. package/dist/test/data.stories.d.ts +26 -0
  86. package/dist/test/data.stories.d.ts.map +1 -0
  87. package/dist/test/data.stories.js +151 -0
  88. package/dist/test/data.stories.js.map +1 -0
  89. package/dist/utils/navigation-context.d.ts +2 -2
  90. package/dist/utils/navigation-context.d.ts.map +1 -1
  91. package/dist/utils/navigation-context.js +18 -5
  92. package/dist/utils/navigation-context.js.map +1 -1
  93. package/dist/utils/navigation.d.ts +47 -0
  94. package/dist/utils/navigation.d.ts.map +1 -1
  95. package/package.json +11 -11
  96. package/src/components/header-navigation/header-navigation-content.tsx +3 -3
  97. package/src/components/header-navigation/header-navigation-extra.stories.tsx +29 -38
  98. package/src/components/header-navigation/header-navigation-links.tsx +19 -41
  99. package/src/components/header-navigation/header-navigation-stacked.stories.tsx +18 -70
  100. package/src/components/header-navigation/header-navigation.module.less +13 -70
  101. package/src/components/header-navigation/header-navigation.module.less.d.ts +0 -1
  102. package/src/components/header-navigation/header-navigation.stories.tsx +20 -71
  103. package/src/components/header-navigation/header-navigation.tsx +6 -82
  104. package/src/components/header-navigation/index.ts +0 -1
  105. package/src/components/layout.stories.tsx +4 -2
  106. package/src/components/left-navigation/header-navigation-tiny-links.tsx +110 -0
  107. package/src/components/left-navigation/header-navigation-tiny.module.less +109 -0
  108. package/src/components/left-navigation/header-navigation-tiny.module.less.d.ts +14 -0
  109. package/src/components/{header-navigation → left-navigation}/header-navigation-tiny.stories.tsx +39 -46
  110. package/src/components/left-navigation/header-navigation-tiny.tsx +65 -0
  111. package/src/components/left-navigation/index.ts +2 -0
  112. package/src/components/{side-navigation → left-navigation}/side-navigation.module.less +28 -22
  113. package/src/components/{side-navigation → left-navigation}/side-navigation.module.less.d.ts +3 -3
  114. package/src/components/left-navigation/side-navigation.stories.tsx +46 -0
  115. package/src/components/left-navigation/side-navigation.tsx +171 -0
  116. package/src/components/links.tsx +31 -0
  117. package/src/components/profile-dropdown/profile-dropdown-stacked.stories.tsx +5 -170
  118. package/src/components/profile-dropdown/profile-dropdown-tiny.stories.tsx +15 -0
  119. package/src/components/profile-dropdown/profile-dropdown.module.less +7 -1
  120. package/src/components/profile-dropdown/profile-dropdown.module.less.d.ts +1 -0
  121. package/src/components/profile-dropdown/profile-dropdown.stories.tsx +106 -129
  122. package/src/components/profile-dropdown/profile-dropdown.tsx +35 -8
  123. package/src/index.ts +2 -1
  124. package/src/test/data-stories.module.less +8 -0
  125. package/src/test/data-stories.module.less.d.ts +3 -0
  126. package/src/test/data.stories.tsx +223 -0
  127. package/src/utils/navigation-context.tsx +10 -10
  128. package/src/utils/navigation.ts +54 -0
  129. package/dist/components/header-navigation/header-navigation-tiny.stories.d.ts.map +0 -1
  130. package/dist/components/header-navigation/header-navigation-tiny.stories.js +0 -25
  131. package/dist/components/header-navigation/header-navigation-tiny.stories.js.map +0 -1
  132. package/dist/components/side-navigation/icons.d.ts +0 -7
  133. package/dist/components/side-navigation/icons.d.ts.map +0 -1
  134. package/dist/components/side-navigation/icons.js +0 -5
  135. package/dist/components/side-navigation/icons.js.map +0 -1
  136. package/dist/components/side-navigation/index.d.ts +0 -2
  137. package/dist/components/side-navigation/index.d.ts.map +0 -1
  138. package/dist/components/side-navigation/index.js +0 -2
  139. package/dist/components/side-navigation/index.js.map +0 -1
  140. package/dist/components/side-navigation/side-navigation.d.ts.map +0 -1
  141. package/dist/components/side-navigation/side-navigation.js +0 -37
  142. package/dist/components/side-navigation/side-navigation.js.map +0 -1
  143. package/dist/components/side-navigation/side-navigation.stories.d.ts +0 -10
  144. package/dist/components/side-navigation/side-navigation.stories.d.ts.map +0 -1
  145. package/dist/components/side-navigation/side-navigation.stories.js +0 -52
  146. package/dist/components/side-navigation/side-navigation.stories.js.map +0 -1
  147. package/src/components/side-navigation/icons.tsx +0 -74
  148. package/src/components/side-navigation/index.ts +0 -1
  149. package/src/components/side-navigation/side-navigation.stories.tsx +0 -95
  150. package/src/components/side-navigation/side-navigation.tsx +0 -224
@@ -1,157 +1,134 @@
1
1
  import { Button } from '@servicetitan/design-system';
2
- import { FC } from 'react';
3
- import { NavLinkComponentProps } from '../../utils/navigation';
2
+ import { withAnvil, withMemoryRouter } from '../../test/data.stories';
4
3
  import { HeaderNavigation } from '../header-navigation';
5
4
  import { ProfileDropdown } from './profile-dropdown';
6
5
 
6
+ const withHeaderNavigation = (Story: any) => (
7
+ <HeaderNavigation>
8
+ <Story />
9
+ </HeaderNavigation>
10
+ );
11
+
7
12
  export default {
8
13
  title: 'Navigation/ProfileDropdown',
9
14
  component: ProfileDropdown,
10
15
  parameters: {},
16
+ decorators: [withMemoryRouter, withAnvil, withHeaderNavigation],
11
17
  };
12
18
 
13
- const NavLinkMock: FC<NavLinkComponentProps> = props => (
14
- <a
15
- href={props.to}
16
- target={props.target}
17
- onClick={e => {
18
- e.preventDefault();
19
- }}
20
- className={props.className}
21
- >
22
- {props.children}
23
- </a>
24
- );
25
-
26
- export const profileDropdownDefault = () => (
27
- <HeaderNavigation navigationComponent={NavLinkMock}>
28
- <ProfileDropdown>
29
- <ProfileDropdown.Link id="first" to="https://google.com">
30
- first link
31
- </ProfileDropdown.Link>
32
- <ProfileDropdown.Link id="second" onClick={() => alert('second click')}>
33
- second link
34
- </ProfileDropdown.Link>
35
- <ProfileDropdown.Divider />
36
- <ProfileDropdown.Section id="content">some content</ProfileDropdown.Section>
37
- <ProfileDropdown.Divider />
38
- <ProfileDropdown.Divider />
39
- <ProfileDropdown.Divider />
40
- <ProfileDropdown.Link id="third" to="https://google.com">
41
- third link
42
- </ProfileDropdown.Link>
43
- <ProfileDropdown.Divider />
44
- </ProfileDropdown>
45
- </HeaderNavigation>
19
+ export const ProfileDropdownDefault = () => (
20
+ <ProfileDropdown>
21
+ <ProfileDropdown.Link id="first" to="https://google.com">
22
+ first link
23
+ </ProfileDropdown.Link>
24
+ <ProfileDropdown.Link id="second" onClick={() => alert('second click')}>
25
+ second link
26
+ </ProfileDropdown.Link>
27
+ <ProfileDropdown.Divider />
28
+ <ProfileDropdown.Section id="content">some content</ProfileDropdown.Section>
29
+ <ProfileDropdown.Divider />
30
+ <ProfileDropdown.Divider />
31
+ <ProfileDropdown.Divider />
32
+ <ProfileDropdown.Link id="third" to="third">
33
+ third link
34
+ </ProfileDropdown.Link>
35
+ <ProfileDropdown.Divider />
36
+ </ProfileDropdown>
46
37
  );
47
38
 
48
- export const profileDropdownWithLogo = () => (
49
- <HeaderNavigation navigationComponent={NavLinkMock}>
50
- <ProfileDropdown
51
- trigger={{
52
- imageSrc: 'https://upload.wikimedia.org/wikipedia/en/1/11/Milhouse_Van_Houten.png',
53
- }}
54
- >
55
- <ProfileDropdown.Link id="first" to="https://google.com">
56
- first link
57
- </ProfileDropdown.Link>
58
- <ProfileDropdown.Link id="second" onClick={() => alert('second click')}>
59
- second link
60
- </ProfileDropdown.Link>
61
- </ProfileDropdown>
62
- </HeaderNavigation>
39
+ export const ProfileDropdownWithLogo = () => (
40
+ <ProfileDropdown
41
+ trigger={{
42
+ imageSrc: 'https://upload.wikimedia.org/wikipedia/en/1/11/Milhouse_Van_Houten.png',
43
+ }}
44
+ >
45
+ <ProfileDropdown.Link id="first" to="https://google.com">
46
+ first link
47
+ </ProfileDropdown.Link>
48
+ <ProfileDropdown.Link id="second" onClick={() => alert('second click')}>
49
+ second link
50
+ </ProfileDropdown.Link>
51
+ </ProfileDropdown>
63
52
  );
64
53
 
65
- export const profileDropdownWithErrorLogo = () => (
66
- <HeaderNavigation>
67
- <ProfileDropdown
68
- trigger={{
69
- imageSrc: 'https://some.incorrect.url/logo.png',
70
- }}
71
- />
72
- </HeaderNavigation>
54
+ export const ProfileDropdownWithErrorLogo = () => (
55
+ <ProfileDropdown
56
+ trigger={{
57
+ imageSrc: 'https://some.incorrect.url/logo.png',
58
+ }}
59
+ />
73
60
  );
74
61
 
75
- export const profileDropdownWithInfo = () => (
76
- <HeaderNavigation>
77
- <ProfileDropdown
78
- trigger={{
79
- info: { text: 'first', title: 'tenant user' },
80
- avatarBadge: true,
81
- }}
82
- />
83
- </HeaderNavigation>
62
+ export const ProfileDropdownWithInfo = () => (
63
+ <ProfileDropdown
64
+ trigger={{
65
+ info: { text: 'first', title: 'tenant user' },
66
+ avatarBadge: true,
67
+ }}
68
+ />
84
69
  );
85
70
 
86
- export const profileDropdownWithCounter = () => (
87
- <HeaderNavigation>
88
- <ProfileDropdown
89
- trigger={{
90
- info: { text: 'first', title: 'tenant user' },
91
- avatarBadge: true,
92
- badge: { content: 3, className: 'bg-red-500' },
93
- }}
94
- />
95
- </HeaderNavigation>
71
+ export const ProfileDropdownWithCounter = () => (
72
+ <ProfileDropdown
73
+ trigger={{
74
+ info: { text: 'first', title: 'tenant user' },
75
+ avatarBadge: true,
76
+ badge: { content: 3, className: 'bg-red-500' },
77
+ }}
78
+ />
96
79
  );
97
80
 
98
- export const profileDropdownWithBothBadges = () => (
99
- <HeaderNavigation>
100
- <ProfileDropdown
101
- trigger={{
102
- avatarBadge: 'yellow-500',
103
- badge: { className: 'bg-red-400' },
104
- }}
105
- />
106
- </HeaderNavigation>
81
+ export const ProfileDropdownWithBothBadges = () => (
82
+ <ProfileDropdown
83
+ trigger={{
84
+ avatarBadge: 'yellow-500',
85
+ badge: { className: 'bg-red-400' },
86
+ }}
87
+ />
107
88
  );
108
89
 
109
90
  // eslint-disable-next-line no-console
110
91
  const log = (text: string) => console.log(text);
111
92
 
112
- export const profileDropdownWithHintPopup = () => (
113
- <HeaderNavigation navigationComponent={NavLinkMock}>
114
- <ProfileDropdown
115
- trigger={{
116
- avatarBadge: 'yellow-500',
117
- badge: { className: 'bg-red-400' },
118
- }}
119
- hintPopup={{
120
- className: 'bg-blue-500-i c-white',
121
- content: ({ openProfile }) => (
122
- <div>
123
- hello{' '}
124
- <Button onClick={openProfile} size="xsmall">
125
- show me
126
- </Button>
127
- </div>
128
- ),
129
- width: 's',
130
- onClose: () => log('close profile dropdown hint'),
131
- }}
132
- onOpen={() => log('open profile dropdown')}
133
- onClose={() => log('close profile dropdown')}
134
- >
135
- <ProfileDropdown.Link id="first" to="https://google.com">
136
- first item
137
- </ProfileDropdown.Link>
138
- <ProfileDropdown.Divider />
139
- <ProfileDropdown.Section id="second">second item</ProfileDropdown.Section>
140
- </ProfileDropdown>
141
- </HeaderNavigation>
93
+ export const ProfileDropdownWithHintPopup = () => (
94
+ <ProfileDropdown
95
+ trigger={{
96
+ avatarBadge: 'yellow-500',
97
+ badge: { className: 'bg-red-400' },
98
+ }}
99
+ hintPopup={{
100
+ className: 'bg-blue-500-i c-white',
101
+ content: ({ openProfile }) => (
102
+ <div>
103
+ hello{' '}
104
+ <Button onClick={openProfile} size="xsmall">
105
+ show me
106
+ </Button>
107
+ </div>
108
+ ),
109
+ width: 's',
110
+ onClose: () => log('close profile dropdown hint'),
111
+ }}
112
+ onOpen={() => log('open profile dropdown')}
113
+ onClose={() => log('close profile dropdown')}
114
+ >
115
+ <ProfileDropdown.Link id="first" to="https://google.com">
116
+ first item
117
+ </ProfileDropdown.Link>
118
+ <ProfileDropdown.Divider />
119
+ <ProfileDropdown.Section id="second">second item</ProfileDropdown.Section>
120
+ </ProfileDropdown>
142
121
  );
143
122
 
144
- export const profileDropdownWithHintAndInfoPopup = () => (
145
- <HeaderNavigation navigationComponent={NavLinkMock}>
146
- <ProfileDropdown
147
- trigger={{
148
- avatarBadge: 'yellow-500',
149
- badge: { className: 'bg-red-400' },
150
- info: { title: 'some text', text: 'qq' },
151
- }}
152
- hintPopup={{
153
- content: () => <div>hello</div>,
154
- }}
155
- />
156
- </HeaderNavigation>
123
+ export const ProfileDropdownWithHintAndInfoPopup = () => (
124
+ <ProfileDropdown
125
+ trigger={{
126
+ avatarBadge: 'yellow-500',
127
+ badge: { className: 'bg-red-400' },
128
+ info: { title: 'some text', text: 'qq' },
129
+ }}
130
+ hintPopup={{
131
+ content: () => <div>hello</div>,
132
+ }}
133
+ />
157
134
  );
@@ -1,4 +1,9 @@
1
- import { BodyText, Icon, Popover, PopoverPropsStrict } from '@servicetitan/design-system';
1
+ import { Icon } from '@servicetitan/anvil2';
2
+ import SvgExpandLess from '@servicetitan/anvil2/assets/icons/material/round/expand_less.svg';
3
+ import SvgExpandMore from '@servicetitan/anvil2/assets/icons/material/round/expand_more.svg';
4
+ import SvgAccountActive from '@servicetitan/anvil2/assets/icons/st/gnav_account_active.svg';
5
+ import SvgAccountInactive from '@servicetitan/anvil2/assets/icons/st/gnav_account_inactive.svg';
6
+ import { BodyText, Popover, PopoverPropsStrict } from '@servicetitan/design-system';
2
7
  import classNames from 'classnames';
3
8
  import {
4
9
  FC,
@@ -7,12 +12,16 @@ import {
7
12
  MouseEventHandler,
8
13
  ReactNode,
9
14
  useCallback,
15
+ useContext,
10
16
  useEffect,
11
17
  useMemo,
12
18
  useState,
13
19
  } from 'react';
14
20
 
15
- import { useNavLink } from '../../utils/navigation-context';
21
+ import {
22
+ NavigationComponentContext,
23
+ NavigationLegacyContext,
24
+ } from '../../utils/navigation-context';
16
25
  import { CounterTag, CounterTagPropsType } from '../counter-tag';
17
26
  import * as Styles from './profile-dropdown.module.less';
18
27
  import { ProfileLogo } from './profile-icon';
@@ -24,6 +33,7 @@ export interface ProfileDropdownTriggerProps {
24
33
  avatarBadge?: boolean | string;
25
34
  badge?: { content?: number | string; className: string };
26
35
  hintArrow?: boolean;
36
+ open: boolean;
27
37
  onClick?(e: MouseEvent): void;
28
38
  }
29
39
 
@@ -35,9 +45,11 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
35
45
  imageSrc,
36
46
  info,
37
47
  onClick,
48
+ open,
38
49
  }) => {
39
50
  const [avatarSource, setAvatarSource] = useState(imageSrc ?? '');
40
51
  const [avatarSourceError, setAvatarSourceError] = useState(false);
52
+ const isLegacy = useContext(NavigationLegacyContext);
41
53
 
42
54
  useEffect(() => {
43
55
  const src = imageSrc ?? '';
@@ -60,7 +72,10 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
60
72
  'd-f align-items-center cursor-pointer position-relative p-x-1 p-y-half',
61
73
  'profile-dropdown-trigger',
62
74
  Styles.triggerContainer,
63
- { [Styles.triggerContainerHintArrow]: hintArrow },
75
+ {
76
+ [Styles.triggerContainerHintArrow]: hintArrow,
77
+ [Styles.triggerContainerLegacy]: isLegacy,
78
+ },
64
79
  className
65
80
  )}
66
81
  onClick={onClick}
@@ -74,13 +89,20 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
74
89
  onError={onAvatarError}
75
90
  alt="user dropdown menu"
76
91
  />
77
- ) : (
92
+ ) : isLegacy ? (
78
93
  <ProfileLogo />
94
+ ) : (
95
+ <Icon size="large" svg={open ? SvgAccountActive : SvgAccountInactive} />
79
96
  )}
80
97
 
81
98
  {!!info && (
82
99
  <div className={Styles.info}>
83
- <BodyText bold title={info.title} className="t-truncate c-white" size="xsmall">
100
+ <BodyText
101
+ bold
102
+ title={info.title}
103
+ className="t-truncate c-inherit"
104
+ size="xsmall"
105
+ >
84
106
  {info.title}
85
107
  </BodyText>
86
108
  <BodyText
@@ -93,7 +115,11 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
93
115
  </div>
94
116
  )}
95
117
 
96
- <Icon className="m-l-half d-f align-items-center" name="expand_more" size={12} />
118
+ <Icon
119
+ svg={open ? SvgExpandLess : SvgExpandMore}
120
+ className={classNames('d-f align-items-center c-inherit', { 'm-l-half': isLegacy })}
121
+ size="small"
122
+ />
97
123
 
98
124
  {!!avatarBadge && (
99
125
  <div
@@ -185,7 +211,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
185
211
  onClick,
186
212
  ...rest
187
213
  }: ProfileDropdownLinkProps) => {
188
- const NavigationComponent = useNavLink();
214
+ const NavigationComponent = useContext(NavigationComponentContext);
189
215
 
190
216
  const clickHandler = (e: MouseEvent<any>) => {
191
217
  e.preventDefault();
@@ -241,7 +267,7 @@ export interface ProfileDropdownPropsStrict {
241
267
  children?: ReactNode;
242
268
  className?: string;
243
269
  direction?: PopoverPropsStrict['direction'];
244
- trigger?: Omit<ProfileDropdownTriggerProps, 'onClick' | 'hintArrow'>;
270
+ trigger?: Omit<ProfileDropdownTriggerProps, 'onClick' | 'open' | 'hintArrow'>;
245
271
  hintPopup?: {
246
272
  className?: string;
247
273
  content: FC<{ openProfile(): void }>;
@@ -305,6 +331,7 @@ export const ProfileDropdown: ProfileDropdownType = (({
305
331
  {...trigger}
306
332
  onClick={children ? onTriggerClick : undefined}
307
333
  hintArrow={hintShown}
334
+ open={open}
308
335
  />
309
336
  );
310
337
 
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ export * from './components/logo/logo-company-title';
4
4
  export * from './components/logo/logo-titan';
5
5
  export * from './components/logo/logo-titan-text';
6
6
  export * from './components/counter-tag';
7
- export * from './components/side-navigation';
7
+ export * from './components/left-navigation';
8
+ export * from './components/links';
8
9
  export * from './utils/navigation';
9
10
  export * from './utils/with-tooltip';
@@ -0,0 +1,8 @@
1
+ // emulate temp anvil2 hotfix from monolith
2
+ .fix-icons {
3
+ [data-anv][data-anv] {
4
+ all: revert-layer;
5
+ line-height: revert-layer;
6
+ -webkit-font-smoothing: auto;
7
+ }
8
+ }
@@ -0,0 +1,3 @@
1
+ export const __esModule: true;
2
+ export const fixIcons: string;
3
+
@@ -0,0 +1,223 @@
1
+ import { AnvilProvider } from '@servicetitan/anvil2';
2
+ import SvgPhone from '@servicetitan/anvil2/assets/icons/material/round/phone_disabled.svg';
3
+ import SvgPhoneActive from '@servicetitan/anvil2/assets/icons/material/round/phone_enabled.svg';
4
+ import SvgAccountingActive from '@servicetitan/anvil2/assets/icons/st/gnav_accounting_active.svg';
5
+ import SvgAccounting from '@servicetitan/anvil2/assets/icons/st/gnav_accounting_inactive.svg';
6
+ import SvgCallsActive from '@servicetitan/anvil2/assets/icons/st/gnav_calls_active.svg';
7
+ import SvgCalls from '@servicetitan/anvil2/assets/icons/st/gnav_calls_inactive.svg';
8
+ import SvgDashboardActive from '@servicetitan/anvil2/assets/icons/st/gnav_dashboard_active.svg';
9
+ import SvgDashboard from '@servicetitan/anvil2/assets/icons/st/gnav_dashboard_inactive.svg';
10
+ import SvgDispatchActive from '@servicetitan/anvil2/assets/icons/st/gnav_dispatch_active.svg';
11
+ import SvgDispatch from '@servicetitan/anvil2/assets/icons/st/gnav_dispatch_inactive.svg';
12
+ import SvgFleetProActive from '@servicetitan/anvil2/assets/icons/st/gnav_fleet_pro_active.svg';
13
+ import SvgFleetPro from '@servicetitan/anvil2/assets/icons/st/gnav_fleet_pro_inactive.svg';
14
+ import SvgFollowUpActive from '@servicetitan/anvil2/assets/icons/st/gnav_follow_up_active.svg';
15
+ import SvgFollowUp from '@servicetitan/anvil2/assets/icons/st/gnav_follow_up_inactive.svg';
16
+ import SvgInventoryActive from '@servicetitan/anvil2/assets/icons/st/gnav_inventory_active.svg';
17
+ import SvgInventory from '@servicetitan/anvil2/assets/icons/st/gnav_inventory_inactive.svg';
18
+ import SvgMarketingActive from '@servicetitan/anvil2/assets/icons/st/gnav_marketing_active.svg';
19
+ import SvgMarketing from '@servicetitan/anvil2/assets/icons/st/gnav_marketing_inactive.svg';
20
+ import SvgPosActive from '@servicetitan/anvil2/assets/icons/st/gnav_pos_active.svg';
21
+ import SvgPos from '@servicetitan/anvil2/assets/icons/st/gnav_pos_inactive.svg';
22
+ import SvgPriceBookActive from '@servicetitan/anvil2/assets/icons/st/gnav_pricebook_active.svg';
23
+ import SvgPriceBook from '@servicetitan/anvil2/assets/icons/st/gnav_pricebook_inactive.svg';
24
+ import SvgProjectsActive from '@servicetitan/anvil2/assets/icons/st/gnav_projects_active.svg';
25
+ import SvgProjects from '@servicetitan/anvil2/assets/icons/st/gnav_projects_inactive.svg';
26
+ import SvgReportsActive from '@servicetitan/anvil2/assets/icons/st/gnav_reports_active.svg';
27
+ import SvgReports from '@servicetitan/anvil2/assets/icons/st/gnav_reports_inactive.svg';
28
+ import SvgScheduleActive from '@servicetitan/anvil2/assets/icons/st/gnav_schedule_active.svg';
29
+ import SvgSchedule from '@servicetitan/anvil2/assets/icons/st/gnav_schedule_inactive.svg';
30
+ import SvgTasksActive from '@servicetitan/anvil2/assets/icons/st/gnav_tasks_active.svg';
31
+ import SvgTasks from '@servicetitan/anvil2/assets/icons/st/gnav_tasks_inactive.svg';
32
+
33
+ import { Popover } from '@servicetitan/design-system';
34
+
35
+ import classNames from 'classnames';
36
+ import { forwardRef, useState } from 'react';
37
+ // needed only for storybook and added in root dependencies
38
+ // eslint-disable-next-line import/no-extraneous-dependencies
39
+ import { MemoryRouter, useHistory, useLocation } from 'react-router-dom';
40
+ import { HeaderNavigationTrigger } from '../components/links';
41
+ import { HeaderNavigationItemData, NavLinkComponentProps } from '../utils/navigation';
42
+ import { NavigationComponentContext } from '../utils/navigation-context';
43
+ import * as Styles from './data-stories.module.less';
44
+
45
+ export const NavLinkMock = forwardRef<any, NavLinkComponentProps>(
46
+ ({ to, children, activeClassName, className, isActive, ...rest }, ref) => {
47
+ const history = useHistory();
48
+ const location = useLocation();
49
+ const linkActive = location.pathname.replace('/', '') === to;
50
+
51
+ return (
52
+ <a
53
+ {...rest}
54
+ className={classNames(className, linkActive ? activeClassName : '')}
55
+ href={to}
56
+ onClick={e => {
57
+ e.preventDefault();
58
+
59
+ if (!to.startsWith('http')) {
60
+ history.push(to);
61
+ }
62
+ }}
63
+ ref={ref}
64
+ >
65
+ {children}
66
+ </a>
67
+ );
68
+ }
69
+ );
70
+
71
+ export const withMemoryRouter = (Story: any) => (
72
+ <MemoryRouter>
73
+ <NavigationComponentContext.Provider value={NavLinkMock}>
74
+ <Story />
75
+ </NavigationComponentContext.Provider>
76
+ </MemoryRouter>
77
+ );
78
+
79
+ export const withAnvil = (Story: any) => (
80
+ <AnvilProvider className={Styles.fixIcons}>
81
+ <Story />
82
+ </AnvilProvider>
83
+ );
84
+
85
+ export const InventoryIcon = () => (
86
+ <svg width="20" xmlns="http://www.w3.org/2000/svg" viewBox="-293 385 24 24" fill="currentColor">
87
+ <polyline points="-288,400.9 -282,404.3 -282,397.6 -288,394.2 -288,400.9 " />
88
+ <path d="M-272,401.5c0,0.4-0.2,0.7-0.5,0.9l-7.9,4.4c-0.2,0.1-0.4,0.2-0.6,0.2s-0.4-0.1-0.6-0.2l-7.9-4.4c-0.3-0.2-0.5-0.5-0.5-0.9v-9c0-0.4,0.2-0.7,0.5-0.9l7.9-4.4c0.2-0.1,0.4-0.2,0.6-0.2s0.4,0.1,0.6,0.2l7.9,4.4c0.3,0.2,0.5,0.5,0.5,0.9V401.5 M-287,392.5 l6,3.4l5.9-3.3l-5.9-3.4L-287,392.5 M-274,400.9v-6.7l-6,3.4v6.7L-274,400.9z" />
89
+ </svg>
90
+ );
91
+
92
+ export const SearchIcon = () => (
93
+ <svg
94
+ width="1em"
95
+ height="1em"
96
+ viewBox="0 0 24 24"
97
+ fill="none"
98
+ xmlns="http://www.w3.org/2000/svg"
99
+ >
100
+ <g transform="translate(0,4)">
101
+ <path
102
+ d="M0 15.7992V13.9992H12V15.7992H0ZM0 9.49922V7.69922H6V9.49922H0ZM0 3.19922V1.39922H6V3.19922H0ZM22.74 15.7992L17.94 10.9992C17.42 11.3992 16.86 11.6992 16.26 11.8992C15.66 12.0992 15.04 12.1992 14.4 12.1992C12.74 12.1992 11.325 11.6142 10.155 10.4442C8.985 9.27422 8.4 7.85922 8.4 6.19922C8.4 4.53922 8.985 3.12422 10.155 1.95422C11.325 0.784219 12.74 0.199219 14.4 0.199219C16.06 0.199219 17.475 0.784219 18.645 1.95422C19.815 3.12422 20.4 4.53922 20.4 6.19922C20.4 6.83922 20.3 7.45922 20.1 8.05922C19.9 8.65922 19.6 9.21922 19.2 9.73922L24 14.5392L22.74 15.7992ZM14.393 10.3992C15.5577 10.3992 16.55 9.99157 17.37 9.17627C18.19 8.36099 18.6 7.37099 18.6 6.20627C18.6 5.04157 18.1923 4.04922 17.377 3.22922C16.5618 2.40922 15.5718 1.99922 14.407 1.99922C13.2423 1.99922 12.25 2.40687 11.43 3.22217C10.61 4.03745 10.2 5.02745 10.2 6.19217C10.2 7.35687 10.6077 8.34922 11.423 9.16922C12.2382 9.98922 13.2282 10.3992 14.393 10.3992Z"
103
+ fill="white"
104
+ />
105
+ </g>
106
+ </svg>
107
+ );
108
+
109
+ const getItem = (
110
+ id: string,
111
+ data: Partial<HeaderNavigationItemData>
112
+ ): HeaderNavigationItemData => ({
113
+ id,
114
+ to: id,
115
+ title: id[0].toUpperCase() + id.substring(1),
116
+ hint: id,
117
+ icon: undefined,
118
+ iconActive: undefined,
119
+ ...(data ?? {}),
120
+ });
121
+
122
+ export const items = {
123
+ calendar: getItem('calendar', {
124
+ iconName: 'event',
125
+ icon: SvgSchedule,
126
+ iconActive: SvgScheduleActive,
127
+ }),
128
+ calls: getItem('calls', {
129
+ iconName: 'local_phone',
130
+ icon: SvgCalls,
131
+ iconActive: SvgCallsActive,
132
+ counter: 12,
133
+ }),
134
+ dashboard: getItem('dashboard', {
135
+ iconName: 'odometer',
136
+ icon: SvgDashboard,
137
+ iconActive: SvgDashboardActive,
138
+ }),
139
+ dispatch: getItem('dispatch', {
140
+ iconName: 'location_disabled',
141
+ icon: SvgDispatch,
142
+ iconActive: SvgDispatchActive,
143
+ counter: 1,
144
+ }),
145
+ fleet: getItem('fleet', {
146
+ iconName: 'fleet-pro',
147
+ icon: SvgFleetPro,
148
+ iconActive: SvgFleetProActive,
149
+ title: 'Fleet Pro',
150
+ }),
151
+ followUps: getItem('followUps', {
152
+ iconName: 'flag',
153
+ icon: SvgFollowUp,
154
+ iconActive: SvgFollowUpActive,
155
+ title: 'Follow Ups',
156
+ }),
157
+ inventory: getItem('inventory', {
158
+ iconName: 'toys',
159
+ icon: SvgInventory,
160
+ iconActive: SvgInventoryActive,
161
+ }),
162
+ purchasing: getItem('purchasing', { iconComponent: InventoryIcon }),
163
+ accounting: getItem('accounting', {
164
+ iconName: 'assignment',
165
+ icon: SvgAccounting,
166
+ iconActive: SvgAccountingActive,
167
+ }),
168
+ marketing: getItem('marketing', {
169
+ iconName: 'bullhorn',
170
+ icon: SvgMarketing,
171
+ iconActive: SvgMarketingActive,
172
+ }),
173
+ priceBook: getItem('priceBook', {
174
+ iconName: 'book',
175
+ icon: SvgPriceBook,
176
+ iconActive: SvgPriceBookActive,
177
+ }),
178
+ pointOfSale: getItem('pointOfSale', {
179
+ iconName: 'cash-register',
180
+ icon: SvgPos,
181
+ iconActive: SvgPosActive,
182
+ }),
183
+ projects: getItem('projects', {
184
+ iconName: 'folder_special',
185
+ icon: SvgProjects,
186
+ iconActive: SvgProjectsActive,
187
+ }),
188
+ reports: getItem('reports', {
189
+ iconName: 'folder_special',
190
+ icon: SvgReports,
191
+ iconActive: SvgReportsActive,
192
+ }),
193
+ tasks: getItem('tasks', {
194
+ iconName: 'format_list_bulleted',
195
+ icon: SvgTasks,
196
+ iconActive: SvgTasksActive,
197
+ }),
198
+ };
199
+
200
+ export const CallsNavigationTrigger = () => {
201
+ const [open, setOpen] = useState(false);
202
+
203
+ return (
204
+ <Popover
205
+ open={open}
206
+ onClickOutside={() => setOpen(false)}
207
+ direction="bl"
208
+ trigger={
209
+ <HeaderNavigationTrigger
210
+ id="dialpad"
211
+ iconName="phone"
212
+ counter={2}
213
+ icon={SvgPhone}
214
+ iconActive={SvgPhoneActive}
215
+ onClick={() => setOpen(!open)}
216
+ isActive={open}
217
+ />
218
+ }
219
+ >
220
+ calls content
221
+ </Popover>
222
+ );
223
+ };
@@ -1,13 +1,13 @@
1
- import { FC, createContext, useContext } from 'react';
2
- import { NavLink } from 'react-router-dom';
1
+ import { FC, createContext } from 'react';
3
2
  import { NavLinkComponentProps } from './navigation';
4
3
 
5
- export const DefaultNavLinkComponent: FC<NavLinkComponentProps> = props => (
6
- <NavLink
7
- {...props}
8
- isActive={props.isActive && ((_, { pathname }) => props.isActive!(pathname))}
9
- />
10
- );
4
+ export const DefaultNavLinkComponent: FC<NavLinkComponentProps> = ({
5
+ children,
6
+ activeClassName,
7
+ isActive,
8
+ ...props
9
+ }) => <a {...props}>{children}</a>;
11
10
 
12
- export const NavLinkContext = createContext(DefaultNavLinkComponent);
13
- export const useNavLink = () => useContext(NavLinkContext);
11
+ export const NavigationComponentContext =
12
+ createContext<FC<NavLinkComponentProps>>(DefaultNavLinkComponent);
13
+ export const NavigationLegacyContext = createContext(false);