@servicetitan/navigation 10.7.0 → 11.0.0-canary.237.0a4df1d.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 (162) hide show
  1. package/dist/components/badge-tag.d.ts +1 -1
  2. package/dist/components/badge-tag.d.ts.map +1 -1
  3. package/dist/components/header-navigation/header-navigation-extra.stories.d.ts.map +1 -1
  4. package/dist/components/header-navigation/header-navigation-extra.stories.js +5 -5
  5. package/dist/components/header-navigation/header-navigation-extra.stories.js.map +1 -1
  6. package/dist/components/header-navigation/header-navigation-links.d.ts.map +1 -1
  7. package/dist/components/header-navigation/header-navigation-links.js +2 -2
  8. package/dist/components/header-navigation/header-navigation-links.js.map +1 -1
  9. package/dist/components/header-navigation/header-navigation-stacked.stories.d.ts.map +1 -1
  10. package/dist/components/header-navigation/header-navigation-stacked.stories.js +1 -1
  11. package/dist/components/header-navigation/header-navigation-stacked.stories.js.map +1 -1
  12. package/dist/components/header-navigation/header-navigation.stories.d.ts.map +1 -1
  13. package/dist/components/header-navigation/header-navigation.stories.js +2 -2
  14. package/dist/components/header-navigation/header-navigation.stories.js.map +1 -1
  15. package/dist/components/header-navigation/with-tooltip.d.ts +1 -1
  16. package/dist/components/header-navigation/with-tooltip.d.ts.map +1 -1
  17. package/dist/components/left-navigation/header-navigation-tiny.stories.d.ts.map +1 -1
  18. package/dist/components/left-navigation/header-navigation-tiny.stories.js +2 -2
  19. package/dist/components/left-navigation/header-navigation-tiny.stories.js.map +1 -1
  20. package/dist/components/links.d.ts.map +1 -1
  21. package/dist/components/links.js +7 -7
  22. package/dist/components/links.js.map +1 -1
  23. package/dist/components/logo/logo-company-title.d.ts +1 -0
  24. package/dist/components/logo/logo-company-title.d.ts.map +1 -1
  25. package/dist/components/logo/logo-company-title.js +2 -2
  26. package/dist/components/logo/logo-company-title.js.map +1 -1
  27. package/dist/components/logo/logo-titan-text.d.ts +1 -1
  28. package/dist/components/logo/logo-titan-text.d.ts.map +1 -1
  29. package/dist/components/profile-dropdown/profile-dropdown.d.ts +17 -9
  30. package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
  31. package/dist/components/profile-dropdown/profile-dropdown.js +11 -9
  32. package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
  33. package/dist/components/profile-dropdown/profile-dropdown.module.less +24 -6
  34. package/dist/components/profile-dropdown/profile-dropdown.stories.js +2 -2
  35. package/dist/components/profile-dropdown/profile-dropdown.stories.js.map +1 -1
  36. package/dist/components/titan-layout/index.d.ts +6 -0
  37. package/dist/components/titan-layout/index.d.ts.map +1 -0
  38. package/dist/components/titan-layout/index.js +6 -0
  39. package/dist/components/titan-layout/index.js.map +1 -0
  40. package/dist/components/titan-layout/interface-internal.d.ts +6 -0
  41. package/dist/components/titan-layout/interface-internal.d.ts.map +1 -0
  42. package/dist/components/titan-layout/interface-internal.js +2 -0
  43. package/dist/components/titan-layout/interface-internal.js.map +1 -0
  44. package/dist/components/titan-layout/interface.d.ts +21 -0
  45. package/dist/components/titan-layout/interface.d.ts.map +1 -0
  46. package/dist/components/titan-layout/interface.js +2 -0
  47. package/dist/components/titan-layout/interface.js.map +1 -0
  48. package/dist/components/titan-layout/layout-context.d.ts +20 -0
  49. package/dist/components/titan-layout/layout-context.d.ts.map +1 -0
  50. package/dist/components/titan-layout/layout-context.js +12 -0
  51. package/dist/components/titan-layout/layout-context.js.map +1 -0
  52. package/dist/components/titan-layout/layout-header-links.d.ts +7 -0
  53. package/dist/components/titan-layout/layout-header-links.d.ts.map +1 -0
  54. package/dist/components/titan-layout/layout-header-links.js +32 -0
  55. package/dist/components/titan-layout/layout-header-links.js.map +1 -0
  56. package/dist/components/titan-layout/layout-header.d.ts +22 -0
  57. package/dist/components/titan-layout/layout-header.d.ts.map +1 -0
  58. package/dist/components/titan-layout/layout-header.js +10 -0
  59. package/dist/components/titan-layout/layout-header.js.map +1 -0
  60. package/dist/components/titan-layout/layout-header.module.less +193 -0
  61. package/dist/components/titan-layout/layout-logo.d.ts +12 -0
  62. package/dist/components/titan-layout/layout-logo.d.ts.map +1 -0
  63. package/dist/components/titan-layout/layout-logo.js +16 -0
  64. package/dist/components/titan-layout/layout-logo.js.map +1 -0
  65. package/dist/components/titan-layout/layout-logo.stories.d.ts +13 -0
  66. package/dist/components/titan-layout/layout-logo.stories.d.ts.map +1 -0
  67. package/dist/components/titan-layout/layout-logo.stories.js +17 -0
  68. package/dist/components/titan-layout/layout-logo.stories.js.map +1 -0
  69. package/dist/components/titan-layout/layout-profile.d.ts +9 -0
  70. package/dist/components/titan-layout/layout-profile.d.ts.map +1 -0
  71. package/dist/components/titan-layout/layout-profile.js +72 -0
  72. package/dist/components/titan-layout/layout-profile.js.map +1 -0
  73. package/dist/components/titan-layout/layout-profile.stories.d.ts +13 -0
  74. package/dist/components/titan-layout/layout-profile.stories.d.ts.map +1 -0
  75. package/dist/components/titan-layout/layout-profile.stories.js +13 -0
  76. package/dist/components/titan-layout/layout-profile.stories.js.map +1 -0
  77. package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts +46 -0
  78. package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts.map +1 -0
  79. package/dist/components/titan-layout/layout-sidebar-links-internal.js +61 -0
  80. package/dist/components/titan-layout/layout-sidebar-links-internal.js.map +1 -0
  81. package/dist/components/titan-layout/layout-sidebar-links.d.ts +6 -0
  82. package/dist/components/titan-layout/layout-sidebar-links.d.ts.map +1 -0
  83. package/dist/components/titan-layout/layout-sidebar-links.js +28 -0
  84. package/dist/components/titan-layout/layout-sidebar-links.js.map +1 -0
  85. package/dist/components/titan-layout/layout-sidebar.d.ts +19 -0
  86. package/dist/components/titan-layout/layout-sidebar.d.ts.map +1 -0
  87. package/dist/components/titan-layout/layout-sidebar.js +67 -0
  88. package/dist/components/titan-layout/layout-sidebar.js.map +1 -0
  89. package/dist/components/titan-layout/layout-sidebar.module.less +536 -0
  90. package/dist/components/titan-layout/notifications-context.d.ts +13 -0
  91. package/dist/components/titan-layout/notifications-context.d.ts.map +1 -0
  92. package/dist/components/titan-layout/notifications-context.js +23 -0
  93. package/dist/components/titan-layout/notifications-context.js.map +1 -0
  94. package/dist/components/titan-layout/titan-layout.d.ts +40 -0
  95. package/dist/components/titan-layout/titan-layout.d.ts.map +1 -0
  96. package/dist/components/titan-layout/titan-layout.js +192 -0
  97. package/dist/components/titan-layout/titan-layout.js.map +1 -0
  98. package/dist/components/titan-layout/titan-layout.module.less +106 -0
  99. package/dist/components/titan-layout/titan-layout.stories.d.ts +22 -0
  100. package/dist/components/titan-layout/titan-layout.stories.d.ts.map +1 -0
  101. package/dist/components/titan-layout/titan-layout.stories.js +83 -0
  102. package/dist/components/titan-layout/titan-layout.stories.js.map +1 -0
  103. package/dist/components/titan-layout/with-tooltip.d.ts +4 -0
  104. package/dist/components/titan-layout/with-tooltip.d.ts.map +1 -0
  105. package/dist/components/titan-layout/with-tooltip.js +4 -0
  106. package/dist/components/titan-layout/with-tooltip.js.map +1 -0
  107. package/dist/index.d.ts +2 -1
  108. package/dist/index.d.ts.map +1 -1
  109. package/dist/index.js +2 -1
  110. package/dist/index.js.map +1 -1
  111. package/dist/test/data.d.ts +4 -1
  112. package/dist/test/data.d.ts.map +1 -1
  113. package/dist/test/data.js +5 -6
  114. package/dist/test/data.js.map +1 -1
  115. package/dist/utils/navigation-legacy.d.ts +3 -1
  116. package/dist/utils/navigation-legacy.d.ts.map +1 -1
  117. package/dist/utils/use-breakpoint.d.ts +8 -0
  118. package/dist/utils/use-breakpoint.d.ts.map +1 -0
  119. package/dist/utils/use-breakpoint.js +14 -0
  120. package/dist/utils/use-breakpoint.js.map +1 -0
  121. package/package.json +5 -6
  122. package/src/components/badge-tag.tsx +1 -1
  123. package/src/components/header-navigation/header-navigation-extra.stories.tsx +7 -0
  124. package/src/components/header-navigation/header-navigation-links.tsx +2 -0
  125. package/src/components/header-navigation/header-navigation-stacked.stories.tsx +5 -1
  126. package/src/components/header-navigation/header-navigation.stories.tsx +6 -1
  127. package/src/components/left-navigation/header-navigation-tiny.stories.tsx +8 -2
  128. package/src/components/left-navigation/side-navigation-links.tsx +1 -1
  129. package/src/components/links.tsx +33 -13
  130. package/src/components/logo/logo-company-title.tsx +8 -6
  131. package/src/components/logo/logo-titan-text.tsx +1 -1
  132. package/src/components/profile-dropdown/profile-dropdown.module.less +24 -6
  133. package/src/components/profile-dropdown/profile-dropdown.module.less.d.ts +2 -0
  134. package/src/components/profile-dropdown/profile-dropdown.stories.tsx +4 -4
  135. package/src/components/profile-dropdown/profile-dropdown.tsx +87 -55
  136. package/src/components/titan-layout/index.ts +5 -0
  137. package/src/components/titan-layout/interface-internal.ts +6 -0
  138. package/src/components/titan-layout/interface.ts +26 -0
  139. package/src/components/titan-layout/layout-context.tsx +30 -0
  140. package/src/components/titan-layout/layout-header-links.tsx +145 -0
  141. package/src/components/titan-layout/layout-header.module.less +193 -0
  142. package/src/components/titan-layout/layout-header.module.less.d.ts +18 -0
  143. package/src/components/titan-layout/layout-header.tsx +97 -0
  144. package/src/components/titan-layout/layout-logo.stories.tsx +31 -0
  145. package/src/components/titan-layout/layout-logo.tsx +64 -0
  146. package/src/components/titan-layout/layout-profile.stories.tsx +46 -0
  147. package/src/components/titan-layout/layout-profile.tsx +180 -0
  148. package/src/components/titan-layout/layout-sidebar-links-internal.tsx +278 -0
  149. package/src/components/titan-layout/layout-sidebar-links.tsx +72 -0
  150. package/src/components/titan-layout/layout-sidebar.module.less +536 -0
  151. package/src/components/titan-layout/layout-sidebar.module.less.d.ts +49 -0
  152. package/src/components/titan-layout/layout-sidebar.tsx +304 -0
  153. package/src/components/titan-layout/notifications-context.tsx +44 -0
  154. package/src/components/titan-layout/titan-layout.module.less +106 -0
  155. package/src/components/titan-layout/titan-layout.module.less.d.ts +16 -0
  156. package/src/components/titan-layout/titan-layout.stories.tsx +346 -0
  157. package/src/components/titan-layout/titan-layout.tsx +457 -0
  158. package/src/components/titan-layout/with-tooltip.tsx +16 -0
  159. package/src/index.ts +2 -1
  160. package/src/test/data.tsx +5 -5
  161. package/src/utils/navigation-legacy.ts +3 -1
  162. package/src/utils/use-breakpoint.ts +21 -0
