@servicetitan/navigation 11.0.0 → 11.1.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 (179) hide show
  1. package/dist/components/badge-tag.js +7 -2
  2. package/dist/components/badge-tag.js.map +1 -1
  3. package/dist/components/counter-tag.js +10 -2
  4. package/dist/components/counter-tag.js.map +1 -1
  5. package/dist/components/header-navigation/header-navigation-content.js +44 -8
  6. package/dist/components/header-navigation/header-navigation-content.js.map +1 -1
  7. package/dist/components/header-navigation/header-navigation-links.js +49 -13
  8. package/dist/components/header-navigation/header-navigation-links.js.map +1 -1
  9. package/dist/components/header-navigation/header-navigation-stories.module.less.d.ts +3 -0
  10. package/dist/components/header-navigation/header-navigation.js +178 -46
  11. package/dist/components/header-navigation/header-navigation.js.map +1 -1
  12. package/dist/components/header-navigation/header-navigation.module.less.d.ts +22 -0
  13. package/dist/components/header-navigation/index.js +1 -0
  14. package/dist/components/header-navigation/index.js.map +1 -1
  15. package/dist/components/header-navigation/with-tooltip.js +7 -1
  16. package/dist/components/header-navigation/with-tooltip.js.map +1 -1
  17. package/dist/components/left-navigation/header-navigation-tiny-links.js +62 -15
  18. package/dist/components/left-navigation/header-navigation-tiny-links.js.map +1 -1
  19. package/dist/components/left-navigation/header-navigation-tiny.js +27 -2
  20. package/dist/components/left-navigation/header-navigation-tiny.js.map +1 -1
  21. package/dist/components/left-navigation/header-navigation-tiny.module.less.d.ts +15 -0
  22. package/dist/components/left-navigation/index.d.ts +1 -1
  23. package/dist/components/left-navigation/index.d.ts.map +1 -1
  24. package/dist/components/left-navigation/index.js +1 -1
  25. package/dist/components/left-navigation/index.js.map +1 -1
  26. package/dist/components/left-navigation/interface-internal.js +2 -1
  27. package/dist/components/left-navigation/interface-internal.js.map +1 -1
  28. package/dist/components/left-navigation/interface.js +2 -1
  29. package/dist/components/left-navigation/interface.js.map +1 -1
  30. package/dist/components/left-navigation/side-navigation-context.js +4 -3
  31. package/dist/components/left-navigation/side-navigation-context.js.map +1 -1
  32. package/dist/components/left-navigation/side-navigation-links-internal.js +76 -16
  33. package/dist/components/left-navigation/side-navigation-links-internal.js.map +1 -1
  34. package/dist/components/left-navigation/side-navigation-links.js +34 -13
  35. package/dist/components/left-navigation/side-navigation-links.js.map +1 -1
  36. package/dist/components/left-navigation/side-navigation.js +314 -85
  37. package/dist/components/left-navigation/side-navigation.js.map +1 -1
  38. package/dist/components/left-navigation/side-navigation.module.less.d.ts +48 -0
  39. package/dist/components/left-navigation/with-tooltip.js +12 -1
  40. package/dist/components/left-navigation/with-tooltip.js.map +1 -1
  41. package/dist/components/links.js +28 -7
  42. package/dist/components/links.js.map +1 -1
  43. package/dist/components/logo/logo-company-title.js +19 -3
  44. package/dist/components/logo/logo-company-title.js.map +1 -1
  45. package/dist/components/logo/logo-titan-text.js +50 -6
  46. package/dist/components/logo/logo-titan-text.js.map +1 -1
  47. package/dist/components/logo/logo-titan-text.module.less.d.ts +6 -0
  48. package/dist/components/logo/logo-titan.d.ts +1 -0
  49. package/dist/components/logo/logo-titan.d.ts.map +1 -1
  50. package/dist/components/logo/logo-titan.js +53 -8
  51. package/dist/components/logo/logo-titan.js.map +1 -1
  52. package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
  53. package/dist/components/profile-dropdown/profile-dropdown.js +174 -33
  54. package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
  55. package/dist/components/profile-dropdown/profile-dropdown.module.less.d.ts +23 -0
  56. package/dist/components/profile-dropdown/profile-icon.js +49 -3
  57. package/dist/components/profile-dropdown/profile-icon.js.map +1 -1
  58. package/dist/components/titan-layout/index.d.ts +2 -2
  59. package/dist/components/titan-layout/index.d.ts.map +1 -1
  60. package/dist/components/titan-layout/index.js +1 -2
  61. package/dist/components/titan-layout/index.js.map +1 -1
  62. package/dist/components/titan-layout/interface-internal.js +2 -1
  63. package/dist/components/titan-layout/interface-internal.js.map +1 -1
  64. package/dist/components/titan-layout/interface.js +2 -1
  65. package/dist/components/titan-layout/interface.js.map +1 -1
  66. package/dist/components/titan-layout/layout-context.js +15 -6
  67. package/dist/components/titan-layout/layout-context.js.map +1 -1
  68. package/dist/components/titan-layout/layout-header-dark.d.ts +10 -0
  69. package/dist/components/titan-layout/layout-header-dark.d.ts.map +1 -0
  70. package/dist/components/titan-layout/layout-header-dark.js +146 -0
  71. package/dist/components/titan-layout/layout-header-dark.js.map +1 -0
  72. package/dist/components/titan-layout/layout-header-links.js +61 -15
  73. package/dist/components/titan-layout/layout-header-links.js.map +1 -1
  74. package/dist/components/titan-layout/layout-header.d.ts +2 -6
  75. package/dist/components/titan-layout/layout-header.d.ts.map +1 -1
  76. package/dist/components/titan-layout/layout-header.js +46 -2
  77. package/dist/components/titan-layout/layout-header.js.map +1 -1
  78. package/dist/components/titan-layout/layout-header.module.less +337 -83
  79. package/dist/components/titan-layout/layout-header.module.less.d.ts +35 -0
  80. package/dist/components/titan-layout/layout-logo.d.ts +5 -3
  81. package/dist/components/titan-layout/layout-logo.d.ts.map +1 -1
  82. package/dist/components/titan-layout/layout-logo.js +47 -9
  83. package/dist/components/titan-layout/layout-logo.js.map +1 -1
  84. package/dist/components/titan-layout/layout-logo.stories.d.ts +15 -4
  85. package/dist/components/titan-layout/layout-logo.stories.d.ts.map +1 -1
  86. package/dist/components/titan-layout/layout-profile.js +75 -23
  87. package/dist/components/titan-layout/layout-profile.js.map +1 -1
  88. package/dist/components/titan-layout/layout-sidebar-links-internal.js +162 -36
  89. package/dist/components/titan-layout/layout-sidebar-links-internal.js.map +1 -1
  90. package/dist/components/titan-layout/layout-sidebar-links.js +33 -13
  91. package/dist/components/titan-layout/layout-sidebar-links.js.map +1 -1
  92. package/dist/components/titan-layout/layout-sidebar.js +198 -34
  93. package/dist/components/titan-layout/layout-sidebar.js.map +1 -1
  94. package/dist/components/titan-layout/layout-sidebar.module.less +6 -2
  95. package/dist/components/titan-layout/layout-sidebar.module.less.d.ts +49 -0
  96. package/dist/components/titan-layout/notifications-context.js +20 -10
  97. package/dist/components/titan-layout/notifications-context.js.map +1 -1
  98. package/dist/components/titan-layout/titan-layout.d.ts +7 -8
  99. package/dist/components/titan-layout/titan-layout.d.ts.map +1 -1
  100. package/dist/components/titan-layout/titan-layout.js +271 -117
  101. package/dist/components/titan-layout/titan-layout.js.map +1 -1
  102. package/dist/components/titan-layout/titan-layout.module.less +7 -2
  103. package/dist/components/titan-layout/titan-layout.module.less.d.ts +17 -0
  104. package/dist/components/titan-layout/titan-layout.stories.d.ts +6 -0
  105. package/dist/components/titan-layout/titan-layout.stories.d.ts.map +1 -1
  106. package/dist/components/titan-layout/with-tooltip.d.ts +4 -1
  107. package/dist/components/titan-layout/with-tooltip.d.ts.map +1 -1
  108. package/dist/components/titan-layout/with-tooltip.js +13 -1
  109. package/dist/components/titan-layout/with-tooltip.js.map +1 -1
  110. package/dist/index.d.ts +4 -3
  111. package/dist/index.d.ts.map +1 -1
  112. package/dist/index.js +2 -3
  113. package/dist/index.js.map +1 -1
  114. package/dist/test/data-stories.module.less.d.ts +3 -0
  115. package/dist/test/data.js +223 -90
  116. package/dist/test/data.js.map +1 -1
  117. package/dist/utils/counter-tag.js +2 -1
  118. package/dist/utils/counter-tag.js.map +1 -1
  119. package/dist/utils/navigation-context.js +12 -6
  120. package/dist/utils/navigation-context.js.map +1 -1
  121. package/dist/utils/navigation-legacy.js +2 -1
  122. package/dist/utils/navigation-legacy.js.map +1 -1
  123. package/dist/utils/navigation.js +2 -1
  124. package/dist/utils/navigation.js.map +1 -1
  125. package/dist/utils/side-nav.js +9 -6
  126. package/dist/utils/side-nav.js.map +1 -1
  127. package/dist/utils/use-breakpoint.js +11 -8
  128. package/dist/utils/use-breakpoint.js.map +1 -1
  129. package/package.json +4 -4
  130. package/src/components/left-navigation/index.ts +1 -1
  131. package/src/components/logo/logo-titan.tsx +3 -1
  132. package/src/components/profile-dropdown/profile-dropdown.tsx +8 -4
  133. package/src/components/titan-layout/index.ts +2 -2
  134. package/src/components/titan-layout/layout-header-dark.tsx +186 -0
  135. package/src/components/titan-layout/layout-header-links.tsx +1 -1
  136. package/src/components/titan-layout/layout-header.module.less +337 -83
  137. package/src/components/titan-layout/layout-header.module.less.d.ts +19 -2
  138. package/src/components/titan-layout/layout-header.tsx +13 -16
  139. package/src/components/titan-layout/layout-logo.stories.tsx +103 -15
  140. package/src/components/titan-layout/layout-logo.tsx +33 -36
  141. package/src/components/titan-layout/layout-profile.stories.tsx +1 -1
  142. package/src/components/titan-layout/layout-sidebar.module.less +6 -2
  143. package/src/components/titan-layout/layout-sidebar.tsx +1 -1
  144. package/src/components/titan-layout/titan-layout.module.less +7 -2
  145. package/src/components/titan-layout/titan-layout.module.less.d.ts +2 -1
  146. package/src/components/titan-layout/titan-layout.stories.tsx +80 -23
  147. package/src/components/titan-layout/titan-layout.tsx +96 -85
  148. package/src/components/titan-layout/with-tooltip.tsx +5 -2
  149. package/src/index.ts +4 -5
  150. package/dist/components/header-navigation/header-navigation-extra-stacked.stories.js +0 -13
  151. package/dist/components/header-navigation/header-navigation-extra-stacked.stories.js.map +0 -1
  152. package/dist/components/header-navigation/header-navigation-extra.stories.js +0 -29
  153. package/dist/components/header-navigation/header-navigation-extra.stories.js.map +0 -1
  154. package/dist/components/header-navigation/header-navigation-stacked.stories.js +0 -50
  155. package/dist/components/header-navigation/header-navigation-stacked.stories.js.map +0 -1
  156. package/dist/components/header-navigation/header-navigation.stories.js +0 -54
  157. package/dist/components/header-navigation/header-navigation.stories.js.map +0 -1
  158. package/dist/components/layout.stories.js +0 -29
  159. package/dist/components/layout.stories.js.map +0 -1
  160. package/dist/components/left-navigation/header-navigation-extra-tiny.stories.js +0 -13
  161. package/dist/components/left-navigation/header-navigation-extra-tiny.stories.js.map +0 -1
  162. package/dist/components/left-navigation/header-navigation-tiny.stories.js +0 -30
  163. package/dist/components/left-navigation/header-navigation-tiny.stories.js.map +0 -1
  164. package/dist/components/left-navigation/side-navigation.stories.js +0 -115
  165. package/dist/components/left-navigation/side-navigation.stories.js.map +0 -1
  166. package/dist/components/logo/logo.stories.js +0 -20
  167. package/dist/components/logo/logo.stories.js.map +0 -1
  168. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.js +0 -13
  169. package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.js.map +0 -1
  170. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.js +0 -13
  171. package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.js.map +0 -1
  172. package/dist/components/profile-dropdown/profile-dropdown.stories.js +0 -51
  173. package/dist/components/profile-dropdown/profile-dropdown.stories.js.map +0 -1
  174. package/dist/components/titan-layout/layout-logo.stories.js +0 -17
  175. package/dist/components/titan-layout/layout-logo.stories.js.map +0 -1
  176. package/dist/components/titan-layout/layout-profile.stories.js +0 -13
  177. package/dist/components/titan-layout/layout-profile.stories.js.map +0 -1
  178. package/dist/components/titan-layout/titan-layout.stories.js +0 -83
  179. package/dist/components/titan-layout/titan-layout.stories.js.map +0 -1
