@servicetitan/navigation 12.0.3 → 13.0.0-canary.256.44cf055.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 (252) hide show
  1. package/dist/components/counter-tag.d.ts +1 -1
  2. package/dist/components/counter-tag.d.ts.map +1 -1
  3. package/dist/components/counter-tag.js.map +1 -1
  4. package/dist/components/profile-dropdown/interface.d.ts +55 -0
  5. package/dist/components/profile-dropdown/interface.d.ts.map +1 -0
  6. package/dist/components/profile-dropdown/interface.js.map +1 -0
  7. package/dist/components/profile-dropdown/profile-dropdown-legacy.stories.d.ts +13 -0
  8. package/dist/components/profile-dropdown/profile-dropdown-legacy.stories.d.ts.map +1 -0
  9. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.d.ts +5 -1
  10. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.d.ts.map +1 -1
  11. package/dist/components/profile-dropdown/profile-dropdown.d.ts +9 -79
  12. package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
  13. package/dist/components/profile-dropdown/profile-dropdown.js +22 -22
  14. package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
  15. package/dist/components/profile-dropdown/profile-dropdown.stories.d.ts +5 -1
  16. package/dist/components/profile-dropdown/profile-dropdown.stories.d.ts.map +1 -1
  17. package/dist/components/titan-layout/interface-internal.d.ts +12 -0
  18. package/dist/components/titan-layout/interface-internal.d.ts.map +1 -1
  19. package/dist/components/titan-layout/interface-internal.js.map +1 -1
  20. package/dist/components/titan-layout/interface.d.ts +67 -14
  21. package/dist/components/titan-layout/interface.d.ts.map +1 -1
  22. package/dist/components/titan-layout/interface.js.map +1 -1
  23. package/dist/components/titan-layout/layout-header-dark.d.ts.map +1 -1
  24. package/dist/components/titan-layout/layout-header-dark.js +24 -12
  25. package/dist/components/titan-layout/layout-header-dark.js.map +1 -1
  26. package/dist/components/titan-layout/layout-header-links-internal.d.ts +22 -3
  27. package/dist/components/titan-layout/layout-header-links-internal.d.ts.map +1 -1
  28. package/dist/components/titan-layout/layout-header-links-internal.js +15 -18
  29. package/dist/components/titan-layout/layout-header-links-internal.js.map +1 -1
  30. package/dist/components/titan-layout/layout-header-links.d.ts +3 -4
  31. package/dist/components/titan-layout/layout-header-links.d.ts.map +1 -1
  32. package/dist/components/titan-layout/layout-header-links.js +25 -5
  33. package/dist/components/titan-layout/layout-header-links.js.map +1 -1
  34. package/dist/components/titan-layout/layout-header.d.ts +4 -2
  35. package/dist/components/titan-layout/layout-header.d.ts.map +1 -1
  36. package/dist/components/titan-layout/layout-header.js +25 -16
  37. package/dist/components/titan-layout/layout-header.js.map +1 -1
  38. package/dist/components/titan-layout/layout-header.module.less +37 -1
  39. package/dist/components/titan-layout/layout-header.module.less.d.ts +3 -0
  40. package/dist/components/titan-layout/layout-profile.d.ts +8 -5
  41. package/dist/components/titan-layout/layout-profile.d.ts.map +1 -1
  42. package/dist/components/titan-layout/layout-profile.js +30 -28
  43. package/dist/components/titan-layout/layout-profile.js.map +1 -1
  44. package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts +48 -31
  45. package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts.map +1 -1
  46. package/dist/components/titan-layout/layout-sidebar-links-internal.js +87 -83
  47. package/dist/components/titan-layout/layout-sidebar-links-internal.js.map +1 -1
  48. package/dist/components/titan-layout/layout-sidebar-links.d.ts +3 -3
  49. package/dist/components/titan-layout/layout-sidebar-links.d.ts.map +1 -1
  50. package/dist/components/titan-layout/layout-sidebar-links.js +32 -19
  51. package/dist/components/titan-layout/layout-sidebar-links.js.map +1 -1
  52. package/dist/components/titan-layout/layout-sidebar.d.ts +1 -1
  53. package/dist/components/titan-layout/layout-sidebar.d.ts.map +1 -1
  54. package/dist/components/titan-layout/layout-sidebar.js +81 -102
  55. package/dist/components/titan-layout/layout-sidebar.js.map +1 -1
  56. package/dist/components/titan-layout/layout-sidebar.module.less +74 -22
  57. package/dist/components/titan-layout/titan-layout-default.stories.d.ts +16 -0
  58. package/dist/components/titan-layout/titan-layout-default.stories.d.ts.map +1 -0
  59. package/dist/components/titan-layout/titan-layout-legacy.stories.d.ts +10 -0
  60. package/dist/components/titan-layout/titan-layout-legacy.stories.d.ts.map +1 -0
  61. package/dist/components/titan-layout/titan-layout-links.d.ts +5 -0
  62. package/dist/components/titan-layout/titan-layout-links.d.ts.map +1 -0
  63. package/dist/components/titan-layout/titan-layout-links.js +34 -0
  64. package/dist/components/titan-layout/titan-layout-links.js.map +1 -0
  65. package/dist/components/titan-layout/titan-layout-stacked.stories.d.ts +10 -0
  66. package/dist/components/titan-layout/titan-layout-stacked.stories.d.ts.map +1 -0
  67. package/dist/components/titan-layout/titan-layout.d.ts +5 -4
  68. package/dist/components/titan-layout/titan-layout.d.ts.map +1 -1
  69. package/dist/components/titan-layout/titan-layout.js +33 -14
  70. package/dist/components/titan-layout/titan-layout.js.map +1 -1
  71. package/dist/index.d.ts +1 -6
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +0 -4
  74. package/dist/index.js.map +1 -1
  75. package/dist/test/data.d.ts +26 -23
  76. package/dist/test/data.d.ts.map +1 -1
  77. package/dist/test/data.js +26 -69
  78. package/dist/test/data.js.map +1 -1
  79. package/dist/test/titan-layout.d.ts +16 -0
  80. package/dist/test/titan-layout.d.ts.map +1 -0
  81. package/dist/test/titan-layout.js +21 -0
  82. package/dist/test/titan-layout.js.map +1 -0
  83. package/dist/utils/navigation-context.d.ts +3 -22
  84. package/dist/utils/navigation-context.d.ts.map +1 -1
  85. package/dist/utils/navigation-context.js +2 -10
  86. package/dist/utils/navigation-context.js.map +1 -1
  87. package/dist/utils/navigation.d.ts +2 -7
  88. package/dist/utils/navigation.d.ts.map +1 -1
  89. package/dist/utils/navigation.js.map +1 -1
  90. package/package.json +4 -4
  91. package/src/components/counter-tag.tsx +1 -1
  92. package/src/components/profile-dropdown/interface.ts +47 -0
  93. package/src/components/profile-dropdown/profile-dropdown-legacy.stories.tsx +25 -0
  94. package/src/components/profile-dropdown/profile-dropdown-stacked.stories.tsx +15 -7
  95. package/src/components/profile-dropdown/profile-dropdown.stories.tsx +50 -43
  96. package/src/components/profile-dropdown/profile-dropdown.tsx +39 -115
  97. package/src/components/titan-layout/interface-internal.ts +13 -0
  98. package/src/components/titan-layout/interface.ts +73 -17
  99. package/src/components/titan-layout/layout-header-dark.tsx +21 -5
  100. package/src/components/titan-layout/layout-header-links-internal.tsx +41 -54
  101. package/src/components/titan-layout/layout-header-links.tsx +65 -12
  102. package/src/components/titan-layout/layout-header.module.less +37 -1
  103. package/src/components/titan-layout/layout-header.module.less.d.ts +3 -0
  104. package/src/components/titan-layout/layout-header.tsx +28 -15
  105. package/src/components/titan-layout/layout-profile.tsx +53 -34
  106. package/src/components/titan-layout/layout-sidebar-links-internal.tsx +188 -147
  107. package/src/components/titan-layout/layout-sidebar-links.tsx +73 -26
  108. package/src/components/titan-layout/layout-sidebar.module.less +74 -22
  109. package/src/components/titan-layout/layout-sidebar.tsx +55 -80
  110. package/src/components/titan-layout/{titan-layout.stories.tsx → titan-layout-default.stories.tsx} +131 -114
  111. package/src/components/titan-layout/titan-layout-legacy.stories.tsx +24 -0
  112. package/src/components/titan-layout/titan-layout-links.tsx +34 -0
  113. package/src/components/titan-layout/titan-layout-stacked.stories.tsx +30 -0
  114. package/src/components/titan-layout/titan-layout.tsx +39 -15
  115. package/src/index.ts +1 -12
  116. package/src/test/data.tsx +31 -83
  117. package/src/test/titan-layout.tsx +34 -0
  118. package/src/utils/navigation-context.tsx +9 -35
  119. package/src/utils/navigation.ts +3 -10
  120. package/dist/components/header-navigation/header-navigation-content.d.ts +0 -30
  121. package/dist/components/header-navigation/header-navigation-content.d.ts.map +0 -1
  122. package/dist/components/header-navigation/header-navigation-content.js +0 -58
  123. package/dist/components/header-navigation/header-navigation-content.js.map +0 -1
  124. package/dist/components/header-navigation/header-navigation-extra-stacked.stories.d.ts +0 -9
  125. package/dist/components/header-navigation/header-navigation-extra-stacked.stories.d.ts.map +0 -1
  126. package/dist/components/header-navigation/header-navigation-extra.stories.d.ts +0 -12
  127. package/dist/components/header-navigation/header-navigation-extra.stories.d.ts.map +0 -1
  128. package/dist/components/header-navigation/header-navigation-links.d.ts +0 -11
  129. package/dist/components/header-navigation/header-navigation-links.d.ts.map +0 -1
  130. package/dist/components/header-navigation/header-navigation-links.js +0 -62
  131. package/dist/components/header-navigation/header-navigation-links.js.map +0 -1
  132. package/dist/components/header-navigation/header-navigation-stacked.stories.d.ts +0 -12
  133. package/dist/components/header-navigation/header-navigation-stacked.stories.d.ts.map +0 -1
  134. package/dist/components/header-navigation/header-navigation-stories.module.less +0 -6
  135. package/dist/components/header-navigation/header-navigation-stories.module.less.d.ts +0 -3
  136. package/dist/components/header-navigation/header-navigation.d.ts +0 -59
  137. package/dist/components/header-navigation/header-navigation.d.ts.map +0 -1
  138. package/dist/components/header-navigation/header-navigation.js +0 -228
  139. package/dist/components/header-navigation/header-navigation.js.map +0 -1
  140. package/dist/components/header-navigation/header-navigation.module.less +0 -260
  141. package/dist/components/header-navigation/header-navigation.module.less.d.ts +0 -22
  142. package/dist/components/header-navigation/header-navigation.stories.d.ts +0 -12
  143. package/dist/components/header-navigation/header-navigation.stories.d.ts.map +0 -1
  144. package/dist/components/header-navigation/index.d.ts +0 -2
  145. package/dist/components/header-navigation/index.d.ts.map +0 -1
  146. package/dist/components/header-navigation/index.js +0 -3
  147. package/dist/components/header-navigation/index.js.map +0 -1
  148. package/dist/components/header-navigation/with-tooltip.d.ts +0 -4
  149. package/dist/components/header-navigation/with-tooltip.d.ts.map +0 -1
  150. package/dist/components/header-navigation/with-tooltip.js +0 -10
  151. package/dist/components/header-navigation/with-tooltip.js.map +0 -1
  152. package/dist/components/layout.stories.d.ts +0 -13
  153. package/dist/components/layout.stories.d.ts.map +0 -1
  154. package/dist/components/left-navigation/header-navigation-extra-tiny.stories.d.ts +0 -9
  155. package/dist/components/left-navigation/header-navigation-extra-tiny.stories.d.ts.map +0 -1
  156. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts +0 -18
  157. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts.map +0 -1
  158. package/dist/components/left-navigation/header-navigation-tiny-links.js +0 -79
  159. package/dist/components/left-navigation/header-navigation-tiny-links.js.map +0 -1
  160. package/dist/components/left-navigation/header-navigation-tiny.d.ts +0 -23
  161. package/dist/components/left-navigation/header-navigation-tiny.d.ts.map +0 -1
  162. package/dist/components/left-navigation/header-navigation-tiny.js +0 -32
  163. package/dist/components/left-navigation/header-navigation-tiny.js.map +0 -1
  164. package/dist/components/left-navigation/header-navigation-tiny.module.less +0 -117
  165. package/dist/components/left-navigation/header-navigation-tiny.module.less.d.ts +0 -15
  166. package/dist/components/left-navigation/header-navigation-tiny.stories.d.ts +0 -12
  167. package/dist/components/left-navigation/header-navigation-tiny.stories.d.ts.map +0 -1
  168. package/dist/components/left-navigation/index.d.ts +0 -5
  169. package/dist/components/left-navigation/index.d.ts.map +0 -1
  170. package/dist/components/left-navigation/index.js +0 -5
  171. package/dist/components/left-navigation/index.js.map +0 -1
  172. package/dist/components/left-navigation/interface-internal.d.ts +0 -10
  173. package/dist/components/left-navigation/interface-internal.d.ts.map +0 -1
  174. package/dist/components/left-navigation/interface-internal.js +0 -3
  175. package/dist/components/left-navigation/interface-internal.js.map +0 -1
  176. package/dist/components/left-navigation/interface.d.ts +0 -20
  177. package/dist/components/left-navigation/interface.d.ts.map +0 -1
  178. package/dist/components/left-navigation/interface.js.map +0 -1
  179. package/dist/components/left-navigation/side-navigation-context.d.ts +0 -8
  180. package/dist/components/left-navigation/side-navigation-context.d.ts.map +0 -1
  181. package/dist/components/left-navigation/side-navigation-context.js +0 -8
  182. package/dist/components/left-navigation/side-navigation-context.js.map +0 -1
  183. package/dist/components/left-navigation/side-navigation-links-internal.d.ts +0 -28
  184. package/dist/components/left-navigation/side-navigation-links-internal.d.ts.map +0 -1
  185. package/dist/components/left-navigation/side-navigation-links-internal.js +0 -89
  186. package/dist/components/left-navigation/side-navigation-links-internal.js.map +0 -1
  187. package/dist/components/left-navigation/side-navigation-links.d.ts +0 -6
  188. package/dist/components/left-navigation/side-navigation-links.d.ts.map +0 -1
  189. package/dist/components/left-navigation/side-navigation-links.js +0 -48
  190. package/dist/components/left-navigation/side-navigation-links.js.map +0 -1
  191. package/dist/components/left-navigation/side-navigation.d.ts +0 -29
  192. package/dist/components/left-navigation/side-navigation.d.ts.map +0 -1
  193. package/dist/components/left-navigation/side-navigation.js +0 -411
  194. package/dist/components/left-navigation/side-navigation.js.map +0 -1
  195. package/dist/components/left-navigation/side-navigation.module.less +0 -530
  196. package/dist/components/left-navigation/side-navigation.module.less.d.ts +0 -48
  197. package/dist/components/left-navigation/side-navigation.stories.d.ts +0 -17
  198. package/dist/components/left-navigation/side-navigation.stories.d.ts.map +0 -1
  199. package/dist/components/left-navigation/with-tooltip.d.ts +0 -4
  200. package/dist/components/left-navigation/with-tooltip.d.ts.map +0 -1
  201. package/dist/components/left-navigation/with-tooltip.js +0 -15
  202. package/dist/components/left-navigation/with-tooltip.js.map +0 -1
  203. package/dist/components/links.d.ts +0 -5
  204. package/dist/components/links.d.ts.map +0 -1
  205. package/dist/components/links.js +0 -35
  206. package/dist/components/links.js.map +0 -1
  207. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.d.ts +0 -9
  208. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.d.ts.map +0 -1
  209. package/dist/components/titan-layout/layout-profile.stories.d.ts +0 -13
  210. package/dist/components/titan-layout/layout-profile.stories.d.ts.map +0 -1
  211. package/dist/components/titan-layout/titan-layout.stories.d.ts +0 -29
  212. package/dist/components/titan-layout/titan-layout.stories.d.ts.map +0 -1
  213. package/dist/utils/navigation-legacy.d.ts +0 -88
  214. package/dist/utils/navigation-legacy.d.ts.map +0 -1
  215. package/dist/utils/navigation-legacy.js +0 -3
  216. package/dist/utils/navigation-legacy.js.map +0 -1
  217. package/src/components/header-navigation/header-navigation-content.tsx +0 -120
  218. package/src/components/header-navigation/header-navigation-extra-stacked.stories.tsx +0 -19
  219. package/src/components/header-navigation/header-navigation-extra.stories.tsx +0 -142
  220. package/src/components/header-navigation/header-navigation-links.tsx +0 -141
  221. package/src/components/header-navigation/header-navigation-stacked.stories.tsx +0 -146
  222. package/src/components/header-navigation/header-navigation-stories.module.less +0 -6
  223. package/src/components/header-navigation/header-navigation-stories.module.less.d.ts +0 -3
  224. package/src/components/header-navigation/header-navigation.module.less +0 -260
  225. package/src/components/header-navigation/header-navigation.module.less.d.ts +0 -22
  226. package/src/components/header-navigation/header-navigation.stories.tsx +0 -165
  227. package/src/components/header-navigation/header-navigation.tsx +0 -327
  228. package/src/components/header-navigation/index.ts +0 -1
  229. package/src/components/header-navigation/with-tooltip.tsx +0 -15
  230. package/src/components/layout.stories.tsx +0 -103
  231. package/src/components/left-navigation/header-navigation-extra-tiny.stories.tsx +0 -21
  232. package/src/components/left-navigation/header-navigation-tiny-links.tsx +0 -145
  233. package/src/components/left-navigation/header-navigation-tiny.module.less +0 -117
  234. package/src/components/left-navigation/header-navigation-tiny.module.less.d.ts +0 -15
  235. package/src/components/left-navigation/header-navigation-tiny.stories.tsx +0 -178
  236. package/src/components/left-navigation/header-navigation-tiny.tsx +0 -65
  237. package/src/components/left-navigation/index.ts +0 -4
  238. package/src/components/left-navigation/interface-internal.ts +0 -11
  239. package/src/components/left-navigation/interface.ts +0 -26
  240. package/src/components/left-navigation/side-navigation-context.tsx +0 -13
  241. package/src/components/left-navigation/side-navigation-links-internal.tsx +0 -151
  242. package/src/components/left-navigation/side-navigation-links.tsx +0 -57
  243. package/src/components/left-navigation/side-navigation.module.less +0 -530
  244. package/src/components/left-navigation/side-navigation.module.less.d.ts +0 -48
  245. package/src/components/left-navigation/side-navigation.stories.tsx +0 -226
  246. package/src/components/left-navigation/side-navigation.tsx +0 -543
  247. package/src/components/left-navigation/with-tooltip.tsx +0 -16
  248. package/src/components/links.tsx +0 -54
  249. package/src/components/profile-dropdown/profile-dropdown-tiny.stories.tsx +0 -25
  250. package/src/components/titan-layout/layout-profile.stories.tsx +0 -46
  251. package/src/utils/navigation-legacy.ts +0 -106
  252. /package/dist/components/{left-navigation → profile-dropdown}/interface.js +0 -0