@@ -6,6 +6,7 @@ import SvgAccountInactive from '@servicetitan/anvil2/assets/icons/st/gnav_accoun
6
6
  import { BodyText, Popover, PopoverPropsStrict } from '@servicetitan/design-system';
7
7
  import classNames from 'classnames';
8
8
  import {
9
+ ComponentPropsWithoutRef,
9
10
  FC,
10
11
  HTMLAttributeAnchorTarget,
11
12
  MouseEvent,
@@ -25,6 +26,7 @@ import {
25
26
  } from '../../utils/navigation-context';
26
27
  import { getCounterTag } from '../../utils/side-nav';
27
28
  import { CounterTag } from '../counter-tag';
29
+ import { withTooltip } from '../titan-layout/with-tooltip';
28
30
  import * as Styles from './profile-dropdown.module.less';
29
31
  import { ProfileLogo } from './profile-icon';
30
32
 
@@ -146,21 +148,43 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
146
148
  );
147
149
  };
148
150
 
151
+ const useTag = (counter?: CounterTagValue, tag?: CounterTagData) =>
152
+ useMemo(() => {
153
+ const data = getCounterTag(counter, tag);
154
+
155
+ return data ? (
156
+ <div className={Styles.counterWrapper}>
157
+ <CounterTag className={Styles.counter} data={data} />
158
+ </div>
159
+ ) : undefined;
160
+ }, [counter, tag]);
161
+
162
+ export type ProfileItemContent =
163
+ | { children: string; text?: string }
164
+ | { children: ReactNode; text: string };
165
+
149
166
  export interface ProfileDropdownSectionPropsStrict {
150
167
  children: ReactNode;
151
168
  id: string;
169
+ tooltip?: string;
152
170
  className?: string;
171
+ tag?: CounterTagData;
172
+ counter?: CounterTagValue;
153
173
  onClick?(e: MouseEvent): void;
154
174
  }
