@servicetitan/navigation 10.7.0 → 11.0.0-canary.237.4cefc6a.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 (215) hide show
  1. package/package.json +4 -4
  2. package/src/components/header-navigation/header-navigation-extra.stories.tsx +7 -0
  3. package/src/components/header-navigation/header-navigation-links.tsx +2 -0
  4. package/src/components/header-navigation/header-navigation-stacked.stories.tsx +4 -0
  5. package/src/components/header-navigation/header-navigation.stories.tsx +5 -0
  6. package/src/components/left-navigation/header-navigation-tiny.stories.tsx +6 -0
  7. package/src/components/links.tsx +33 -13
  8. package/src/components/logo/logo-company-title.tsx +8 -6
  9. package/src/components/profile-dropdown/profile-dropdown.module.less +4 -0
  10. package/src/components/profile-dropdown/profile-dropdown.stories.tsx +4 -4
  11. package/src/components/profile-dropdown/profile-dropdown.tsx +43 -46
  12. package/src/components/titan-layout/index.ts +5 -0
  13. package/src/components/titan-layout/interface-internal.ts +6 -0
  14. package/src/components/titan-layout/interface.ts +26 -0
  15. package/src/components/titan-layout/layout-context.tsx +30 -0
  16. package/src/components/titan-layout/layout-header-links.tsx +144 -0
  17. package/{dist/components/left-navigation/header-navigation-tiny.module.less → src/components/titan-layout/layout-header.module.less} +41 -5
  18. package/src/components/titan-layout/layout-header.tsx +86 -0
  19. package/src/components/titan-layout/layout-logo.stories.tsx +31 -0
  20. package/src/components/titan-layout/layout-logo.tsx +57 -0
  21. package/src/components/titan-layout/layout-profile.stories.tsx +37 -0
  22. package/src/components/titan-layout/layout-profile.tsx +116 -0
  23. package/src/components/titan-layout/layout-sidebar-links-internal.tsx +265 -0
  24. package/src/components/titan-layout/layout-sidebar-links.tsx +56 -0
  25. package/src/components/titan-layout/layout-sidebar.module.less +528 -0
  26. package/src/components/titan-layout/layout-sidebar.tsx +298 -0
  27. package/src/components/titan-layout/titan-layout.module.less +53 -0
  28. package/src/components/titan-layout/titan-layout.stories.tsx +194 -0
  29. package/src/components/titan-layout/titan-layout.tsx +270 -0
  30. package/src/components/titan-layout/with-tooltip.tsx +16 -0
  31. package/src/index.ts +2 -1
  32. package/src/test/data.tsx +3 -2
  33. package/src/utils/navigation-legacy.ts +3 -1
  34. package/src/utils/use-breakpoint.ts +19 -0
  35. package/dist/components/badge-tag.d.ts +0 -12
  36. package/dist/components/badge-tag.d.ts.map +0 -1
  37. package/dist/components/badge-tag.js +0 -8
  38. package/dist/components/badge-tag.js.map +0 -1
  39. package/dist/components/counter-tag.d.ts +0 -12
  40. package/dist/components/counter-tag.d.ts.map +0 -1
  41. package/dist/components/counter-tag.js +0 -8
  42. package/dist/components/counter-tag.js.map +0 -1
  43. package/dist/components/header-navigation/header-navigation-content.d.ts +0 -30
  44. package/dist/components/header-navigation/header-navigation-content.d.ts.map +0 -1
  45. package/dist/components/header-navigation/header-navigation-content.js +0 -22
  46. package/dist/components/header-navigation/header-navigation-content.js.map +0 -1
  47. package/dist/components/header-navigation/header-navigation-extra-stacked.stories.d.ts +0 -9
  48. package/dist/components/header-navigation/header-navigation-extra-stacked.stories.d.ts.map +0 -1
  49. package/dist/components/header-navigation/header-navigation-extra-stacked.stories.js +0 -13
  50. package/dist/components/header-navigation/header-navigation-extra-stacked.stories.js.map +0 -1
  51. package/dist/components/header-navigation/header-navigation-extra.stories.d.ts +0 -12
  52. package/dist/components/header-navigation/header-navigation-extra.stories.d.ts.map +0 -1
  53. package/dist/components/header-navigation/header-navigation-extra.stories.js +0 -29
  54. package/dist/components/header-navigation/header-navigation-extra.stories.js.map +0 -1
  55. package/dist/components/header-navigation/header-navigation-links.d.ts +0 -11
  56. package/dist/components/header-navigation/header-navigation-links.d.ts.map +0 -1
  57. package/dist/components/header-navigation/header-navigation-links.js +0 -26
  58. package/dist/components/header-navigation/header-navigation-links.js.map +0 -1
  59. package/dist/components/header-navigation/header-navigation-stacked.stories.d.ts +0 -12
  60. package/dist/components/header-navigation/header-navigation-stacked.stories.d.ts.map +0 -1
  61. package/dist/components/header-navigation/header-navigation-stacked.stories.js +0 -50
  62. package/dist/components/header-navigation/header-navigation-stacked.stories.js.map +0 -1
  63. package/dist/components/header-navigation/header-navigation-stories.module.less +0 -6
  64. package/dist/components/header-navigation/header-navigation.d.ts +0 -59
  65. package/dist/components/header-navigation/header-navigation.d.ts.map +0 -1
  66. package/dist/components/header-navigation/header-navigation.js +0 -96
  67. package/dist/components/header-navigation/header-navigation.js.map +0 -1
  68. package/dist/components/header-navigation/header-navigation.module.less +0 -260
  69. package/dist/components/header-navigation/header-navigation.stories.d.ts +0 -12
  70. package/dist/components/header-navigation/header-navigation.stories.d.ts.map +0 -1
  71. package/dist/components/header-navigation/header-navigation.stories.js +0 -54
  72. package/dist/components/header-navigation/header-navigation.stories.js.map +0 -1
  73. package/dist/components/header-navigation/index.d.ts +0 -2
  74. package/dist/components/header-navigation/index.d.ts.map +0 -1
  75. package/dist/components/header-navigation/index.js +0 -2
  76. package/dist/components/header-navigation/index.js.map +0 -1
  77. package/dist/components/header-navigation/with-tooltip.d.ts +0 -4
  78. package/dist/components/header-navigation/with-tooltip.d.ts.map +0 -1
  79. package/dist/components/header-navigation/with-tooltip.js +0 -4
  80. package/dist/components/header-navigation/with-tooltip.js.map +0 -1
  81. package/dist/components/layout.stories.d.ts +0 -13
  82. package/dist/components/layout.stories.d.ts.map +0 -1
  83. package/dist/components/layout.stories.js +0 -29
  84. package/dist/components/layout.stories.js.map +0 -1
  85. package/dist/components/left-navigation/header-navigation-extra-tiny.stories.d.ts +0 -9
  86. package/dist/components/left-navigation/header-navigation-extra-tiny.stories.d.ts.map +0 -1
  87. package/dist/components/left-navigation/header-navigation-extra-tiny.stories.js +0 -13
  88. package/dist/components/left-navigation/header-navigation-extra-tiny.stories.js.map +0 -1
  89. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts +0 -18
  90. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts.map +0 -1
  91. package/dist/components/left-navigation/header-navigation-tiny-links.js +0 -32
  92. package/dist/components/left-navigation/header-navigation-tiny-links.js.map +0 -1
  93. package/dist/components/left-navigation/header-navigation-tiny.d.ts +0 -23
  94. package/dist/components/left-navigation/header-navigation-tiny.d.ts.map +0 -1
  95. package/dist/components/left-navigation/header-navigation-tiny.js +0 -7
  96. package/dist/components/left-navigation/header-navigation-tiny.js.map +0 -1
  97. package/dist/components/left-navigation/header-navigation-tiny.stories.d.ts +0 -12
  98. package/dist/components/left-navigation/header-navigation-tiny.stories.d.ts.map +0 -1
  99. package/dist/components/left-navigation/header-navigation-tiny.stories.js +0 -30
  100. package/dist/components/left-navigation/header-navigation-tiny.stories.js.map +0 -1
  101. package/dist/components/left-navigation/index.d.ts +0 -5
  102. package/dist/components/left-navigation/index.d.ts.map +0 -1
  103. package/dist/components/left-navigation/index.js +0 -5
  104. package/dist/components/left-navigation/index.js.map +0 -1
  105. package/dist/components/left-navigation/interface-internal.d.ts +0 -10
  106. package/dist/components/left-navigation/interface-internal.d.ts.map +0 -1
  107. package/dist/components/left-navigation/interface-internal.js +0 -2
  108. package/dist/components/left-navigation/interface-internal.js.map +0 -1
  109. package/dist/components/left-navigation/interface.d.ts +0 -20
  110. package/dist/components/left-navigation/interface.d.ts.map +0 -1
  111. package/dist/components/left-navigation/interface.js +0 -2
  112. package/dist/components/left-navigation/interface.js.map +0 -1
  113. package/dist/components/left-navigation/side-navigation-context.d.ts +0 -8
  114. package/dist/components/left-navigation/side-navigation-context.d.ts.map +0 -1
  115. package/dist/components/left-navigation/side-navigation-context.js +0 -7
  116. package/dist/components/left-navigation/side-navigation-context.js.map +0 -1
  117. package/dist/components/left-navigation/side-navigation-links-internal.d.ts +0 -28
  118. package/dist/components/left-navigation/side-navigation-links-internal.d.ts.map +0 -1
  119. package/dist/components/left-navigation/side-navigation-links-internal.js +0 -29
  120. package/dist/components/left-navigation/side-navigation-links-internal.js.map +0 -1
  121. package/dist/components/left-navigation/side-navigation-links.d.ts +0 -6
  122. package/dist/components/left-navigation/side-navigation-links.d.ts.map +0 -1
  123. package/dist/components/left-navigation/side-navigation-links.js +0 -27
  124. package/dist/components/left-navigation/side-navigation-links.js.map +0 -1
  125. package/dist/components/left-navigation/side-navigation.d.ts +0 -29
  126. package/dist/components/left-navigation/side-navigation.d.ts.map +0 -1
  127. package/dist/components/left-navigation/side-navigation.js +0 -182
  128. package/dist/components/left-navigation/side-navigation.js.map +0 -1
  129. package/dist/components/left-navigation/side-navigation.module.less +0 -530
  130. package/dist/components/left-navigation/side-navigation.stories.d.ts +0 -17
  131. package/dist/components/left-navigation/side-navigation.stories.d.ts.map +0 -1
  132. package/dist/components/left-navigation/side-navigation.stories.js +0 -115
  133. package/dist/components/left-navigation/side-navigation.stories.js.map +0 -1
  134. package/dist/components/left-navigation/with-tooltip.d.ts +0 -4
  135. package/dist/components/left-navigation/with-tooltip.d.ts.map +0 -1
  136. package/dist/components/left-navigation/with-tooltip.js +0 -4
  137. package/dist/components/left-navigation/with-tooltip.js.map +0 -1
  138. package/dist/components/links.d.ts +0 -5
  139. package/dist/components/links.d.ts.map +0 -1
  140. package/dist/components/links.js +0 -14
  141. package/dist/components/links.js.map +0 -1
  142. package/dist/components/logo/logo-company-title.d.ts +0 -7
  143. package/dist/components/logo/logo-company-title.d.ts.map +0 -1
  144. package/dist/components/logo/logo-company-title.js +0 -6
  145. package/dist/components/logo/logo-company-title.js.map +0 -1
  146. package/dist/components/logo/logo-titan-text.d.ts +0 -29
  147. package/dist/components/logo/logo-titan-text.d.ts.map +0 -1
  148. package/dist/components/logo/logo-titan-text.js +0 -13
  149. package/dist/components/logo/logo-titan-text.js.map +0 -1
  150. package/dist/components/logo/logo-titan-text.module.less +0 -31
  151. package/dist/components/logo/logo-titan.d.ts +0 -9
  152. package/dist/components/logo/logo-titan.d.ts.map +0 -1
  153. package/dist/components/logo/logo-titan.js +0 -13
  154. package/dist/components/logo/logo-titan.js.map +0 -1
  155. package/dist/components/logo/logo.stories.d.ts +0 -14
  156. package/dist/components/logo/logo.stories.d.ts.map +0 -1
  157. package/dist/components/logo/logo.stories.js +0 -20
  158. package/dist/components/logo/logo.stories.js.map +0 -1
  159. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.d.ts +0 -9
  160. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.d.ts.map +0 -1
  161. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.js +0 -13
  162. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.js.map +0 -1
  163. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.d.ts +0 -9
  164. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.d.ts.map +0 -1
  165. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.js +0 -13
  166. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.js.map +0 -1
  167. package/dist/components/profile-dropdown/profile-dropdown.d.ts +0 -74
  168. package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +0 -1
  169. package/dist/components/profile-dropdown/profile-dropdown.js +0 -86
  170. package/dist/components/profile-dropdown/profile-dropdown.js.map +0 -1
  171. package/dist/components/profile-dropdown/profile-dropdown.module.less +0 -167
  172. package/dist/components/profile-dropdown/profile-dropdown.stories.d.ts +0 -16
  173. package/dist/components/profile-dropdown/profile-dropdown.stories.d.ts.map +0 -1
  174. package/dist/components/profile-dropdown/profile-dropdown.stories.js +0 -51
  175. package/dist/components/profile-dropdown/profile-dropdown.stories.js.map +0 -1
  176. package/dist/components/profile-dropdown/profile-icon.d.ts +0 -3
  177. package/dist/components/profile-dropdown/profile-icon.d.ts.map +0 -1
  178. package/dist/components/profile-dropdown/profile-icon.js +0 -5
  179. package/dist/components/profile-dropdown/profile-icon.js.map +0 -1
  180. package/dist/index.d.ts +0 -12
  181. package/dist/index.d.ts.map +0 -1
  182. package/dist/index.js +0 -12
  183. package/dist/index.js.map +0 -1
  184. package/dist/test/data-stories.module.less +0 -8
  185. package/dist/test/data.d.ts +0 -32
  186. package/dist/test/data.d.ts.map +0 -1
  187. package/dist/test/data.js +0 -244
  188. package/dist/test/data.js.map +0 -1
  189. package/dist/utils/counter-tag.d.ts +0 -5
  190. package/dist/utils/counter-tag.d.ts.map +0 -1
  191. package/dist/utils/counter-tag.js +0 -2
  192. package/dist/utils/counter-tag.js.map +0 -1
  193. package/dist/utils/navigation-context.d.ts +0 -27
  194. package/dist/utils/navigation-context.d.ts.map +0 -1
  195. package/dist/utils/navigation-context.js +0 -10
  196. package/dist/utils/navigation-context.js.map +0 -1
  197. package/dist/utils/navigation-legacy.d.ts +0 -86
  198. package/dist/utils/navigation-legacy.d.ts.map +0 -1
  199. package/dist/utils/navigation-legacy.js +0 -2
  200. package/dist/utils/navigation-legacy.js.map +0 -1
  201. package/dist/utils/navigation.d.ts +0 -48
  202. package/dist/utils/navigation.d.ts.map +0 -1
  203. package/dist/utils/navigation.js +0 -2
  204. package/dist/utils/navigation.js.map +0 -1
  205. package/dist/utils/side-nav.d.ts +0 -6
  206. package/dist/utils/side-nav.d.ts.map +0 -1
  207. package/dist/utils/side-nav.js +0 -28
  208. package/dist/utils/side-nav.js.map +0 -1
  209. package/src/components/header-navigation/header-navigation-stories.module.less.d.ts +0 -3
  210. package/src/components/header-navigation/header-navigation.module.less.d.ts +0 -22
  211. package/src/components/left-navigation/header-navigation-tiny.module.less.d.ts +0 -15
  212. package/src/components/left-navigation/side-navigation.module.less.d.ts +0 -48
  213. package/src/components/logo/logo-titan-text.module.less.d.ts +0 -6
  214. package/src/components/profile-dropdown/profile-dropdown.module.less.d.ts +0 -21
  215. package/src/test/data-stories.module.less.d.ts +0 -3