@@ -0,0 +1,47 @@
1
+ import { PopoverPropsStrict } from '@servicetitan/design-system';
2
+ import { ComponentPropsWithoutRef, FC, ReactNode } from 'react';
3
+ import { CounterTagData, CounterTagValue } from '../../utils/counter-tag';
4
+
5
+ export type ProfileDropdownTriggerProps = {
6
+ info?: { title: string; text: string };
7
+ imageSrc?: string | null;
8
+ avatarBadge?: boolean | string;
9
+ badge?: { content?: number | string; className: string };
10
+ } & Omit<ComponentPropsWithoutRef<'div'>, 'onClick'>;
11
+
12
+ export type ProfileDropdownProps = {
13
+ direction?: PopoverPropsStrict['direction'];
14
+ trigger?: Omit<ProfileDropdownTriggerProps, 'onClick' | 'open' | 'hintArrow'>;
15
+ hintPopup?: {
16
+ className?: string;
17
+ content: FC<{ openProfile(): void }>;
18
+ width?: PopoverPropsStrict['width'];
19
+ onClose?: () => void;
20
+ };
21
+ portal?: boolean;
22
+ width?: PopoverPropsStrict['width'];
23
+ onClose?(): void;
24
+ onOpen?(): void;
25
+ } & ComponentPropsWithoutRef<'div'>;
26
+
27
+ export type ProfileItemContent =
28
+ | { children: string; text?: string }
29
+ | { children: ReactNode; text: string };
30
+
31
+ export type ProfileDropdownSectionProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'> & {
32
+ children: ReactNode;
33
+ id: string;
34
+ tooltip?: string;
35
+ tag?: CounterTagData;
36
+ counter?: CounterTagValue;
37
+ } & ProfileItemContent;
38
+
39
+ export type ProfileDropdownLinkProps = Omit<ComponentPropsWithoutRef<'a'>, 'children'> & {
40
+ id: string;
41
+ children: ReactNode;
42
+ external?: boolean;
43
+ tooltip?: string;
44
+ to: string;
45
+ tag?: CounterTagData;
46
+ counter?: CounterTagValue;
47
+ } & ProfileItemContent;
@@ -0,0 +1,25 @@
1
+ import { NavLinkMock, withAnvil, withMemoryRouter } from '../../test/data';
2
+ import { TitanLayout } from '../titan-layout';
3
+ import { DesktopProfileDropdown } from './profile-dropdown';
4
+
5
+ const withLayout = (Story: any) => (
6
+ <TitanLayout navVariant="top" profile={<Story />} navigationComponent={NavLinkMock} />
7
+ );
8
+
9
+ export default {
10
+ title: 'Navigation/DesktopProfileDropdown/Legacy',
11
+ component: DesktopProfileDropdown,
12
+ parameters: {},
13
+ decorators: [withMemoryRouter, withAnvil, withLayout],
14
+ };
15
+
16
+ export {
17
+ ProfileDropdownDefault,
18
+ ProfileDropdownWithBothBadges,
19
+ ProfileDropdownWithCounter,
20
+ ProfileDropdownWithErrorLogo,
21
+ ProfileDropdownWithInfo,
22
+ ProfileDropdownWithHintAndInfoPopup,
23
+ ProfileDropdownWithHintPopup,
24
+ ProfileDropdownWithLogo,
25
+ } from './profile-dropdown.stories';
@@ -1,14 +1,22 @@
1
- import { withAnvil, withMemoryRouter } from '../../test/data';
2
- import { HeaderNavigationStacked } from '../header-navigation';
3
- import { ProfileDropdown } from './profile-dropdown';
1
+ import { NavLinkMock, navItems, withAnvil, withMemoryRouter } from '../../test/data';
2
+ import { TitanLayout } from '../titan-layout';
3
+ import { DesktopProfileDropdown } from './profile-dropdown';
4
4
 