@@ -1,2 +1,3 @@
1
- export {};
1
+ export { };
2
+
2
3
  //# sourceMappingURL=navigation-legacy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-legacy.js","sourceRoot":"","sources":["../../src/utils/navigation-legacy.ts"],"names":[],"mappings":""}
1
+ {"version":3,"sources":["../../src/utils/navigation-legacy.ts"],"sourcesContent":["import { IconProps } from '@servicetitan/anvil2';\nimport { IconPropsStrict } from '@servicetitan/design-system';\nimport { FC, HTMLAttributeAnchorTarget } from 'react';\nimport { CounterTagData, CounterTagValue } from './counter-tag';\nimport { NavigationSubmenuData } from './navigation';\n\nexport interface HeaderNavigationItemData extends HeaderNavigationItemLinkProps {\n /** link description */\n hint: string;\n\n /** flag if the link is not shown (based on FG and/or user permissions) */\n isHidden?: boolean;\n\n /** custom className (can be used for mdi icons) */\n iconClassName?: string;\n\n /** anvil's icon name of item */\n iconName?: IconPropsStrict['name'];\n\n /** svg icon (anvil2) of inactive item */\n icon: IconProps['svg'] | undefined;\n\n /** svg icon (anvil2) of active item */\n iconActive: IconProps['svg'] | undefined;\n\n /** icon component of item (<svg />) */\n iconComponent?: FC;\n\n /** item tag (optional). shown if it is set and true or greater than 0 */\n counter?: CounterTagValue;\n tag?: CounterTagData;\n\n /** class name of link item */\n className?: string;\n\n /** optional submenu of link item */\n submenu?: NavigationSubmenuData;\n}\n\nexport interface HeaderNavigationItemLinkProps {\n /** link id */\n id: string;\n\n /** link href */\n to: string;\n\n /** link title */\n title: string;\n\n /** callback to return active state. By default, it compares link href with current pathname */\n isActive?: boolean | ((pathname: string) => boolean);\n}\n\nexport interface HeaderNavigationTriggerPropsStrict {\n /** unique identifier */\n id: string;\n /** item title (used for mobile) */\n title: string;\n /** tooltip text */\n tooltip?: string;\n /** item description */\n hint?: string;\n /** container class name */\n className?: string;\n /** item label */\n label?: string;\n /** label class name */\n labelClassName?: string;\n /** isActive */\n isActive?: boolean;\n /** counter value shown for item */\n counter?: CounterTagValue;\n tag?: CounterTagData;\n /** counter component class name */\n counterClassName?: string;\n /** icon component class name */\n iconClassName?: string;\n /** IconComponent custom icon component */\n iconComponent?: FC;\n /** iconName name of anvil icon */\n iconName?: IconPropsStrict['name'];\n /** svg icon (anvil2) of inactive item */\n icon: IconProps['svg'] | undefined;\n /** svg icon (anvil2) of active item */\n iconActive?: IconProps['svg'];\n}\n\nexport interface HeaderNavigationTriggerProps extends HeaderNavigationTriggerPropsStrict {\n /** unstrict props */\n [key: string]: any;\n}\n\nexport interface HeaderNavigationLinkPropsStrict\n extends Omit<HeaderNavigationTriggerPropsStrict, 'isActive'> {\n /** link href */\n to: string;\n /** isActive */\n isActive?: boolean | ((pathname: string) => boolean);\n /** link html target */\n target?: HTMLAttributeAnchorTarget;\n}\n\nexport interface HeaderNavigationLinkProps extends HeaderNavigationLinkPropsStrict {\n /** unstrict props */\n [key: string]: any;\n}\n"],"names":[],"mappings":"AAsGA,WAGC"}
@@ -1,2 +1,3 @@
1
- export {};
1
+ export { };
2
+
2
3
  //# sourceMappingURL=navigation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/utils/navigation.ts"],"names":[],"mappings":""}
