@servicetitan/navigation 11.1.2 → 12.0.1

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 (52) hide show
  1. package/dist/components/titan-layout/layout-header-dark.d.ts.map +1 -1
  2. package/dist/components/titan-layout/layout-header-dark.js +32 -20
  3. package/dist/components/titan-layout/layout-header-dark.js.map +1 -1
  4. package/dist/components/titan-layout/layout-header-links-internal.d.ts +10 -0
  5. package/dist/components/titan-layout/layout-header-links-internal.d.ts.map +1 -0
  6. package/dist/components/titan-layout/layout-header-links-internal.js +75 -0
  7. package/dist/components/titan-layout/layout-header-links-internal.js.map +1 -0
  8. package/dist/components/titan-layout/layout-header-links.d.ts.map +1 -1
  9. package/dist/components/titan-layout/layout-header-links.js +10 -70
  10. package/dist/components/titan-layout/layout-header-links.js.map +1 -1
  11. package/dist/components/titan-layout/layout-header.d.ts.map +1 -1
  12. package/dist/components/titan-layout/layout-header.js +1 -0
  13. package/dist/components/titan-layout/layout-header.js.map +1 -1
  14. package/dist/components/titan-layout/layout-header.module.less +76 -63
  15. package/dist/components/titan-layout/layout-header.module.less.d.ts +1 -0
  16. package/dist/components/titan-layout/layout-logo.d.ts.map +1 -1
  17. package/dist/components/titan-layout/layout-logo.js +5 -2
  18. package/dist/components/titan-layout/layout-logo.js.map +1 -1
  19. package/dist/components/titan-layout/layout-profile.d.ts.map +1 -1
  20. package/dist/components/titan-layout/layout-profile.js +4 -3
  21. package/dist/components/titan-layout/layout-profile.js.map +1 -1
  22. package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts +3 -1
  23. package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts.map +1 -1
  24. package/dist/components/titan-layout/layout-sidebar-links-internal.js +7 -3
  25. package/dist/components/titan-layout/layout-sidebar-links-internal.js.map +1 -1
  26. package/dist/components/titan-layout/layout-sidebar-links.js +1 -1
  27. package/dist/components/titan-layout/layout-sidebar-links.js.map +1 -1
  28. package/dist/components/titan-layout/layout-sidebar.js +6 -3
  29. package/dist/components/titan-layout/layout-sidebar.js.map +1 -1
  30. package/dist/components/titan-layout/titan-layout.d.ts.map +1 -1
  31. package/dist/components/titan-layout/titan-layout.js +1 -2
  32. package/dist/components/titan-layout/titan-layout.js.map +1 -1
  33. package/dist/components/titan-layout/titan-layout.stories.d.ts +1 -0
  34. package/dist/components/titan-layout/titan-layout.stories.d.ts.map +1 -1
  35. package/dist/components/titan-layout/with-tooltip.d.ts +1 -1
  36. package/dist/components/titan-layout/with-tooltip.d.ts.map +1 -1
  37. package/dist/components/titan-layout/with-tooltip.js.map +1 -1
  38. package/package.json +2 -2
  39. package/src/components/titan-layout/layout-header-dark.tsx +42 -20
  40. package/src/components/titan-layout/layout-header-links-internal.tsx +151 -0
  41. package/src/components/titan-layout/layout-header-links.tsx +9 -125
  42. package/src/components/titan-layout/layout-header.module.less +76 -63
  43. package/src/components/titan-layout/layout-header.module.less.d.ts +1 -0
  44. package/src/components/titan-layout/layout-header.tsx +5 -1
  45. package/src/components/titan-layout/layout-logo.tsx +10 -5
  46. package/src/components/titan-layout/layout-profile.tsx +4 -3
  47. package/src/components/titan-layout/layout-sidebar-links-internal.tsx +14 -5
  48. package/src/components/titan-layout/layout-sidebar-links.tsx +1 -1
  49. package/src/components/titan-layout/layout-sidebar.tsx +8 -6
  50. package/src/components/titan-layout/titan-layout.stories.tsx +14 -0
  51. package/src/components/titan-layout/titan-layout.tsx +1 -2
  52. package/src/components/titan-layout/with-tooltip.tsx +1 -1
@@ -122,14 +122,15 @@
122
122
  min-width: 0;
123
123
  overflow-x: auto;
124
124
  overflow-y: hidden;
125
+ flex: 1;
125
126
 
126
127
  display: flex;
127
128
  justify-content: center;
128
129
  align-items: center;
129
130
 