155
175
 
156
- interface ProfileDropdownSectionProps extends ProfileDropdownSectionPropsStrict {
157
- [key: string]: any;
158
- }
176
+ export type ProfileDropdownSectionProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'> &
177
+ ProfileDropdownSectionPropsStrict &
178
+ ProfileItemContent;
159
179
 
160
180
  export const ProfileDropdownSection: FC<ProfileDropdownSectionProps> = ({
161
181
  children,
162
182
  className,
183
+ counter,
163
184
  id,
185
+ tag,
186
+ text,
187
+ tooltip,
164
188
  onClick,
165
189
  ...rest
166
190
  }) => {
@@ -172,16 +196,26 @@ export const ProfileDropdownSection: FC<ProfileDropdownSectionProps> = ({
172
196
  }
173
197
  };
174
198
 
175
- return (
199
+ const tagElement = useTag(counter, tag);
200
+
201
+ return withTooltip(
176
202
  <div
177
- className={classNames(Styles.dropdownSection, className)}
203
+ className={classNames(
204
+ Styles.dropdownSection,
205
+ tagElement && Styles.dropdownSectionWithCounter,
206
+ !!onClick && Styles.dropdownLink,
207
+ className
208
+ )}
178
209
  onClick={clickHandler}
179
210
  data-cy={`profile-dropdown-section-${id}`}
180
211
  data-pendo={`profile-dropdown-section-${id}`}
181
212
  {...rest}
182
213
  >
183
214
  {children}
184
- </div>
215
+ {tagElement}
216
+ </div>,
217
+ tooltip,
218
+ 'left'
185
219
  );
186
220
  };
187
221
 
@@ -193,15 +227,15 @@ export interface ProfileDropdownLinkPropsStrict {
193
227
  className?: string;
194
228
  external?: boolean;
195
229
  target?: HTMLAttributeAnchorTarget;
196
- to?: string;
230
+ tooltip?: string;
231
+ to: string;
197
232
  tag?: CounterTagData;
198
233
  counter?: CounterTagValue;
199
- onClick?: () => void;
200
234
  }
201
235
 
202
- export interface ProfileDropdownLinkProps extends ProfileDropdownLinkPropsStrict {
203
- [key: string]: any;
204
- }
236
+ export type ProfileDropdownLinkProps = Omit<ComponentPropsWithoutRef<'a'>, 'children'> &
237
+ ProfileDropdownLinkPropsStrict &
238
+ ProfileItemContent;
205
239
 
206
240
  export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
207
241
  children,
@@ -211,59 +245,56 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
211
245
  counter,
212
246
  tag,
213
247
  target,
248
+ text,
214
249
  to,
250
+ tooltip,
215
251
  onClick,
216
252
  ...rest
217
253
  }: ProfileDropdownLinkProps) => {
218
254
  const NavigationComponent = useContext(NavigationComponentContext);
219
255
 
220
- const clickHandler = (e: MouseEvent<any>) => {
221
- e.preventDefault();
222
- onClick?.();
223
- };
224
-
225
256
  const isExternalLink = external ?? to?.startsWith('http');
226
257
 
227
- const tagElement = useMemo(
228
- () => <CounterTag data={getCounterTag(counter, tag)} className={Styles.counter} />,
229
- [counter, tag]
230
- );
258
+ const tagElement = useTag(counter, tag);
231
259
 
232
- return isExternalLink ? (
233
- <a
234
- className={classNames(Styles.dropdownSection, Styles.dropdownLink, className)}
235
- href={to}
236
- target={target}
237
- data-cy={`profile-dropdown-link-${id}`}
238
- data-pendo={`profile-dropdown-link-${id}`}
239
- {...rest}
240
- >
241
- {children}
242
- {tagElement}
243
- </a>
244
- ) : to ? (
245
- <NavigationComponent
246
- className={classNames(Styles.dropdownSection, Styles.dropdownLink, className)}
247
- target={target}
248
- to={to}
249
- data-cy={`profile-dropdown-link-${id}`}
250
- data-pendo={`profile-dropdown-link-${id}`}
251
- {...rest}
252
- >
253
- {children}
254
- {tagElement}
255
- </NavigationComponent>
256
- ) : (
257
- <a
258
- className={classNames(Styles.dropdownSection, Styles.dropdownLink, className)}
259
- onClick={clickHandler}
260
- data-cy={`profile-dropdown-link-${id}`}
261
- data-pendo={`profile-dropdown-link-${id}`}
262
- {...rest}
263
- >
264
- {children}
265
- {tagElement}
266
- </a>
260
+ return withTooltip(
261
+ isExternalLink ? (
262
+ <a
263
+ className={classNames(
264
+ Styles.dropdownSection,
265
+ tagElement && Styles.dropdownSectionWithCounter,
266
+ Styles.dropdownLink,
267
+ className
268
+ )}
269
+ href={to}
270
+ target={target}
271
+ data-cy={`profile-dropdown-link-${id}`}
272
+ data-pendo={`profile-dropdown-link-${id}`}
273
+ {...rest}
274
+ >
275
+ {children}
276
+ {tagElement}
277
+ </a>
278
+ ) : (
279
+ <NavigationComponent
280
+ className={classNames(
281
+ Styles.dropdownSection,
282
+ Styles.dropdownLink,
283
+ { [Styles.dropdownSectionWithCounter]: !!tagElement },
284
+ className
285
+ )}
286
+ target={target}
287
+ to={to}
288
+ data-cy={`profile-dropdown-link-${id}`}
289
+ data-pendo={`profile-dropdown-link-${id}`}
290
+ {...rest}
291
+ >
292
+ {children}
293
+ {tagElement}
294
+ </NavigationComponent>
295
+ ),
296
+ tooltip,
297
+ 'left'
267
298
  );
268
299
  };
269
300
 
@@ -291,6 +322,7 @@ export interface ProfileDropdownProps extends ProfileDropdownPropsStrict {
291
322
  export interface ProfileDropdownType extends FC<ProfileDropdownProps> {
292
323
  Divider: typeof ProfileDropdownDivider;
293
324
  Link: typeof ProfileDropdownLink;
325
+ Trigger: typeof ProfileDropdownTrigger;
294
326
  Section: typeof ProfileDropdownSection;
295
327
  }
296
328
 
@@ -0,0 +1,5 @@
1
+ export * from './titan-layout';
2
+ export * from './layout-profile';
3
+ export * from './layout-context';
4
+ export * from './layout-logo';
5
+ export * from './interface';
@@ -0,0 +1,6 @@
1
+ import { FC } from 'react';
2
+ import { NavLinkComponentProps } from '../../utils/navigation-context';
3
+
4
+ export interface NavigationComponentProps {
5
+ navigationComponent: FC<NavLinkComponentProps>;
6
+ }
@@ -0,0 +1,26 @@
1
+ import { FC, ReactElement } from 'react';
2
+ import { NavigationItemData } from '../../utils/navigation';
3
+ import { TitanLayoutSidebarContextType } from './layout-context';
4
+
5
+ export interface TitanLayoutSidebarLinkWrapperProps {
6
+ children:
7
+ | ReactElement<TitanLayoutSidebarLinkProps>
8
+ | ReactElement<TitanLayoutSidebarTriggerProps>;
9
+ context: TitanLayoutSidebarContextType;
10
+ }
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
+ }
22
+
23
+ export interface TitanLayoutState {
24
+ navCollapsed: boolean;
25
+ submenuExpanded?: string;
26
+ }
@@ -0,0 +1,30 @@
1
+ import { CSSProperties, FC, createContext, useContext } from 'react';
2
+ import { DefaultNavLinkComponent, NavLinkComponentProps } from '../../utils/navigation-context';
3
+ import { TitanBreakpoint } from '../../utils/use-breakpoint';
4
+
5
+ export interface TitanLayoutSidebarContextType {
6
+ styles: {
7
+ popoverContent: CSSProperties;
8
+ };
9
+ }
10
+
11
+ export type TitanLayoutPlacement = 'top' | 'side' | 'unset';
12
+
13
+ export interface TitanLayoutContextType {
14
+ NavigationComponent: FC<NavLinkComponentProps>;
15
+ breakpoint: TitanBreakpoint;
16
+ isTitanLayout: boolean;
17
+ sidebar: TitanLayoutSidebarContextType;
18
+ }
19
+
20
+ export const LayoutContext = createContext<TitanLayoutContextType>({
21
+ NavigationComponent: DefaultNavLinkComponent,
22
+ breakpoint: { name: 'lg', isMobile: false, width: 0 },
23
+ isTitanLayout: false,
24
+ sidebar: { styles: { popoverContent: {} } },
25
+ });
26
+
27
+ export const useTitanLayoutContext = () => useContext(LayoutContext);
28
+
29
+ export const LayoutPlacementContext = createContext<TitanLayoutPlacement | undefined>(undefined);
30
+ export const useTitanLayoutPlacementContext = () => useContext(LayoutPlacementContext);
@@ -0,0 +1,145 @@
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={icon}
138
+ iconActive={iconActive}
139
+ label={label}
140
+ labelClassName={labelClassName}
141
+ />
142
+ </div>,
143
+ tooltip
144
+ );
145
+ };
@@ -0,0 +1,193 @@
1
+ /* stylelint-disable no-descending-specificity */
2
+ @import (reference) '@servicetitan/tokens/core/tokens.less';
3
+
4
+ @size-links-tiny: 24px;
5
+
6
+ .header {
7
+ --nav-top-content-height: 32px;
8
+ display: flex;
9
+ justify-content: space-between;
10
+
11
+ background-color: @color-white;
12
+ color: @color-black;
13
+ box-sizing: border-box;
14
+ outline: 1px solid @color-neutral-60;
15
+
16
+ & > * {
17
+ overflow-y: hidden;
18
+ }
19
+
20
+ .he-top-left {
21
+ display: flex;
22
+ align-items: center;
23
+ }
24
+
25
+ .he-top-center {
26
+ overflow: hidden;
27
+ }
28
+
29
+ .he-top-right {
30
+ & > * {
31
+ color: @color-black;
32
+ }
33
+
34
+ .he-top-right-text {
35
+ font-size: @typescale-2;
36
+ font-weight: @font-weight-bold;
37
+ font-family: @base-font-family;
38
+ margin-right: @spacing-1;
39
+ }
40
+ }
41
+
42
+ :global(.profile-dropdown-image) {
43
+ height: 24px;
44
+ width: 24px;
45
+ }
46
+
47
+ :global(.profile-dropdown-trigger) {
48
+ height: 32px;
49
+ font-size: @size-links-tiny;
50
+ }
51
+
52
+ .navigation-link {
53
+ border-radius: 12px;
54
+ font-size: @size-links-tiny;
55
+ color: inherit;
56
+
57
+ &.navigation-item-active:not(.navigation-item-overflow) {
58
+ background-color: @color-blue-100 !important;
59
+ color: @color-blue-500 !important;
60
+ }
61
+ &:hover:not(.navigation-item-active):not(.navigation-item-overflow) {
62
+ background-color: rgba(0, 0, 0, 0.12) !important;
63
+ }
64
+
65
+ &.navigation-item-icon-state.navigation-item-active {
66
+ .navigation-icon[data-anv][data-anv]:not(.navigation-icon-active) {
67
+ display: none;
68
+ }
69
+
70
+ .navigation-icon.navigation-icon-active[data-anv][data-anv] {
71
+ display: block;
72
+ }
73
+ }
74
+ }
75
+
76
+ .navigation-icon[data-anv][data-anv] {
77
+ display: inline-block;
78
+ color: inherit;
79
+ height: 24px;
80
+ width: 24px;
81
+
82
+ > svg {
83
+ height: @size-links-tiny;
84
+ width: @size-links-tiny;
85
+ }
86
+
87
+ &.navigation-icon-active {
88
+ display: none;
89
+ }
90
+ }
91
+ }
92
+
93
+ .header-mobile {
94
+ padding: @spacing-2 @spacing-0;
95
+ height: var(--nav-offset-top);
96
+
97
+ --nav-top-content-height: 40px;
98
+
99
+ .navigation-link {
100
+ padding: 10px;
101
+ }
102
+
103
+ .he-top-center {
104
+ max-width: unset;
105
+ flex: 1;
106
+ margin-left: @spacing-3;
107
+ margin-right: @spacing-3;
108
+ }
109
+
110
+ .he-top-left {
111
+ margin-left: @spacing-half;
112
+ }
113
+
114
+ .he-top-right {
115
+ margin-right: @spacing-half;
116
+ }
117
+ }
118
+
119
+ // desktop
120
+ .header-desktop {
121
+ height: var(--nav-offset-top);
122
+ .navigation-link {
123
+ margin: 6px 2px;
124
+ padding: 6px 6px;
125
+
126
+ .navigation-item-counter {
127
+ min-width: 12px !important;
128
+ height: 12px !important;
129
+ }
130
+ }
131
+
132
+ .he-top-left {
133
+ padding-left: @spacing-1;
134
+ }
135
+ .he-top-center {
136
+ flex: 1;
137
+ margin-left: @spacing-2;
138
+ margin-right: @spacing-2;
139
+ max-width: 400px;
140
+ }
141
+ }
142
+
143
+ // desktop wide
144
+ @media only screen and (min-width: 1200px) {
145
+ .header-desktop {
146
+ display: grid;
147
+ grid-template-columns: repeat(3, 1fr);
148
+ grid-template-rows: 48px;
149
+
150
+ .he-top-left,
151
+ .he-top-center,
152
+ .he-top-right {
153
+ grid-column: span 1;
154
+ }
155
+
156
+ .he-top-center {
157
+ max-width: unset;
158
+ }
159
+ }
160
+ }
161
+
162
+ .navigation-link {
163
+ // styles specific to extra nav links
164
+ color: @color-black;
165
+ position: relative;
166
+ display: flex;
167
+ align-items: center;
168
+ flex-wrap: nowrap;
169
+ text-wrap: nowrap;
170
+
171
+ .navigation-item-counter {
172
+ color: @color-white;
173
+ font-weight: @font-weight-semibold;
174
+ font-size: 8px !important;
175
+ min-width: 16px !important;
176
+ height: 16px !important;
177
+ position: absolute;
178
+ top: 4px;
179
+ right: -2px;
180
+ }
181
+
182
+ .navigation-item-label {
183
+ color: inherit;
184
+ font-size: @typescale-1;
185
+ font-family: @base-font-family;
186
+ font-weight: @font-weight-semibold;
187
+ margin-left: @spacing-half;
188
+ }
189
+
190
+ &.navigation-item-counter-long {
191
+ right: -8px;
192
+ }
193
+ }
@@ -0,0 +1,18 @@
1
+ export const __esModule: true;
2
+ export const heTopCenter: string;
3
+ export const heTopLeft: string;
4
+ export const heTopRight: string;
5
+ export const heTopRightText: string;
6
+ export const header: string;
7
+ export const headerDesktop: string;
8
+ export const headerMobile: string;
9
+ export const navigationIcon: string;
10
+ export const navigationIconActive: string;
11
+ export const navigationItemActive: string;
12
+ export const navigationItemCounter: string;
13
+ export const navigationItemCounterLong: string;
14
+ export const navigationItemIconState: string;
15
+ export const navigationItemLabel: string;
16
+ export const navigationItemOverflow: string;
17
+ export const navigationLink: string;
18
+