1
+ {"version":3,"sources":["../../src/utils/navigation.ts"],"sourcesContent":["import { IconProps } from '@servicetitan/anvil2';\nimport { FC } from 'react';\nimport { CounterTagData, CounterTagValue } from './counter-tag';\n\nexport interface NavigationItemData extends NavigationLinkData {\n /** flag if the link is not shown (based on FG and/or user permissions) */\n isHidden?: boolean;\n\n /** custom className (can be used for mdi icons) */\n iconClassName?: string;\n\n /** svg icon (anvil2) of inactive item */\n icon: IconProps['svg'] | undefined;\n\n /** svg icon (anvil2) of active item */\n iconActive: IconProps['svg'] | undefined;\n\n /** icon component of item (<svg />) */\n iconComponent?: FC;\n\n /** item tag (optional). shown if it is set and true or greater than 0 */\n counter?: CounterTagValue;\n tag?: CounterTagData;\n\n /** class name of link item */\n className?: string;\n\n /** optional submenu of link item */\n submenu?: NavigationSubmenuData;\n}\n\nexport interface NavigationLinkData {\n /** link id */\n id: string;\n\n /** link href */\n to: string;\n\n /** link title */\n title: string;\n\n /** callback to return active state. By default, it compares link href with current pathname */\n isActive?: boolean | ((pathname: string) => boolean);\n}\n\nexport interface NavigationSubmenuData {\n /** submenu groups */\n groups: NavigationSubmenuGroupData[];\n}\n\nexport interface NavigationSubmenuItemData extends NavigationLinkData {\n /** item tag (optional) value. shown if it is set and true or greater than 0 */\n counter?: CounterTagValue;\n tag?: CounterTagData;\n}\n\nexport interface NavigationSubmenuGroupData {\n /** submenu group title */\n title: string;\n\n /** submenu group links */\n links: NavigationSubmenuItemData[];\n}\n"],"names":[],"mappings":"AAwDA,WAMC"}
@@ -3,8 +3,8 @@ export function getSubmenuGroupTag(submenu, defaultTag) {
3
3
  return defaultTag;
4
4
  }