130
131
  &.calculating {
131
- .header-navigation {
132
- opacity: 0;
132
+ > * {
133
+ opacity: 0 !important;
133
134
  }
134
135
  }
135
136
 
@@ -202,6 +203,12 @@
202
203
  text-decoration: none;
203
204
  }
204
205
  }
206
+ .logo-title {
207
+ font-family: @display-font-family;
208
+ font-weight: @font-weight-semibold;
209
+ font-size: 21px;
210
+ line-height: 24px;
211
+ }
205
212
  }
206
213
 
207
214
  .header-desktop {
@@ -231,7 +238,8 @@
231
238
  }
232
239
 
233
240
  //!!!!!!!!!!!!!!! nav links styles !!!!!!!!!!!!!!!//
234
- .navigation-link {
241
+ .navigation-link,
242
+ .navigation-link-overflow {
235
243
  &.navigation-item-icon-state.navigation-item-active {
236
244
  .navigation-icon[data-anv][data-anv]:not(.navigation-icon-active) {
237
245
  display: none;
@@ -270,34 +278,34 @@
270
278
 
271
279
  border-radius: 12px;
272
280
  font-size: @size-links-tiny;
273
- }
274
-
275
- .navigation-item-counter {
276
- color: @color-white;
277
- font-weight: @font-weight-semibold;
278
- font-size: 8px !important;
279
- min-width: 16px !important;
280
- height: 16px !important;
281
- position: absolute;
282
- top: 4px;
283
- right: -2px;
284
281
 
285
- &.navigation-item-counter-long {
286
- right: -8px;
282
+ .navigation-item-counter {
283
+ color: @color-white;
284
+ font-weight: @font-weight-semibold;
285
+ font-size: 8px !important;
286
+ min-width: 16px !important;
287
+ height: 16px !important;
288
+ position: absolute;
289
+ top: 4px;
290
+ right: -2px;
291
+
292
+ &.navigation-item-counter-long {
293
+ right: -8px;
294
+ }
287
295
  }
288
- }
289
296
 
290
- .navigation-item-label {
291
- color: inherit;
292
- font-size: @typescale-1;
293
- font-family: @base-font-family;
294
- font-weight: @font-weight-semibold;
295
- margin-left: @spacing-half;
296
- }
297
+ .navigation-item-label {
298
+ color: inherit;
299
+ font-size: @typescale-1;
300
+ font-family: @base-font-family;
301
+ font-weight: @font-weight-semibold;
302
+ margin-left: @spacing-half;
303
+ }
297
304
 
298
- .navigation-icon[data-anv][data-anv] {
299
- height: 24px;
300
- width: 24px;
305
+ .navigation-icon[data-anv][data-anv] {
306
+ height: 24px;
307
+ width: 24px;
308
+ }
301
309
  }
302
310
 
303
311
  &.header-desktop {
@@ -333,7 +341,7 @@
333
341
  }
334
342
 
335
343
  .header-dark .navigation-link,
336
- .header-navigation > .navigation-link {
344
+ .header-navigation .navigation-link {
337
345
  &.navigation-item-active {
338
346
  color: @color-blue-200 !important;
339
347
  }
@@ -395,47 +403,52 @@
395
403
  }
396
404
  }
397
405
 
398
- .header-navigation-overflow .navigation-link {
399
- display: inline-flex;
400
- color: @color-black;
401
- padding: @spacing-1 12px;
402
- cursor: pointer;
403
-
404
- font-family: @base-font-family;
405
- font-size: @typescale-4;
406
- position: relative;
407
- align-items: center;
408
- flex-wrap: nowrap;
409
- text-wrap: nowrap;
406
+ .header-navigation-overflow {
407
+ display: flex;
408
+ flex-direction: column;
410
409
 
411
410
  margin-left: -0.5rem;
412
411
  margin-right: -0.5rem;
413
412
 
414
- &:hover {
415
- background-color: @color-blue-500;
416
- color: @color-white;
417
- }
418
-
419
- &.navigation-item-active:not(:hover) {
420
- color: @color-blue;
421
- }
413
+ .navigation-link-overflow {
414
+ display: inline-flex;
415
+ color: @color-black;
416
+ padding: @spacing-1 12px;
417
+ cursor: pointer;
422
418
 
423
- .navigation-item-label {
424
419
  font-family: @base-font-family;
425
- font-size: @typescale-2;
426
- margin-left: @spacing-half;
427
- }
428
- .navigation-item-counter {
429
- color: @color-white;
430
- font-weight: @font-weight-semibold;
431
- font-size: 8px !important;
420
+ font-size: @typescale-4;
421
+ position: relative;
422
+ align-items: center;
423
+ flex-wrap: nowrap;
424
+ text-wrap: nowrap;
432
425
 
433
- min-width: 12px !important;
434
- height: 12px !important;
435
- margin-left: @spacing-half;
436
- margin-top: -@spacing-1;
437
- }
438
- .navigation-icon[data-anv][data-anv] {
439
- height: 20px;
426
+ &:hover {
427
+ background-color: @color-blue-500;
428
+ color: @color-white;
429
+ }
430
+
431
+ &.navigation-item-active:not(:hover) {
432
+ color: @color-blue;
433
+ }
434
+
435
+ .navigation-item-label {
436
+ font-family: @base-font-family;
437
+ font-size: @typescale-2;
438
+ margin-left: @spacing-half;
439
+ }
440
+ .navigation-item-counter {
441
+ color: @color-white;
442
+ font-weight: @font-weight-semibold;
443
+ font-size: 8px !important;
444
+ margin-right: @spacing-half;
445
+ margin-left: @spacing-half;
446
+
447
+ min-width: 12px !important;
448
+ height: 12px !important;
449
+ }
450
+ .navigation-icon[data-anv][data-anv] {
451
+ height: 20px;
452
+ }
440
453
  }
441
454
  }
@@ -32,4 +32,5 @@ export const navigationItemCounterLong: string;
32
32
  export const navigationItemIconState: string;
33
33
  export const navigationItemLabel: string;
34
34
  export const navigationLink: string;
35
+ export const navigationLinkOverflow: string;
35
36
 
@@ -84,7 +84,11 @@ export const LayoutHeader: FC<LayoutHeaderProps> = ({
84
84
  )}
85
85
  data-cy="navigation-right"
86
86
  >
87
- {!!rightText && <div className={Styles.heTopRightText}>{rightText}</div>}
87
+ {!!rightText && (
88
+ <div className={Styles.heTopRightText} data-cy="navigation-right-text">
89
+ {rightText}
90
+ </div>
91
+ )}
88
92
  {right}
89
93
  {profile}
90
94
  </div>
@@ -2,7 +2,6 @@ import classNames from 'classnames';
2
2
  import { ComponentPropsWithoutRef, FC, Fragment, ReactNode } from 'react';
3
3
  import { LogoCompanyTitle } from '../logo/logo-company-title';
4
4
  import { LogoTitanSvg } from '../logo/logo-titan';
5
- import { LogoTitanTitle } from '../logo/logo-titan-text';
6
5
  import { useTitanLayoutContext } from './layout-context';
7
6
  import * as Styles from './layout-header.module.less';
8
7
 
@@ -37,26 +36,32 @@ export const LayoutLogo: FC<TitanLayoutLogoProps> = props => {
37
36
  return (
38
37
  <div className={classNames(Styles.logo)} data-cy="navigation-left">
39
38
  {showCompanyTitle ? (
40
- <div {...rest} className={Styles.logoCompanyWrapper}>
39
+ <div data-cy="logo-wrapper" {...rest} className={Styles.logoCompanyWrapper}>
41
40
  <Wrapper to={to} className={Styles.logoLink}>
42
41
  <LogoCompanyTitle />
43
42
  </Wrapper>
44
43
  </div>
45
44
  ) : (
46
45
  <Fragment>
47
- <div {...rest} className={Styles.logoShortWrapper}>
46
+ <div data-cy="logo-wrapper" {...rest} className={Styles.logoShortWrapper}>
48
47
  <Wrapper to={to} className={Styles.logoLink}>
49
48
  <LogoTitanSvg mantleFill={mantleFill} />
50
49
  </Wrapper>
51
50
  </div>
52
51
 
53
52
  {isLogoText(props, isMobile) && (
54
- <LogoTitanTitle className={Styles.logoTitle}>{title}</LogoTitanTitle>
53
+ <div className={Styles.logoTitle} data-cy="logo-title">
54
+ {title}
55
+ </div>
55
56
  )}
56
57
  </Fragment>
57
58
  )}
58
59
 
59
- {!isMobile && postfix && <div className={Styles.logoPostfix}>{postfix}</div>}
60
+ {!isMobile && postfix && (
61
+ <div className={Styles.logoPostfix} data-cy="logo-postfix">
62
+ {postfix}
63
+ </div>
64
+ )}
60
65
  </div>
61
66
  );
62
67
  };
@@ -50,12 +50,12 @@ const ProfileDropdownContent: FC<ProfileDropdownProps> = props => {
50
50
  );
51
51
  };
52
52
  ProfileDropdownContent.displayName = 'ProfileDropdown';
53
+ const profileId = '--profile';
53
54
 
54
55
  const MobileProfileDropdown: FC<ProfileDropdownProps & NavigationComponentProps> = ({
55
56
  children,
56
57
  ...props
57
58
  }) => {
58
- const id = '__profile';
59
59
  const [expanded, setExpanded] = useState(false);
60
60
  const { hasNotifications, NotificationsContextProvider } = useNotificationsState();
61
61
  const { onNotificationsUpdate } = useNotificationsContext();
@@ -65,13 +65,13 @@ const MobileProfileDropdown: FC<ProfileDropdownProps & NavigationComponentProps>
65
65
  };
66
66
 
67
67
  useEffect(() => {
68
- onNotificationsUpdate(id, hasNotifications);
68
+ onNotificationsUpdate(profileId, hasNotifications);
69
69
  }, [hasNotifications, onNotificationsUpdate]);
70
70
 
71
71
  return (
72
72
  <NotificationsContextProvider>
73
73
  <InternalSideNavigationGroup
74
- id={id}
74
+ id={profileId}
75
75
  to={undefined}
76
76
  title="Profile"
77
77
  icon={SvgAccountInactive}
@@ -168,6 +168,7 @@ const MobileProfileDropdownLink: FC<ProfileDropdownLinkProps & NavigationCompone
168
168
  {...props}
169
169
  to={to}
170
170
  title={linkText}
171
+ parentId={profileId}
171
172
  navigationComponent={isExternalLink ? ExternalNavComponent : navigationComponent}
172
173
  />
173
174
  ) : null;
@@ -59,7 +59,9 @@ export const InternalSideNavigationItemContent: FC<InternalSideNavigationItemCon
59
59
  </Fragment>
60
60
  )}
61
61
 
62
- <div className={Styles.navItemTextExpanded}>{title}</div>
62
+ <div className={Styles.navItemTextExpanded} data-cy="nav-item-label">
63
+ {title}
64
+ </div>
63
65
  {!!tag && (
64
66
  <BadgeTag
65
67
  data={tag}
@@ -74,7 +76,11 @@ export const InternalSideNavigationItemContent: FC<InternalSideNavigationItemCon
74
76
  className={Styles.navItemGroupToggle}
75
77
  onClick={onExpandToggle}
76
78
  />
77
- <div className={Styles.navItemGroupToggleClick} onClick={onExpandToggle} />
79
+ <div
80
+ className={Styles.navItemGroupToggleClick}
81
+ data-cy="nav-item-group-expand"
82
+ onClick={onExpandToggle}
83
+ />
78
84
  </div>
79
85
  )}
80
86
  </div>
@@ -83,6 +89,7 @@ export const InternalSideNavigationItemContent: FC<InternalSideNavigationItemCon
83
89
  className={classNames(Styles.navItemTextCollapsed, {
84
90
  [Styles.navItemTextSmall]: !!title && title.length >= 10,
85
91
  })}
92
+ data-cy="nav-item-label"
86
93
  >
87
94
  {title}
88
95
  </div>
@@ -181,10 +188,11 @@ export const InternalSideNavigationTrigger: FC<
181
188
  };
182
189
 
183
190
  export const InternalSideNavigationGroupLink: FC<
184
- NavigationSubmenuItemData & NavigationComponentProps
191
+ NavigationSubmenuItemData & NavigationComponentProps & { parentId: string }
185
192
  > = ({
186
193
  id,
187
194
  counter,
195
+ parentId,
188
196
  tag,
189
197
  title,
190
198
  to,
@@ -195,8 +203,8 @@ export const InternalSideNavigationGroupLink: FC<
195
203
  return (
196
204
  <NavigationComponent
197
205
  key={id}
198
- data-cy={`navigation-item-${id}`}
199
- data-pendo={`navigation-item-${id}`}
206
+ data-cy={`navigation-item-${parentId}--${id}`}
207
+ data-pendo={`navigation-item-${parentId}--${id}`}
200
208
  {...rest}
201
209
  to={to}
202
210
  className={classNames(Styles.submenuItem, Styles.submenuLink, {
@@ -270,6 +278,7 @@ export const InternalSideNavigationGroup: FC<
270
278
  className={classNames(Styles.submenuWrapper, {
271
279
  [Styles.submenuWrapperCollapsed]: !submenuExpanded,
272
280
  })}
281
+ data-cy={`navigation-submenu-${props.id}`}
273
282
  >
274
283
  <div className={Styles.submenu}>{children}</div>
275
284
  </div>
@@ -32,7 +32,7 @@ export function TitanLayoutSidebarLink({ wrapper, ...props }: TitanLayoutSidebar
32
32
  {...props}
33
33
  navigationComponent={NavigationComponent}
34
34
  submenuExpanded={undefined}
35
- dataPrefix="navigation-link"
35
+ dataPrefix="navigation-item"
36
36
  tag={tag}
37
37
  />
38
38
  );
@@ -205,6 +205,7 @@ const SideNavigationGroupItem: FC<
205
205
  tag={tag}
206
206
  >
207
207
  <SideNavigationGroupContent
208
+ parentId={props.id}
208
209
  groups={props.submenu?.groups ?? []}
209
210
  navigationComponent={props.navigationComponent}
210
211
  />
@@ -233,6 +234,7 @@ const SideNavigationGroupItem: FC<
233
234
  {props.title}
234
235
  </Text>
235
236
  <SideNavigationGroupContent
237
+ parentId={props.id}
236
238
  groups={props.submenu?.groups ?? []}
237
239
  navigationComponent={props.navigationComponent}
238
240
  />
@@ -241,10 +243,9 @@ const SideNavigationGroupItem: FC<
241
243
  </Popover>
242
244
  );
243
245
  };
244
- const SideNavigationGroupContent: FC<NavigationSubmenuData & NavigationComponentProps> = ({
245
- groups,
246
- navigationComponent,
247
- }) => {
246
+ const SideNavigationGroupContent: FC<
247
+ NavigationSubmenuData & NavigationComponentProps & { parentId: string }
248
+ > = ({ groups, parentId, navigationComponent }) => {
248
249
  return (
249
250
  <Fragment>
250
251
  {groups.reduce((out, group, index) => {
@@ -256,7 +257,7 @@ const SideNavigationGroupContent: FC<NavigationSubmenuData & NavigationComponent
256
257
  /* eslint-disable react/no-array-index-key */
257
258
  out.push(
258
259
  <Text
259
- key={`:group:${index}:title`}
260
+ key={`:group:${parentId}:${index}:title`}
260
261
  variant="eyebrow"
261
262
  className={classNames(Styles.submenuGroupHeader, {
262
263
  [Styles.submenuGroupHeaderEmpty]: !title,
@@ -268,8 +269,9 @@ const SideNavigationGroupContent: FC<NavigationSubmenuData & NavigationComponent
268
269
  out.push(
269
270
  ...group.links.map((link, index) => (
270
271
  <InternalSideNavigationGroupLink
271
- key={`:${link.id}:${index}`}
272
+ key={`:${parentId}:${link.id}:${index}`}
272
273
  {...link}
274
+ parentId={parentId}
273
275
  navigationComponent={navigationComponent}
274
276
  />
275
277
  ))
@@ -365,6 +365,20 @@ export const TitanLayoutAnvil1TopNav = (args: LayoutContentArgs) => (
365
365
  );
366
366
 
367
367
  export const TitanLayoutAnvil1Top = (args: LayoutContentArgs) => (
368
+ <TitanLayout
369
+ {...useLayoutProps(args)}
370
+ appearance="anvil1"
371
+ navVariant="top"
372
+ top={undefined}
373
+ navigationOverflowItems={undefined}
374
+ >
375
+ <Anvil1Page>
376
+ <Content {...args} />
377
+ </Anvil1Page>
378
+ </TitanLayout>
379
+ );
380
+
381
+ export const TitanLayoutAnvil1TopOverflow = (args: LayoutContentArgs) => (
368
382
  <TitanLayout {...useLayoutProps(args)} appearance="anvil1" navVariant="top" top={undefined}>
369
383
  <Anvil1Page>
370
384
  <Content {...args} />
@@ -316,10 +316,9 @@ const TitanLayoutComponent: FC<TitanLayoutProps> = ({
316
316
  {extraLinks}
317
317
  {!!extraText && (
318
318
  <InternalSideNavigationTrigger
319
- id="__extra_text"
319
+ id="--extra-text"
320
320
  title={extraText}
321
321
  submenuExpanded={undefined}
322
- dataPrefix="navigation-extra-text"
323
322
  tag={undefined}
324
323
  icon={undefined}
325
324
  iconActive={undefined}
@@ -4,7 +4,7 @@ import { ReactElement } from 'react';
4
4
  export const withTooltip = (
5
5
  element: ReactElement,
6
6
  tooltip: string | undefined,
7
- props: {
7
+ props?: {
8
8
  placement?: TooltipProps['placement'];
9
9
  key?: string;
10
10
  }