5
- const withHeaderNavigationStacked = (Story: any) => <HeaderNavigationStacked right={<Story />} />;
5
+ const withStackedLayout = (Story: any) => (
6
+ <TitanLayout
7
+ navVariant="top"
8
+ top={<div />}
9
+ profile={<Story />}
10
+ navigationMainItems={[navItems.accounting]}
11
+ navigationComponent={NavLinkMock}
12
+ />
13
+ );
6
14
 
7
15
  export default {
8
- title: 'Navigation/ProfileDropdown/Stacked',
9
- component: ProfileDropdown,
16
+ title: 'Navigation/DesktopProfileDropdown/Stacked',
17
+ component: DesktopProfileDropdown,
10
18
  parameters: {},
11
- decorators: [withMemoryRouter, withAnvil, withHeaderNavigationStacked],
19
+ decorators: [withStackedLayout, withMemoryRouter, withAnvil],
12
20
  };
13
21
 
14
22
  export {
@@ -1,58 +1,65 @@
1
1
  import { Button } from '@servicetitan/design-system';
2
- import { withAnvil, withMemoryRouter } from '../../test/data';
3
- import { HeaderNavigation } from '../header-navigation';
4
- import { ProfileDropdown } from './profile-dropdown';
2
+ import { NavLinkMock, withAnvil, withMemoryRouter } from '../../test/data';
3
+ import { TitanLayout } from '../titan-layout';
4
+ import { DesktopProfileDropdown } from './profile-dropdown';
5
5
 
6
- const withHeaderNavigation = (Story: any) => (
7
- <HeaderNavigation>
8
- <Story />
9
- </HeaderNavigation>
6
+ const withLegacyLayout = (Story: any) => (
7
+ <TitanLayout navigationComponent={NavLinkMock} profile={<Story />} />
10
8
  );
11
9
 
12
10
  export default {
13
- title: 'Navigation/ProfileDropdown/Legacy',
14
- component: ProfileDropdown,
11
+ title: 'Navigation/DesktopProfileDropdown/Default',
12
+ component: DesktopProfileDropdown,
15
13
  parameters: {},
16
- decorators: [withMemoryRouter, withAnvil, withHeaderNavigation],
14
+ decorators: [withLegacyLayout, withMemoryRouter, withAnvil],
17
15
  };
18
16
 
19
17
  export const ProfileDropdownDefault = () => (
20
- <ProfileDropdown>
21
- <ProfileDropdown.Link id="first" to="https://google.com">
18
+ <DesktopProfileDropdown>
19
+ <DesktopProfileDropdown.Link id="first" to="https://google.com" external>
22
20
  first link
23
- </ProfileDropdown.Link>
24
- <ProfileDropdown.Section id="second" onClick={() => alert('second click')}>
21
+ </DesktopProfileDropdown.Link>
22
+ <DesktopProfileDropdown.Section id="second" onClick={() => alert('second click')}>
25
23
  second link
26
- </ProfileDropdown.Section>
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">
24
+ </DesktopProfileDropdown.Section>
25
+ <DesktopProfileDropdown.Divider />
26
+ <DesktopProfileDropdown.Section id="content">some content</DesktopProfileDropdown.Section>
27
+ <DesktopProfileDropdown.Divider />
28
+ <DesktopProfileDropdown.Divider />
29
+ <DesktopProfileDropdown.Divider />
30
+ <DesktopProfileDropdown.Link id="third" to="third">
33
31
  third link
34
- </ProfileDropdown.Link>
35
- <ProfileDropdown.Divider />
36
- </ProfileDropdown>
32
+ </DesktopProfileDropdown.Link>
33
+ <DesktopProfileDropdown.Divider />
34
+ <DesktopProfileDropdown.Section
35
+ id="forth"
36
+ onClick={() => alert('forth click')}
37
+ text="Sign Out user"
38
+ >
39
+ Sign Out
40
+ <span className="c-neutral-60 m-l-1">user</span>
41
+ </DesktopProfileDropdown.Section>
42
+ <DesktopProfileDropdown.Divider />
43
+ </DesktopProfileDropdown>
37
44
  );
38
45
 
39
46
  export const ProfileDropdownWithLogo = () => (
40
- <ProfileDropdown
47
+ <DesktopProfileDropdown
41
48
  trigger={{
42
49
  imageSrc: 'https://upload.wikimedia.org/wikipedia/en/1/11/Milhouse_Van_Houten.png',
43
50
  }}
44
51
  >
45
- <ProfileDropdown.Link id="first" to="https://google.com">
52
+ <DesktopProfileDropdown.Link id="first" to="https://google.com">
46
53
  first link
47
- </ProfileDropdown.Link>
48
- <ProfileDropdown.Section id="second" onClick={() => alert('second click')}>
54
+ </DesktopProfileDropdown.Link>
55
+ <DesktopProfileDropdown.Section id="second" onClick={() => alert('second click')}>
49
56
  second link
50
- </ProfileDropdown.Section>
51
- </ProfileDropdown>
57
+ </DesktopProfileDropdown.Section>
58
+ </DesktopProfileDropdown>
52
59
  );
53
60
 
54
61
  export const ProfileDropdownWithErrorLogo = () => (
55
- <ProfileDropdown
62
+ <DesktopProfileDropdown
56
63
  trigger={{
57
64
  imageSrc: 'https://some.incorrect.url/logo.png',
58
65
  }}
@@ -60,7 +67,7 @@ export const ProfileDropdownWithErrorLogo = () => (
60
67
  );
61
68
 
62
69
  export const ProfileDropdownWithInfo = () => (
63
- <ProfileDropdown
70
+ <DesktopProfileDropdown
64
71
  trigger={{
65
72
  info: { text: 'first', title: 'tenant user' },
66
73
  avatarBadge: true,
@@ -69,7 +76,7 @@ export const ProfileDropdownWithInfo = () => (
69
76
  );
70
77
 
71
78
  export const ProfileDropdownWithCounter = () => (
72
- <ProfileDropdown
79
+ <DesktopProfileDropdown
73
80
  trigger={{
74
81
  info: { text: 'first', title: 'tenant user' },
75
82
  avatarBadge: true,
@@ -79,7 +86,7 @@ export const ProfileDropdownWithCounter = () => (
79
86
  );
80
87
 
81
88
  export const ProfileDropdownWithBothBadges = () => (
82
- <ProfileDropdown
89
+ <DesktopProfileDropdown
83
90
  trigger={{
84
91
  avatarBadge: 'yellow-500',
85
92
  badge: { className: 'bg-red-400' },
@@ -91,7 +98,7 @@ export const ProfileDropdownWithBothBadges = () => (
91
98
  const log = (text: string) => console.log(text);
92
99
 
93
100
  export const ProfileDropdownWithHintPopup = () => (
94
- <ProfileDropdown
101
+ <DesktopProfileDropdown
95
102
  trigger={{
96
103
  avatarBadge: 'yellow-500',
97
104
  badge: { className: 'bg-red-400' },
@@ -112,19 +119,19 @@ export const ProfileDropdownWithHintPopup = () => (
112
119
  onOpen={() => log('open profile dropdown')}
113
120
  onClose={() => log('close profile dropdown')}
114
121
  >
115
- <ProfileDropdown.Link id="first" to="https://google.com" counter={12}>
122
+ <DesktopProfileDropdown.Link id="first" to="https://google.com" counter={12}>
116
123
  first item
117
- </ProfileDropdown.Link>
118
- <ProfileDropdown.Divider />
119
- <ProfileDropdown.Section id="second">second item</ProfileDropdown.Section>
120
- <ProfileDropdown.Link id="third" to="https://google.com" tag={{ value: 1 }}>
124
+ </DesktopProfileDropdown.Link>
125
+ <DesktopProfileDropdown.Divider />
126
+ <DesktopProfileDropdown.Section id="second">second item</DesktopProfileDropdown.Section>
127
+ <DesktopProfileDropdown.Link id="third" to="https://google.com" tag={{ value: 1 }}>
121
128
  third item
122
- </ProfileDropdown.Link>
123
- </ProfileDropdown>
129
+ </DesktopProfileDropdown.Link>
130
+ </DesktopProfileDropdown>
124
131
  );
125
132
 
126
133
  export const ProfileDropdownWithHintAndInfoPopup = () => (
127
- <ProfileDropdown
134
+ <DesktopProfileDropdown
128
135
  trigger={{
129
136
  avatarBadge: 'yellow-500',
130
137
  badge: { className: 'bg-red-400' },
@@ -3,57 +3,41 @@ import SvgExpandLess from '@servicetitan/anvil2/assets/icons/material/round/expa
3
3
  import SvgExpandMore from '@servicetitan/anvil2/assets/icons/material/round/expand_more.svg';
4
4
  import SvgAccountActive from '@servicetitan/anvil2/assets/icons/st/gnav_account_active.svg';
5
5
  import SvgAccountInactive from '@servicetitan/anvil2/assets/icons/st/gnav_account_inactive.svg';
6
- import { BodyText, Popover, PopoverPropsStrict } from '@servicetitan/design-system';
6
+ import { BodyText, Popover } from '@servicetitan/design-system';
7
7
  import classNames from 'classnames';
8
8
  import {
9
9
  ComponentPropsWithoutRef,
10
10
  FC,
11
- HTMLAttributeAnchorTarget,
12
11
  MouseEvent,
13
12
  MouseEventHandler,
14
- ReactNode,
15
13
  useCallback,
16
- useContext,
17
14
  useEffect,
18
15
  useMemo,
19
16
  useState,
20
17
  } from 'react';
21
18
 
22
19
  import { CounterTagData, CounterTagValue } from '../../utils/counter-tag';
23
- import {
24
- NavigationComponentContext,
25
- NavigationLegacyContext,
26
- } from '../../utils/navigation-context';
27
20
  import { getCounterTag } from '../../utils/side-nav';
28
21
  import { CounterTag } from '../counter-tag';
22
+ import { useTitanLayoutContext } from '../titan-layout';
29
23
  import { withTooltip } from '../titan-layout/with-tooltip';
24
+ import {
25
+ ProfileDropdownLinkProps,
26
+ ProfileDropdownProps,
27
+ ProfileDropdownSectionProps,
28
+ ProfileDropdownTriggerProps,
29
+ } from './interface';
30
30
  import * as Styles from './profile-dropdown.module.less';
31
- import { ProfileLogo } from './profile-icon';
32
31
 
33
- export interface ProfileDropdownTriggerProps {
34
- className?: string;
35
- info?: { title: string; text: string };
36
- imageSrc?: string | null;
37
- avatarBadge?: boolean | string;
38
- badge?: { content?: number | string; className: string };
39
- hintArrow?: boolean;
40
- open: boolean;
41
- onClick?(e: MouseEvent): void;
42
- }
43
-
44
- const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
45
- avatarBadge,
46
- badge,
47
- className,
48
- hintArrow,
49
- imageSrc,
50
- info,
51
- onClick,
52
- open,
53
- }) => {
32
+ const ProfileDropdownTrigger: FC<
33
+ ProfileDropdownTriggerProps & {
34
+ hintArrow?: boolean;
35
+ open: boolean;
36
+ onClick: ComponentPropsWithoutRef<'div'>['onClick'];
37
+ }
38
+ > = ({ info, imageSrc, avatarBadge, badge, className, hintArrow, open, onClick, ...rest }) => {
54
39
  const [avatarSource, setAvatarSource] = useState(imageSrc ?? '');
55
40
  const [avatarSourceError, setAvatarSourceError] = useState(false);
56
- const isLegacy = useContext(NavigationLegacyContext);
57
41
 
58
42
  useEffect(() => {
59
43
  const src = imageSrc ?? '';
@@ -72,19 +56,19 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
72
56
 
73
57
  return (
74
58
  <div
59
+ data-cy="profile-dropdown-trigger"
60
+ data-pendo="profile-dropdown-trigger"
61
+ {...rest}
75
62
  className={classNames(
76
63
  'd-f align-items-center cursor-pointer position-relative p-x-1 p-y-half',
77
64
  'profile-dropdown-trigger',
78
65
  Styles.triggerContainer,
79
66
  {
80
67
  [Styles.triggerContainerHintArrow]: hintArrow,
81
- [Styles.triggerContainerLegacy]: isLegacy,
82
68
  },
83
69
  className
84
70
  )}
85
71
  onClick={onClick}
86
- data-cy="profile-dropdown-trigger"
87
- data-pendo="profile-dropdown-trigger"
88
72
  >
89
73
  {avatarSource && !avatarSourceError ? (
90
74
  <img
@@ -93,8 +77,6 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
93
77
  onError={onAvatarError}
94
78
  alt="user dropdown menu"
95
79
  />
96
- ) : isLegacy ? (
97
- <ProfileLogo />
98
80
  ) : (
99
81
  <Icon
100
82
  className="c-inherit-i"
@@ -163,25 +145,7 @@ const useTag = (counter?: CounterTagValue, tag?: CounterTagData) =>
163
145
  ) : undefined;
164
146
  }, [counter, tag]);
165
147
 
166
- export type ProfileItemContent =
167
- | { children: string; text?: string }
168
- | { children: ReactNode; text: string };
169
-
170
- export interface ProfileDropdownSectionPropsStrict {
171
- children: ReactNode;
172
- id: string;
173
- tooltip?: string;
174
- className?: string;
175
- tag?: CounterTagData;
176
- counter?: CounterTagValue;
177
- onClick?(e: MouseEvent): void;
178
- }
179
-
180
- export type ProfileDropdownSectionProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'> &
181
- ProfileDropdownSectionPropsStrict &
182
- ProfileItemContent;
183
-
184
- export const ProfileDropdownSection: FC<ProfileDropdownSectionProps> = ({
148
+ function DesktopProfileDropdownSection({
185
149
  children,
186
150
  className,
187
151
  counter,
@@ -191,7 +155,7 @@ export const ProfileDropdownSection: FC<ProfileDropdownSectionProps> = ({
191
155
  tooltip,
192
156
  onClick,
193
157
  ...rest
194
- }) => {
158
+ }: ProfileDropdownSectionProps) {
195
159
  const clickHandler: MouseEventHandler<never> = e => {
196
160
  if (onClick) {
197
161
  onClick(e);
@@ -221,27 +185,11 @@ export const ProfileDropdownSection: FC<ProfileDropdownSectionProps> = ({
221
185
  tooltip,
222
186
  { placement: 'left' }
223
187
  );
224
- };
225
-
226
- export const ProfileDropdownDivider: FC = Popover.Divider;
227
-
228
- export interface ProfileDropdownLinkPropsStrict {
229
- id: string;
230
- children: ReactNode;
231
- className?: string;
232
- external?: boolean;
233
- target?: HTMLAttributeAnchorTarget;
234
- tooltip?: string;
235
- to: string;
236
- tag?: CounterTagData;
237
- counter?: CounterTagValue;
238
188
  }
239
189
 
240
- export type ProfileDropdownLinkProps = Omit<ComponentPropsWithoutRef<'a'>, 'children'> &
241
- ProfileDropdownLinkPropsStrict &
242
- ProfileItemContent;
190
+ const DesktopProfileDropdownDivider: FC = Popover.Divider;
243
191
 
244
- export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
192
+ function DesktopProfileDropdownLink({
245
193
  children,
246
194
  className,
247
195
  external,
@@ -254,8 +202,8 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
254
202
  tooltip,
255
203
  onClick,
256
204
  ...rest
257
- }: ProfileDropdownLinkProps) => {
258
- const NavigationComponent = useContext(NavigationComponentContext);
205
+ }: ProfileDropdownLinkProps) {
206
+ const { NavigationComponent } = useTitanLayoutContext();
259
207
 
260
208
  const isExternalLink = external ?? to?.startsWith('http');
261
209
 
@@ -300,47 +248,21 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
300
248
  tooltip,
301
249
  { placement: 'left' }
302
250
  );
303
- };
304
-
305
- export interface ProfileDropdownPropsStrict {
306
- children?: ReactNode;
307
- className?: string;
308
- direction?: PopoverPropsStrict['direction'];
309
- trigger?: Omit<ProfileDropdownTriggerProps, 'onClick' | 'open' | 'hintArrow'>;
310
- hintPopup?: {
311
- className?: string;
312
- content: FC<{ openProfile(): void }>;
313
- width?: PopoverPropsStrict['width'];
314
- onClose?: () => void;
315
- };
316
- portal?: boolean;
317
- width?: PopoverPropsStrict['width'];
318
- onClose?(): void;
319
- onOpen?(): void;
320
- }
321
-
322
- export interface ProfileDropdownProps extends ProfileDropdownPropsStrict {
323
- [key: string]: any;
324
251
  }
325
252
 
326
- export interface ProfileDropdownType extends FC<ProfileDropdownProps> {
327
- Divider: typeof ProfileDropdownDivider;
328
- Link: typeof ProfileDropdownLink;
329
- Trigger: typeof ProfileDropdownTrigger;
330
- Section: typeof ProfileDropdownSection;
331
- }
332
-
333
- export const ProfileDropdown: ProfileDropdownType = (({
253
+ function DesktopProfileDropdownComponent({
334
254
  children,
335
- className,
255
+
336
256
  direction,
257
+ trigger,
337
258
  hintPopup,
338
- onClose,
339
- onOpen,
340
259
  portal,
341
- trigger,
342
260
  width,
343
- }) => {
261
+ onClose,
262
+ onOpen,
263
+
264
+ ...rest
265
+ }: ProfileDropdownProps) {
344
266
  const [open, setOpen] = useState(false);
345
267
  const handleClose = useCallback(() => {
346
268
  setOpen(false);
@@ -376,7 +298,7 @@ export const ProfileDropdown: ProfileDropdownType = (({
376
298
  );
377
299
 
378
300
  return (
379
- <div className={className} data-cy="profile-dropdown">
301
+ <div data-cy="profile-dropdown" {...rest}>
380
302
  {!!hintPopup && hintShown && HintComponent ? (
381
303
  <Popover
382
304
  direction={direction ?? 'bl'}
@@ -415,8 +337,10 @@ export const ProfileDropdown: ProfileDropdownType = (({
415
337
  )}
416
338
  </div>
417
339
  );
418
- }) as ProfileDropdownType;
340
+ }
419
341
 
420
- ProfileDropdown.Divider = ProfileDropdownDivider;
421
- ProfileDropdown.Link = ProfileDropdownLink;
422
- ProfileDropdown.Section = ProfileDropdownSection;
342
+ export const DesktopProfileDropdown = Object.assign(DesktopProfileDropdownComponent, {
343
+ Divider: DesktopProfileDropdownDivider,
344
+ Link: DesktopProfileDropdownLink,
345
+ Section: DesktopProfileDropdownSection,
346
+ });
@@ -1,6 +1,19 @@
1
+ import { IconProps } from '@servicetitan/anvil2';
1
2
  import { FC } from 'react';
3
+ import { CounterTagData } from '../../utils/counter-tag';
2
4
  import { NavLinkComponentProps } from '../../utils/navigation-context';
3
5
 
4
6
  export interface NavigationComponentProps {
5
7
  navigationComponent: FC<NavLinkComponentProps>;
6
8
  }
9
+ export interface NavigationItemPropsStrict {
10
+ id: string;
11
+ to: string;
12
+ title: string;
13
+ isActive: boolean | ((pathname: string) => boolean) | undefined;
14
+ icon: IconProps['svg'] | undefined;
15
+ iconActive: IconProps['svg'] | undefined;
16
+
17
+ tag: CounterTagData | undefined;
18
+ className: string | undefined;
19
+ }
@@ -1,26 +1,82 @@
1
- import { FC, ReactElement } from 'react';
2
- import { NavigationItemData } from '../../utils/navigation';
1
+ import { IconProps } from '@servicetitan/anvil2';
2
+ import { ComponentPropsWithoutRef, FC, ReactNode } from 'react';
3
+ import { CounterTagData, CounterTagValue } from '../../utils/counter-tag';
3
4
  import { TitanLayoutSidebarContextType } from './layout-context';
4
5
 
5
- export interface TitanLayoutSidebarLinkWrapperProps {
6
- children:
7
- | ReactElement<TitanLayoutSidebarLinkProps>
8
- | ReactElement<TitanLayoutSidebarTriggerProps>;
6
+ export interface TitanLayoutLinkWrapperProps {
7
+ children: ReactNode;
9
8
  context: TitanLayoutSidebarContextType;
9
+ isMobile: boolean;
10
10
  }
11
11
 
12
- export interface TitanLayoutSidebarLinkProps extends Omit<NavigationItemData, 'submenu'> {
13
- wrapper?: FC<TitanLayoutSidebarLinkWrapperProps>;
14
- }
15
- export interface TitanLayoutSidebarTriggerProps
16
- extends Omit<TitanLayoutSidebarLinkProps, 'to' | 'isActive'> {
17
- isActive?: boolean;
18
- wrapper?: FC<TitanLayoutSidebarLinkWrapperProps>;
19
- onClick?: () => void;
20
- onMobileClick?: () => void;
21
- }
12
+ export type TitanLayoutLinkWrapper = FC<TitanLayoutLinkWrapperProps>;
22
13
 
23
14
  export interface TitanLayoutState {
24
15
  navCollapsed: boolean;
25
- submenuExpanded?: string;
16
+ submenusExpanded?: string[];
17
+ }
18
+
19
+ export interface TitanLayoutLinkExtraProps {
20
+ showTitle?: boolean;
21
+ flashing?: boolean;
22
+ }
23
+
24
+ export interface TitanLayoutLinkSideProps {
25
+ counter: CounterTagValue;
26
26
  }
27
+
28
+ export type TitanLayoutLinkProps = {
29
+ /** link id */
30
+ id: string;
31
+ /** link href */
32
+ to: string;
33
+ /** link title */
34
+ title: string;
35
+ /** callback to return active state. By default, it compares link href with current pathname */
36
+ isActive?: boolean | ((pathname: string) => boolean);
37
+ /** svg icon (anvil2) of inactive item */
38
+ icon: IconProps['svg'] | undefined;
39
+ /** svg icon (anvil2) of active item */
40
+ iconActive: IconProps['svg'] | undefined;
41
+ /** item tag (optional). shown if it is set and value is true or greater than 0 */
42
+ tag?: CounterTagData;
43
+ counter?: CounterTagValue;
44
+ /** class name of link item */
45
+ className?: string;
46
+
47
+ /** tooltip text (for extra links) */
48
+ tooltip?: string;
49
+ /** wrapper component for link element (used for side links) */
50
+ wrapper?: TitanLayoutLinkWrapper;
51
+ /** props for extra link element */
52
+ extra?: TitanLayoutLinkExtraProps;
53
+ /** props for side nav link element (mobile version) */
54
+ side?: TitanLayoutLinkSideProps;
55
+ } & Omit<ComponentPropsWithoutRef<'a'>, 'children' | 'title'>;
56
+
57
+ export type TitanLayoutTriggerProps = {
58
+ /** link id */
59
+ id: string;
60
+ /** link title */
61
+ title: string;
62
+ /** active state */
63
+ isActive?: boolean;
64
+ /** svg icon (anvil2) of inactive item */
65
+ icon: IconProps['svg'] | undefined;
66
+ /** svg icon (anvil2) of active item */
67
+ iconActive: IconProps['svg'] | undefined;
68
+ /** item tag (optional). shown if it is set and value is true or greater than 0 */
69
+ tag?: CounterTagData;
70
+ counter?: CounterTagValue;
71
+ /** class name of link item */
72
+ className?: string;
73
+
74
+ /** tooltip text (for extra links) */
75
+ tooltip?: string;
76
+ /** wrapper component for link element (used for side links) */
77
+ wrapper?: TitanLayoutLinkWrapper;
78
+ /** props for extra link element */
79
+ extra?: TitanLayoutLinkExtraProps;
80
+ /** props for nav link element (mobile version) */
81
+ side?: TitanLayoutLinkSideProps;
82
+ } & Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'title'>;