5
5
  let tagValue = undefined;
6
- for (const group of submenu.groups) {
7
- for (const link of group.links) {
6
+ for (const group of submenu.groups){
7
+ for (const link of group.links){
8
8
  const ltv = link.counter;
9
9
  if (ltv) {
10
10
  if (typeof ltv === 'number') {
@@ -12,8 +12,7 @@ export function getSubmenuGroupTag(submenu, defaultTag) {
12
12
  tagValue = 0;
13
13
  }
14
14
  tagValue += ltv;
15
- }
16
- else if (typeof tagValue !== 'number') {
15
+ } else if (typeof tagValue !== 'number') {
17
16
  tagValue = true;
18
17
  }
19
18
  }
@@ -21,8 +20,12 @@ export function getSubmenuGroupTag(submenu, defaultTag) {
21
20
  }
22
21
  return tagValue ? getCounterTag(tagValue) : defaultTag;
23
22
  }
24
- export const getCounterTag = (counter, tag) => {
23
+ export const getCounterTag = (counter, tag)=>{
25
24
  const value = counter !== null && counter !== void 0 ? counter : tag === null || tag === void 0 ? void 0 : tag.value;
26
- return value ? { value, className: '' } : undefined;
25
+ return value ? {
26
+ value,
27
+ className: ''
28
+ } : undefined;
27
29
  };
30
+
28
31
  //# sourceMappingURL=side-nav.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"side-nav.js","sourceRoot":"","sources":["../../src/utils/side-nav.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,kBAAkB,CAC9B,OAA0C,EAC1C,UAAuC;IAEvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,IAAI,QAAQ,GAAiC,SAAS,CAAC;IAEvD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAiC,IAAI,CAAC,OAAO,CAAC;YAEvD,IAAI,GAAG,EAAE,CAAC;gBACN,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBAC1B,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;wBAC/B,QAAQ,GAAG,CAAC,CAAC;oBACjB,CAAC;oBACD,QAAQ,IAAI,GAAG,CAAC;gBACpB,CAAC;qBAAM,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBACtC,QAAQ,GAAG,IAAI,CAAC;gBACpB,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CACzB,OAAoC,EACpC,GAAoB,EACO,EAAE;IAC7B,MAAM,KAAK,GAAG,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,KAAK,CAAC;IAEpC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC,CAAC"}
1
+ {"version":3,"sources":["../../src/utils/side-nav.ts"],"sourcesContent":["import { CounterTagProps } from '../components/counter-tag';\nimport { CounterTagData, CounterTagValue } from './counter-tag';\nimport { NavigationSubmenuData } from './navigation';\n\nexport function getSubmenuGroupTag(\n submenu: NavigationSubmenuData | undefined,\n defaultTag: CounterTagProps | undefined\n): CounterTagProps | undefined {\n if (!submenu) {\n return defaultTag;\n }\n\n let tagValue: number | boolean | undefined = undefined;\n\n for (const group of submenu.groups) {\n for (const link of group.links) {\n const ltv: number | boolean | undefined = link.counter;\n\n if (ltv) {\n if (typeof ltv === 'number') {\n if (typeof tagValue !== 'number') {\n tagValue = 0;\n }\n tagValue += ltv;\n } else if (typeof tagValue !== 'number') {\n tagValue = true;\n }\n }\n }\n }\n\n return tagValue ? getCounterTag(tagValue) : defaultTag;\n}\n\nexport const getCounterTag = (\n counter: CounterTagValue | undefined,\n tag?: CounterTagData\n): CounterTagProps | undefined => {\n const value = counter ?? tag?.value;\n\n return value ? { value, className: '' } : undefined;\n};\n"],"names":["getSubmenuGroupTag","submenu","defaultTag","tagValue","undefined","group","groups","link","links","ltv","counter","getCounterTag","tag","value","className"],"mappings":"AAIA,OAAO,SAASA,mBACZC,OAA0C,EAC1CC,UAAuC;IAEvC,IAAI,CAACD,SAAS;QACV,OAAOC;IACX;IAEA,IAAIC,WAAyCC;IAE7C,KAAK,MAAMC,SAASJ,QAAQK,MAAM,CAAE;QAChC,KAAK,MAAMC,QAAQF,MAAMG,KAAK,CAAE;YAC5B,MAAMC,MAAoCF,KAAKG,OAAO;YAEtD,IAAID,KAAK;gBACL,IAAI,OAAOA,QAAQ,UAAU;oBACzB,IAAI,OAAON,aAAa,UAAU;wBAC9BA,WAAW;oBACf;oBACAA,YAAYM;gBAChB,OAAO,IAAI,OAAON,aAAa,UAAU;oBACrCA,WAAW;gBACf;YACJ;QACJ;IACJ;IAEA,OAAOA,WAAWQ,cAAcR,YAAYD;AAChD;AAEA,OAAO,MAAMS,gBAAgB,CACzBD,SACAE;IAEA,MAAMC,QAAQH,oBAAAA,qBAAAA,UAAWE,gBAAAA,0BAAAA,IAAKC,KAAK;IAEnC,OAAOA,QAAQ;QAAEA;QAAOC,WAAW;IAAG,IAAIV;AAC9C,EAAE"}
@@ -1,14 +1,17 @@
1
1
  import { useBreakpoint } from '@servicetitan/anvil2';
2
2
  import { useMemo } from 'react';
3
- export const useTitanBreakpoint = () => {
3
+ export const useTitanBreakpoint = ()=>{
4
4
  const breakpoint = useBreakpoint();
5
- return useMemo(() => {
6
- var _a, _b;
7
- return ({
8
- name: (_a = breakpoint === null || breakpoint === void 0 ? void 0 : breakpoint.name) !== null && _a !== void 0 ? _a : 'xl',
5
+ return useMemo(()=>{
6
+ var _breakpoint_name, _breakpoint_innerWidth;
7
+ return {
8
+ name: (_breakpoint_name = breakpoint === null || breakpoint === void 0 ? void 0 : breakpoint.name) !== null && _breakpoint_name !== void 0 ? _breakpoint_name : 'xl',
9
9
  isMobile: breakpoint ? breakpoint.innerWidth < 768 : false,
10
- width: (_b = breakpoint === null || breakpoint === void 0 ? void 0 : breakpoint.innerWidth) !== null && _b !== void 0 ? _b : 0,
11
- });
12
- }, [breakpoint]);
10
+ width: (_breakpoint_innerWidth = breakpoint === null || breakpoint === void 0 ? void 0 : breakpoint.innerWidth) !== null && _breakpoint_innerWidth !== void 0 ? _breakpoint_innerWidth : 0
11
+ };
12
+ }, [
13
+ breakpoint
14
+ ]);
13
15
  };
16
+
14
17
  //# sourceMappingURL=use-breakpoint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-breakpoint.js","sourceRoot":"","sources":["../../src/utils/use-breakpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAQhC,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAoB,EAAE;IACpD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,OAAO,OAAO,CACV,GAAG,EAAE;;QAAC,OAAA,CAAC;YACH,IAAI,EAAE,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,IAAI,mCAAI,IAAI;YAC9B,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK;YAC1D,KAAK,EAAE,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,UAAU,mCAAI,CAAC;SACrC,CAAC,CAAA;KAAA,EACF,CAAC,UAAU,CAAC,CACf,CAAC;AACN,CAAC,CAAC"}
1
+ {"version":3,"sources":["../../src/utils/use-breakpoint.ts"],"sourcesContent":["import { BreakpointReturnProps, useBreakpoint } from '@servicetitan/anvil2';\nimport { useMemo } from 'react';\n\nexport interface TitanBreakpoint {\n name: BreakpointReturnProps['name'];\n isMobile: boolean;\n width: number;\n}\n\nexport const useTitanBreakpoint = (): TitanBreakpoint => {\n const breakpoint = useBreakpoint();\n\n return useMemo(\n () => ({\n name: breakpoint?.name ?? 'xl',\n isMobile: breakpoint ? breakpoint.innerWidth < 768 : false,\n width: breakpoint?.innerWidth ?? 0,\n }),\n [breakpoint]\n );\n};\n"],"names":["useBreakpoint","useMemo","useTitanBreakpoint","breakpoint","name","isMobile","innerWidth","width"],"mappings":"AAAA,SAAgCA,aAAa,QAAQ,uBAAuB;AAC5E,SAASC,OAAO,QAAQ,QAAQ;AAQhC,OAAO,MAAMC,qBAAqB;IAC9B,MAAMC,aAAaH;IAEnB,OAAOC,QACH;YACUE,kBAECA;eAHJ;YACHC,MAAMD,CAAAA,mBAAAA,uBAAAA,iCAAAA,WAAYC,IAAI,cAAhBD,8BAAAA,mBAAoB;YAC1BE,UAAUF,aAAaA,WAAWG,UAAU,GAAG,MAAM;YACrDC,OAAOJ,CAAAA,yBAAAA,uBAAAA,iCAAAA,WAAYG,UAAU,cAAtBH,oCAAAA,yBAA0B;QACrC;OACA;QAACA;KAAW;AAEpB,EAAE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/navigation",
3
- "version": "11.0.0",
3
+ "version": "11.1.1",
4
4
  "description": "Navigation components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,9 +26,9 @@
26
26
  "react": ">=18.0.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@servicetitan/anvil2": "~1.47.1",
29
+ "@servicetitan/anvil2": "~1.49.2",
30
30
  "@servicetitan/design-system": "~14.5.1",
31
- "@servicetitan/react-ioc": "^30.3.1",
31
+ "@servicetitan/react-ioc": "^32.6.0",
32
32
  "@servicetitan/tokens": ">=12.1.11",
33
33
  "@testing-library/react": "^16.2.0",
34
34
  "mobx": "~6.10.2",
@@ -42,5 +42,5 @@
42
42
  "less": true,
43
43
  "webpack": false
44
44
  },
45
- "gitHead": "3d64834ce8f40a41b7cfc00e44110050e67bed5a"
45
+ "gitHead": "fc3ac25baf0fac6c2295807f9fb31afe4aa5da70"
46
46
  }
@@ -1,4 +1,4 @@
1
1
  export * from './header-navigation-tiny';
2
2
  export * from './side-navigation';
3
3
  export * from './side-navigation-links';
4
- export * from './interface';
4
+ export type * from './interface';
@@ -1,6 +1,7 @@
1
1
  import { FC } from 'react';
2
2
 
3
3
  export interface LogoTitanSvgProps {
4
+ className?: string;
4
5
  height?: number;
5
6
  width?: number;
6
7
  fill?: string;
@@ -13,11 +14,12 @@ export const LogoTitanSvg: FC<LogoTitanSvgProps> = props => {
13
14
  width: props.width ?? 116,
14
15
  height: props.height ?? 106,
15
16
  };
16
- const fill = props.fill ?? '#3A3A3A';
17
+ const fill = props.fill ?? 'currentColor';
17
18
  const mantleFill = props.mantleFill ?? fill;
18
19
 
19
20
  return (
20
21
  <svg
22
+ className={props.className}
21
23
  xmlns="http://www.w3.org/2000/svg"
22
24
  xmlnsXlink="http://www.w3.org/1999/xlink"
23
25
  {...dimensions}
@@ -96,7 +96,11 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
96
96
  ) : isLegacy ? (
97
97
  <ProfileLogo />
98
98
  ) : (
99
- <Icon size="large" svg={open ? SvgAccountActive : SvgAccountInactive} />
99
+ <Icon
100
+ className="c-inherit-i"
101
+ size="large"
102
+ svg={open ? SvgAccountActive : SvgAccountInactive}
103
+ />
100
104
  )}
101
105
 
102
106
  {!!info && (
@@ -121,7 +125,7 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
121
125
 
122
126
  <Icon
123
127
  svg={open ? SvgExpandLess : SvgExpandMore}
124
- className={classNames(Styles.expandIcon)}
128
+ className={classNames(Styles.expandIcon, 'c-inherit-i')}
125
129
  size="small"
126
130
  />
127
131
 
@@ -215,7 +219,7 @@ export const ProfileDropdownSection: FC<ProfileDropdownSectionProps> = ({
215
219
  {tagElement}
216
220
  </div>,
217
221
  tooltip,
218
- 'left'
222
+ { placement: 'left' }
219
223
  );
220
224
  };
221
225
 
@@ -294,7 +298,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
294
298
  </NavigationComponent>
295
299
  ),
296
300
  tooltip,
297
- 'left'
301
+ { placement: 'left' }
298
302
  );
299
303
  };
300
304
 
@@ -1,5 +1,5 @@
1
1
  export * from './titan-layout';
2
2
  export * from './layout-profile';
3
3
  export * from './layout-context';
4
- export * from './layout-logo';
5
- export * from './interface';
4
+ export type { TitanLayoutLogoProps } from './layout-logo';
5
+ export type * from './interface';
@@ -0,0 +1,186 @@
1
+ import { ButtonCompound, Icon, Menu } from '@servicetitan/anvil2';
2
+ import SvgMoreVert from '@servicetitan/anvil2/assets/icons/material/round/more_vert.svg';
3
+ import classNames from 'classnames';
4
+ import { FC, useCallback, useEffect, useRef, useState } from 'react';
5
+ import { NavigationItemData } from '../../utils/navigation';
6
+ import { LayoutHeader, LayoutHeaderProps } from './layout-header';
7
+ import { LayoutHeaderNavigationLink } from './layout-header-links';
8
+ import * as Styles from './layout-header.module.less';
9
+ import { withTooltip } from './with-tooltip';
10
+
11
+ function useForceUpdate() {
12
+ const [, setTick] = useState(0);
13
+ return useCallback(() => {
14
+ setTick(tick => tick + 1);
15
+ }, []);
16
+ }
17
+
18
+ enum MinimizedState {
19
+ Calculating,
20
+ Minimized,
21
+ Full,
22
+ }
23
+
24
+ interface LayoutHeaderStackedProps extends Omit<LayoutHeaderProps, 'variant'> {
25
+ navigationMainItems?: NavigationItemData[];
26
+ navigationOverflowItems?: NavigationItemData[];
27
+ }
28
+
29
+ export const LayoutHeaderDark: FC<LayoutHeaderStackedProps> = ({
30
+ className,
31
+ isMobile,
32
+ navigationMainItems,
33
+ navigationOverflowItems,
34
+ hasNotifications,
35
+ onBurgerClick,
36
+ logo,
37
+ profile,
38
+ right,
39
+ rightText,
40
+ rightClassName,
41
+ center,
42
+ centerClassName,
43
+ ...rest
44
+ }) => {
45
+ return center ? (
46
+ <div
47
+ className={classNames(Styles.headerStacked, className)}
48
+ data-cy="header-navigation"
49
+ {...rest}
50
+ >
51
+ <LayoutHeader
52
+ variant="dark"
53
+ right={right}
54
+ rightText={rightText}
55
+ rightClassName={rightClassName}
56
+ center={center}
57
+ centerClassName={centerClassName}
58
+ isMobile={isMobile}
59
+ hasNotifications={hasNotifications}
60
+ logo={logo}
61
+ profile={profile}
62
+ onBurgerClick={onBurgerClick}
63
+ data-cy="header-navigation-top"
64
+ />
65
+
66
+ {!isMobile && (
67
+ <LayoutHeaderNav
68
+ className={Styles.headerStackedNav}
69
+ mainItems={navigationMainItems}
70
+ overflowItems={navigationOverflowItems}
71
+ />
72
+ )}
73
+ </div>
74
+ ) : (
75
+ <LayoutHeader
76
+ variant="dark"
77
+ className={classNames(className, !isMobile && Styles.headerDesktopNav)}
78
+ right={right}
79
+ rightText={rightText}
80
+ rightClassName={rightClassName}
81
+ center={
82
+ isMobile ? undefined : (
83
+ <LayoutHeaderNav
84
+ mainItems={navigationMainItems}
85
+ overflowItems={navigationOverflowItems}
86
+ />
87
+ )
88
+ }
89
+ centerClassName={centerClassName}
90
+ isMobile={isMobile}
91
+ hasNotifications={hasNotifications}
92
+ logo={logo}
93
+ profile={profile}
94
+ onBurgerClick={onBurgerClick}
95
+ {...rest}
96
+ />
97
+ );
98
+ };
99
+
100
+ interface LayoutHeaderNavProps {
101
+ className?: string;
102
+ mainItems?: NavigationItemData[];
103
+ overflowItems?: NavigationItemData[];
104
+ }
105
+ const LayoutHeaderNav: FC<LayoutHeaderNavProps> = ({ className, mainItems, overflowItems }) => {
106
+ const containerRef = useRef<HTMLDivElement>(null);
107
+ const navigationRef = useRef<HTMLDivElement>(null);
108
+ const forceUpdate = useForceUpdate();
109
+ const [minimized, setMinimized] = useState(MinimizedState.Calculating);
110
+
111
+ useEffect(() => {
112
+ const handleResize = () => {
113
+ setMinimized(MinimizedState.Calculating);
114
+ forceUpdate();
115
+ };
116
+
117
+ window.addEventListener('resize', handleResize);
118
+ return () => window.removeEventListener('resize', handleResize);
119
+ }, [forceUpdate]);
120
+
121
+ const updateIsMinimized = () => {
122
+ if (containerRef.current && navigationRef.current) {
123
+ if (navigationRef.current.clientWidth + 16 > containerRef.current.clientWidth) {
124
+ setMinimized(MinimizedState.Minimized);
125
+ } else if (minimized === MinimizedState.Calculating) {
126
+ setMinimized(MinimizedState.Full);
127
+ }
128
+ }
129
+ };
130
+
131
+ useEffect(() => {
132
+ updateIsMinimized();
133
+ });
134
+
135
+ useEffect(() => {
136
+ setMinimized(MinimizedState.Calculating);
137
+ forceUpdate();
138
+ }, [forceUpdate]);
139
+
140
+ const isMinimized = minimized === MinimizedState.Minimized;
141
+
142
+ return (
143
+ <div
144
+ ref={containerRef}
145
+ className={classNames(Styles.headerNavigationWrapper, className, {
146
+ [Styles.calculating]: minimized === MinimizedState.Calculating,
147
+ })}
148
+ data-cy="navigation-items"
149
+ >
150
+ <div ref={navigationRef} className={classNames(Styles.headerNavigation)}>
151
+ {mainItems?.map(item =>
152
+ withTooltip(
153
+ <LayoutHeaderNavigationLink
154
+ {...item}
155
+ label={isMinimized ? undefined : item.title}
156
+ key={item.id}
157
+ />,
158
+ isMinimized ? item.title : undefined,
159
+ { key: item.id }
160
+ )
161
+ )}
162
+ </div>
163
+ {!!overflowItems?.length && <LayoutHeaderNavOverflow items={overflowItems} />}
164
+ </div>
165
+ );
166
+ };
167
+
168
+ const LayoutHeaderNavOverflow: FC<{
169
+ items: NavigationItemData[];
170
+ }> = ({ items }) => {
171
+ return (
172
+ <Menu
173
+ trigger={props => (
174
+ <ButtonCompound {...props} className={Styles.headerNavigationOverflowTrigger}>
175
+ <Icon svg={SvgMoreVert} size="medium" />
176
+ </ButtonCompound>
177
+ )}
178
+ contentClassName={Styles.headerNavigationOverflow}
179
+ placement="bottom-end"
180
+ >
181
+ {items.map(item => (
182
+ <LayoutHeaderNavigationLink {...item} label={item.title} key={item.id} />
183
+ ))}
184
+ </Menu>
185
+ );
186
+ };
@@ -66,6 +66,7 @@ export const LayoutHeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
66
66
  labelClassName,
67
67
  tag,
68
68
  target,
69
+ title,
69
70
  ...rest
70
71
  }) => {
71
72
  const { NavigationComponent } = useTitanLayoutContext();
@@ -77,7 +78,6 @@ export const LayoutHeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
77
78
  {...rest}
78
79
  key={id}
79
80
  to={to}
80
- title={hint}
81
81
  className={classNames(Styles.navigationLink, className, {
82
82
  [Styles.navigationItemActive]: isActive === true,
83
83
  [Styles.navigationItemIconState]: !!icon && !!iconActive,