@@ -0,0 +1,144 @@
1
+ import { Icon, IconProps } from '@servicetitan/anvil2';
2
+ import classNames from 'classnames';
3
+ import { FC, Fragment } from 'react';
4
+ import {
5
+ HeaderNavigationLinkProps,
6
+ HeaderNavigationTriggerProps,
7
+ } from '../../utils/navigation-legacy';
8
+ import { getCounterTag } from '../../utils/side-nav';
9
+ import { CounterTag, CounterTagProps } from '../counter-tag';
10
+ // use v1 tooltips due to bug with v2 in monolith
11
+ import { withTooltip } from '../header-navigation/with-tooltip';
12
+ import { useTitanLayoutContext } from './layout-context';
13
+ import * as Styles from './layout-header.module.less';
14
+
15
+ /** Content for navigation items */
16
+ const HeaderNavigationItemContent: FC<{
17
+ tag?: CounterTagProps;
18
+ counterClassName?: string;
19
+ icon: IconProps['svg'] | undefined;
20
+ iconActive?: IconProps['svg'];
21
+ label?: string;
22
+ labelClassName?: string;
23
+ }> = ({ counterClassName, icon, iconActive, label, labelClassName, tag }) => {
24
+ return (
25
+ <Fragment>
26
+ {!!icon && <Icon svg={icon} className={Styles.navigationIcon} />}
27
+ {!!iconActive && (
28
+ <Icon
29
+ svg={iconActive}
30
+ className={classNames(Styles.navigationIcon, Styles.navigationIconActive)}
31
+ />
32
+ )}
33
+
34
+ {!!label && (
35
+ <span className={classNames(Styles.navigationItemLabel, labelClassName)}>
36
+ {label}
37
+ </span>
38
+ )}
39
+
40
+ {!!tag && (
41
+ <CounterTag
42
+ data={tag}
43
+ className={classNames(Styles.navigationItemCounter, counterClassName)}
44
+ longClassName={Styles.navigationItemCounterLong}
45
+ />
46
+ )}
47
+ </Fragment>
48
+ );
49
+ };
50
+
51
+ /** Navigation extra item with link */
52
+ export const LayoutHeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
53
+ id,
54
+ to,
55
+ hint,
56
+ tooltip,
57
+ className,
58
+ counter,
59
+ icon,
60
+ iconActive,
61
+ iconClassName,
62
+ iconComponent,
63
+ iconName,
64
+ isActive,
65
+ label,
66
+ labelClassName,
67
+ tag,
68
+ target,
69
+ ...rest
70
+ }) => {
71
+ const { NavigationComponent } = useTitanLayoutContext();
72
+
73
+ return withTooltip(
74
+ <NavigationComponent
75
+ data-cy={`navigation-link-${id}`}
76
+ data-pendo={`navigation-link-${id}`}
77
+ {...rest}
78
+ key={id}
79
+ to={to}
80
+ title={hint}
81
+ className={classNames(Styles.navigationLink, className, {
82
+ [Styles.navigationItemActive]: isActive === true,
83
+ [Styles.navigationItemIconState]: !!icon && !!iconActive,
84
+ })}
85
+ isActive={typeof isActive === 'function' ? isActive : undefined}
86
+ activeClassName={Styles.navigationItemActive}
87
+ target={target}
88
+ >
89
+ <HeaderNavigationItemContent
90
+ tag={getCounterTag(counter, tag)}
91
+ icon={icon}
92
+ iconActive={iconActive}
93
+ label={label}
94
+ labelClassName={labelClassName}
95
+ />
96
+ </NavigationComponent>,
97
+ tooltip
98
+ );
99
+ };
100
+
101
+ /** Navigation extra item with icon button */
102
+ export const LayoutHeaderNavigationTrigger: FC<HeaderNavigationTriggerProps> = ({
103
+ id,
104
+ className,
105
+ counter,
106
+ icon,
107
+ iconActive,
108
+ iconName,
109
+ isActive,
110
+ hint,
111
+ label,
112
+ labelClassName,
113
+ tag,
114
+ tooltip,
115
+ title,
116
+ titleClassName,
117
+ ...rest
118
+ }) => {
119
+ return withTooltip(
120
+ <div
121
+ data-cy={`navigation-trigger-${id}`}
122
+ data-pendo={`navigation-trigger-${id}`}
123
+ {...rest}
124
+ title={hint}
125
+ className={classNames(
126
+ Styles.navigationLink,
127
+ {
128
+ [Styles.navigationItemActive]: isActive === true,
129
+ [Styles.navigationItemIconState]: !!icon && !!iconActive,
130
+ },
131
+ 'cursor-pointer',
132
+ className
133
+ )}
134
+ >
135
+ <HeaderNavigationItemContent
136
+ tag={getCounterTag(counter, tag)}
137
+ icon={isActive && iconActive ? iconActive : icon}
138
+ label={label}
139
+ labelClassName={labelClassName}
140
+ />
141
+ </div>,
142
+ tooltip
143
+ );
144
+ };
@@ -3,10 +3,8 @@
3
3
 
4
4
  @size-links-tiny: 24px;
5
5
 
6
- .header-tiny {
6
+ .header {
7
7
  display: grid;
8
- grid-template-columns: repeat(3, 1fr);
9
- grid-template-rows: 48px;
10
8
 
11
9
  background-color: @color-white;
12
10
  color: @color-black;
@@ -17,6 +15,8 @@
17
15
 
18
16
  .he-top-left {
19
17
  grid-column: span 1;
18
+ display: flex;
19
+ align-items: center;
20
20
  }
21
21
 
22
22
  .he-top-center {
@@ -29,6 +29,13 @@
29
29
  & > * {
30
30
  color: @color-black;
31
31
  }
32
+
33
+ .he-top-right-text {
34
+ font-size: @typescale-2;
35
+ font-weight: @font-weight-bold;
36
+ font-family: @base-font-family;
37
+ margin-right: @spacing-1;
38
+ }
32
39
  }
33
40
 
34
41
  :global(.profile-dropdown-image) {
@@ -42,8 +49,6 @@
42
49
  }
43
50
 
44
51
  .navigation-link {
45
- margin: 6px 2px;
46
- padding: 6px 6px;
47
52
  border-radius: 12px;
48
53
  font-size: @size-links-tiny;
49
54
  color: inherit;
@@ -84,6 +89,37 @@
84
89
  }
85
90
  }
86
91
 
92
+ // desktop
93
+ @media only screen and (min-width: 768px) {
94
+ .header {
95
+ grid-template-columns: repeat(3, 1fr);
96
+ grid-template-rows: 48px;
97
+
98
+ .navigation-link {
99
+ margin: 6px 2px;
100
+ padding: 6px 6px;
101
+ }
102
+ }
103
+
104
+ .he-top-left {
105
+ padding-left: @spacing-1;
106
+ }
107
+ }
108
+
109
+ // mobile
110
+ @media only screen and (max-width: 768px) {
111
+ .header {
112
+ grid-template-columns: repeat(3, 1fr);
113
+ grid-template-rows: 44px;
114
+
115
+ padding: @spacing-1 @spacing-half;
116
+
117
+ .navigation-link {
118
+ padding: 10px;
119
+ }
120
+ }
121
+ }
122
+
87
123
  .navigation-link {
88
124
  // styles specific to extra nav links
89
125
  color: @color-black;
@@ -0,0 +1,86 @@
1
+ import SvgBurgerMenu from '@servicetitan/anvil2/assets/icons/material/round/menu.svg';
2
+ import classNames from 'classnames';
3
+ import { ComponentPropsWithoutRef, FC, ReactElement, ReactNode } from 'react';
4
+ import { LayoutPlacementContext, useTitanLayoutContext } from './layout-context';
5
+ import { LayoutHeaderNavigationTrigger } from './layout-header-links';
6
+ import * as Styles from './layout-header.module.less';
7
+ import { TitanLayoutLogoProps } from './layout-logo';
8
+
9
+ export interface TitanLayoutHeaderLogoProps {
10
+ title?: true | string;
11
+ mantleFill?: string;
12
+ to?: string;
13
+ }
14
+
15
+ export type LayoutHeaderProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'> & {
16
+ right?: ReactNode;
17
+ rightText?: string;
18
+ rightClassName?: string;
19
+
20
+ id?: string;
21
+
22
+ center?: ReactElement;
23
+ centerClassName?: string;
24
+
25
+ logo: ReactElement<TitanLayoutLogoProps>;
26
+ profile?: ReactElement;
27
+
28
+ onBurgerClick?: (e: MouseEvent) => void;
29
+ };
30
+
31
+ export const LayoutHeader: FC<LayoutHeaderProps> = ({
32
+ className,
33
+ right,
34
+ rightText,
35
+ rightClassName,
36
+ center,
37
+ centerClassName,
38
+ logo,
39
+ profile,
40
+ onBurgerClick,
41
+ ...rest
42
+ }) => {
43
+ const { breakpoint } = useTitanLayoutContext();
44
+
45
+ return (
46
+ <LayoutPlacementContext.Provider value="top">
47
+ <div
48
+ className={classNames(Styles.header, className)}
49
+ {...rest}
50
+ data-cy="header-navigation"
51
+ >
52
+ <div className={classNames(Styles.heTopLeft)} data-cy="navigation-left">
53
+ {breakpoint.isMobile && (
54
+ <LayoutHeaderNavigationTrigger
55
+ id="burger"
56
+ title=""
57
+ icon={SvgBurgerMenu}
58
+ iconActive={SvgBurgerMenu}
59
+ className="m-r-1"
60
+ onClick={onBurgerClick}
61
+ />
62
+ )}
63
+ {logo}
64
+ </div>
65
+ <div
66
+ className={classNames(Styles.heTopCenter, centerClassName)}
67
+ data-cy="navigation-center"
68
+ >
69
+ {center}
70
+ </div>
71
+ <div
72
+ className={classNames(
73
+ 'd-f flex-row justify-content-end align-items-center',
74
+ Styles.heTopRight,
75
+ rightClassName
76
+ )}
77
+ data-cy="navigation-right"
78
+ >
79
+ {!!rightText && <div className={Styles.heTopRightText}>{rightText}</div>}
80
+ {right}
81
+ {profile}
82
+ </div>
83
+ </div>
84
+ </LayoutPlacementContext.Provider>
85
+ );
86
+ };
@@ -0,0 +1,31 @@
1
+ import { Chip } from '@servicetitan/anvil2';
2
+ import { ReactElement } from 'react';
3
+ import { withAnvil, withDefaultRedirects, withMemoryRouter } from '../../test/data';
4
+ import { TitanLayoutLogo, TitanLayoutLogoProps } from './layout-logo';
5
+ import { TitanLayout } from './titan-layout';
6
+
7
+ const withTitanLayout = (element: ReactElement<TitanLayoutLogoProps>) => () => (
8
+ <TitanLayout navigationMainItems={[]}>
9
+ {element}
10
+ <TitanLayout.Content>logo</TitanLayout.Content>
11
+ </TitanLayout>
12
+ );
13
+
14
+ export default {
15
+ title: 'Navigation/TitanLayoutLogo',
16
+ component: TitanLayoutLogo,
17
+ decorators: [withDefaultRedirects, withMemoryRouter, withAnvil],
18
+ parameters: {},
19
+ };
20
+
21
+ export const LogoDefault = withTitanLayout(<TitanLayoutLogo />);
22
+
23
+ export const LogoCompanyTitle = withTitanLayout(<TitanLayoutLogo title />);
24
+
25
+ export const LogoCommercial = withTitanLayout(
26
+ <TitanLayoutLogo title="Commercial" mantleFill="#2270EE" />
27
+ );
28
+
29
+ export const LogoWithPostfix = withTitanLayout(
30
+ <TitanLayoutLogo title postfix={<Chip className="m-l-2-i" label="demo" />} />
31
+ );
@@ -0,0 +1,57 @@
1
+ import classNames from 'classnames';
2
+ import { FC, Fragment, ReactNode } from 'react';
3
+ import { LogoCompanyTitle } from '../logo/logo-company-title';
4
+ import { LogoTitan, LogoTitanTitle, WrapperProps } from '../logo/logo-titan-text';
5
+ import { useTitanLayoutContext } from './layout-context';
6
+
7
+ export interface TitanLayoutLogoProps {
8
+ /** container class name */
9
+ className?: string;
10
+
11
+ title?: string | boolean;
12
+
13
+ postfix?: ReactNode;
14
+
15
+ logoWrapper?: WrapperProps;
16
+
17
+ mantleFill?: string;
18
+ }
19
+
20
+ const EmptyWrapper: FC<any> = ({ children }) => children;
21
+
22
+ export const TitanLayoutLogo: FC<TitanLayoutLogoProps> = ({
23
+ className,
24
+ mantleFill,
25
+ postfix,
26
+ title,
27
+ logoWrapper = EmptyWrapper,
28
+ }) => {
29
+ const {
30
+ breakpoint: { isMobile },
31
+ } = useTitanLayoutContext();
32
+
33
+ const Wrapper = logoWrapper;
34
+ const logoSize = isMobile ? 44 : 56;
35
+ const logoCompanySize = 48;
36
+
37
+ return (
38
+ <div className={classNames('d-f align-items-center', className)}>
39
+ {typeof title === 'string' ? (
40
+ <Fragment>
41
+ <LogoTitan size={logoSize} mantleFill={mantleFill} logoWrapper={Wrapper} />
42
+ {!isMobile && (
43
+ <LogoTitanTitle className="c-inherit m-l-1">{title}</LogoTitanTitle>
44
+ )}
45
+ </Fragment>
46
+ ) : title === true && !isMobile ? (
47
+ <Wrapper className="">
48
+ <LogoCompanyTitle height={logoCompanySize} />
49
+ </Wrapper>
50
+ ) : (
51
+ <LogoTitan size={logoSize} mantleFill={mantleFill} logoWrapper={Wrapper} />
52
+ )}
53
+
54
+ {!isMobile && postfix}
55
+ </div>
56
+ );
57
+ };
@@ -0,0 +1,37 @@
1
+ import { ReactElement } from 'react';
2
+ import { withAnvil, withDefaultRedirects, withMemoryRouter } from '../../test/data';
3
+ import { ProfileDropdown } from './layout-profile';
4
+ import { TitanLayout } from './titan-layout';
5
+
6
+ const withTitanLayout = (element: ReactElement) => () => (
7
+ <TitanLayout navigationMainItems={[]} profile={element}>
8
+ <TitanLayout.Content>profile</TitanLayout.Content>
9
+ </TitanLayout>
10
+ );
11
+
12
+ export default {
13
+ title: 'Navigation/TitanLayoutProfile',
14
+ component: ProfileDropdown,
15
+ decorators: [withDefaultRedirects, withMemoryRouter, withAnvil],
16
+ parameters: {},
17
+ };
18
+
19
+ export const ProfileDefault = withTitanLayout(
20
+ <ProfileDropdown>
21
+ <ProfileDropdown.Link id="first" to="https://google.com">
22
+ first link
23
+ </ProfileDropdown.Link>
24
+ <ProfileDropdown.Section id="second" onClick={() => alert('second click')}>
25
+ 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">
33
+ third link
34
+ </ProfileDropdown.Link>
35
+ <ProfileDropdown.Divider />
36
+ </ProfileDropdown>
37
+ );
@@ -0,0 +1,116 @@
1
+ import SvgAccountActive from '@servicetitan/anvil2/assets/icons/st/gnav_account_active.svg';
2
+ import SvgAccountInactive from '@servicetitan/anvil2/assets/icons/st/gnav_account_inactive.svg';
3
+
4
+ import { FC, useState } from 'react';
5
+ import { NavigationComponentContext } from '../../utils/navigation-context';
6
+ import {
7
+ ProfileDropdown as DesktopProfileDropdown,
8
+ ProfileDropdownLinkProps,
9
+ ProfileDropdownProps,
10
+ ProfileDropdownSectionProps,
11
+ } from '../profile-dropdown/profile-dropdown';
12
+ import { NavigationComponentProps } from './interface-internal';
13
+ import { useTitanLayoutContext } from './layout-context';
14
+ import {
15
+ InternalSideNavigationGroup,
16
+ InternalSideNavigationGroupDivider,
17
+ InternalSideNavigationGroupLink,
18
+ InternalSideNavigationGroupTrigger,
19
+ } from './layout-sidebar-links-internal';
20
+
21
+ export type {
22
+ ProfileDropdownProps,
23
+ ProfileDropdownSectionProps,
24
+ ProfileDropdownLinkProps,
25
+ } from '../profile-dropdown/profile-dropdown';
26
+
27
+ const ProfileDropdownContent: FC<ProfileDropdownProps> = props => {
28
+ const { breakpoint, NavigationComponent } = useTitanLayoutContext();
29
+ return breakpoint.isMobile ? (
30
+ <MobileProfileDropdown {...props} navigationComponent={NavigationComponent} />
31
+ ) : (
32
+ <NavigationComponentContext.Provider value={NavigationComponent}>
33
+ <DesktopProfileDropdown {...props} />
34
+ </NavigationComponentContext.Provider>
35
+ );
36
+ };
37
+ ProfileDropdownContent.displayName = 'ProfileDropdown';
38
+
39
+ const MobileProfileDropdown: FC<ProfileDropdownProps & NavigationComponentProps> = ({
40
+ children,
41
+ ...props
42
+ }) => {
43
+ const [expanded, setExpanded] = useState(false);
44
+ const onExpandToggle = () => setExpanded(!expanded);
45
+ return (
46
+ <InternalSideNavigationGroup
47
+ id="__profile"
48
+ to={undefined}
49
+ title="Profile"
50
+ icon={SvgAccountInactive}
51
+ iconActive={SvgAccountActive}
52
+ isActive={expanded}
53
+ {...props}
54
+ submenuExpanded={expanded}
55
+ onExpandToggle={onExpandToggle}
56
+ onClick={onExpandToggle}
57
+ tag={undefined}
58
+ >
59
+ {children}
60
+ </InternalSideNavigationGroup>
61
+ );
62
+ };
63
+
64
+ const ProfileDropdownDivider: FC = () => {
65
+ const { breakpoint } = useTitanLayoutContext();
66
+ return breakpoint.isMobile ? (
67
+ <InternalSideNavigationGroupDivider />
68
+ ) : (
69
+ <DesktopProfileDropdown.Divider />
70
+ );
71
+ };
72
+
73
+ const ProfileDropdownSection: FC<ProfileDropdownSectionProps> = props => {
74
+ const { breakpoint } = useTitanLayoutContext();
75
+ return breakpoint.isMobile ? (
76
+ <MobileProfileDropdownSection {...props} />
77
+ ) : (
78
+ <DesktopProfileDropdown.Section {...props} />
79
+ );
80
+ };
81
+ const MobileProfileDropdownSection: FC<ProfileDropdownSectionProps> = props => {
82
+ const title = typeof props.children === 'string' ? props.children : undefined;
83
+ return title ? (
84
+ <InternalSideNavigationGroupTrigger id={props.id} title={title} onClick={props.onClick} />
85
+ ) : null;
86
+ };
87
+
88
+ const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = props => {
89
+ const { breakpoint, NavigationComponent } = useTitanLayoutContext();
90
+ return breakpoint.isMobile ? (
91
+ <MobileProfileDropdownLink {...props} navigationComponent={NavigationComponent} />
92
+ ) : (
93
+ <DesktopProfileDropdown.Link {...props} />
94
+ );
95
+ };
96
+ const MobileProfileDropdownLink: FC<ProfileDropdownLinkProps & NavigationComponentProps> = ({
97
+ to,
98
+ navigationComponent,
99
+ ...props
100
+ }) => {
101
+ const title = typeof props.children === 'string' ? props.children : undefined;
102
+ return title ? (
103
+ <InternalSideNavigationGroupLink
104
+ {...props}
105
+ to={to}
106
+ title={title}
107
+ navigationComponent={navigationComponent}
108
+ />
109
+ ) : null;
110
+ };
111
+
112
+ export const ProfileDropdown = Object.assign(ProfileDropdownContent, {
113
+ Divider: ProfileDropdownDivider,
114
+ Link: ProfileDropdownLink,
115
+ Section: ProfileDropdownSection,
116
+ });