@servicetitan/navigation 9.2.1 → 10.0.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 (102) hide show
  1. package/dist/components/counter-tag.d.ts +4 -4
  2. package/dist/components/counter-tag.d.ts.map +1 -1
  3. package/dist/components/counter-tag.js +2 -8
  4. package/dist/components/counter-tag.js.map +1 -1
  5. package/dist/components/header-navigation/header-navigation-content.d.ts +3 -3
  6. package/dist/components/header-navigation/header-navigation-content.d.ts.map +1 -1
  7. package/dist/components/header-navigation/header-navigation-content.js +3 -2
  8. package/dist/components/header-navigation/header-navigation-content.js.map +1 -1
  9. package/dist/components/header-navigation/header-navigation-extra.stories.js +3 -3
  10. package/dist/components/header-navigation/header-navigation-extra.stories.js.map +1 -1
  11. package/dist/components/header-navigation/header-navigation-links.d.ts +1 -1
  12. package/dist/components/header-navigation/header-navigation-links.d.ts.map +1 -1
  13. package/dist/components/header-navigation/header-navigation-links.js +5 -4
  14. package/dist/components/header-navigation/header-navigation-links.js.map +1 -1
  15. package/dist/components/header-navigation/header-navigation-stacked.stories.js +1 -1
  16. package/dist/components/header-navigation/header-navigation-stacked.stories.js.map +1 -1
  17. package/dist/components/header-navigation/header-navigation.d.ts +1 -1
  18. package/dist/components/header-navigation/header-navigation.d.ts.map +1 -1
  19. package/dist/components/header-navigation/header-navigation.js.map +1 -1
  20. package/dist/components/header-navigation/header-navigation.stories.js +1 -1
  21. package/dist/components/header-navigation/header-navigation.stories.js.map +1 -1
  22. package/dist/components/header-navigation/with-tooltip.d.ts +1 -1
  23. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts +3 -3
  24. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts.map +1 -1
  25. package/dist/components/left-navigation/header-navigation-tiny-links.js +5 -4
  26. package/dist/components/left-navigation/header-navigation-tiny-links.js.map +1 -1
  27. package/dist/components/left-navigation/header-navigation-tiny.stories.js +2 -2
  28. package/dist/components/left-navigation/header-navigation-tiny.stories.js.map +1 -1
  29. package/dist/components/left-navigation/interface-internal.d.ts +1 -1
  30. package/dist/components/left-navigation/interface-internal.d.ts.map +1 -1
  31. package/dist/components/left-navigation/interface.d.ts +2 -2
  32. package/dist/components/left-navigation/interface.d.ts.map +1 -1
  33. package/dist/components/left-navigation/side-navigation-links-internal.d.ts +7 -4
  34. package/dist/components/left-navigation/side-navigation-links-internal.d.ts.map +1 -1
  35. package/dist/components/left-navigation/side-navigation-links-internal.js.map +1 -1
  36. package/dist/components/left-navigation/side-navigation-links.d.ts.map +1 -1
  37. package/dist/components/left-navigation/side-navigation-links.js +3 -2
  38. package/dist/components/left-navigation/side-navigation-links.js.map +1 -1
  39. package/dist/components/left-navigation/side-navigation.d.ts +2 -2
  40. package/dist/components/left-navigation/side-navigation.d.ts.map +1 -1
  41. package/dist/components/left-navigation/side-navigation.js +5 -5
  42. package/dist/components/left-navigation/side-navigation.js.map +1 -1
  43. package/dist/components/links.d.ts +1 -1
  44. package/dist/components/links.d.ts.map +1 -1
  45. package/dist/components/links.js.map +1 -1
  46. package/dist/components/profile-dropdown/profile-dropdown.d.ts +3 -2
  47. package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
  48. package/dist/components/profile-dropdown/profile-dropdown.js +3 -2
  49. package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
  50. package/dist/components/profile-dropdown/profile-dropdown.stories.d.ts.map +1 -1
  51. package/dist/components/profile-dropdown/profile-dropdown.stories.js +1 -1
  52. package/dist/components/profile-dropdown/profile-dropdown.stories.js.map +1 -1
  53. package/dist/index.d.ts +2 -1
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +2 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/test/data.d.ts +2 -1
  58. package/dist/test/data.d.ts.map +1 -1
  59. package/dist/test/data.js +10 -7
  60. package/dist/test/data.js.map +1 -1
  61. package/dist/utils/counter-tag.d.ts +3 -6
  62. package/dist/utils/counter-tag.d.ts.map +1 -1
  63. package/dist/utils/counter-tag.js +1 -1
  64. package/dist/utils/counter-tag.js.map +1 -1
  65. package/dist/utils/navigation-context.d.ts +13 -2
  66. package/dist/utils/navigation-context.d.ts.map +1 -1
  67. package/dist/utils/navigation-context.js.map +1 -1
  68. package/dist/utils/navigation-legacy.d.ts +86 -0
  69. package/dist/utils/navigation-legacy.d.ts.map +1 -0
  70. package/dist/utils/navigation-legacy.js +2 -0
  71. package/dist/utils/navigation-legacy.js.map +1 -0
  72. package/dist/utils/navigation.d.ts +15 -76
  73. package/dist/utils/navigation.d.ts.map +1 -1
  74. package/dist/utils/side-nav.d.ts +5 -2
  75. package/dist/utils/side-nav.d.ts.map +1 -1
  76. package/dist/utils/side-nav.js +6 -5
  77. package/dist/utils/side-nav.js.map +1 -1
  78. package/package.json +2 -2
  79. package/src/components/counter-tag.tsx +10 -21
  80. package/src/components/header-navigation/header-navigation-content.tsx +6 -4
  81. package/src/components/header-navigation/header-navigation-extra.stories.tsx +3 -3
  82. package/src/components/header-navigation/header-navigation-links.tsx +9 -3
  83. package/src/components/header-navigation/header-navigation-stacked.stories.tsx +2 -2
  84. package/src/components/header-navigation/header-navigation.stories.tsx +2 -2
  85. package/src/components/header-navigation/header-navigation.tsx +1 -1
  86. package/src/components/left-navigation/header-navigation-tiny-links.tsx +11 -5
  87. package/src/components/left-navigation/header-navigation-tiny.stories.tsx +2 -2
  88. package/src/components/left-navigation/interface-internal.ts +1 -1
  89. package/src/components/left-navigation/interface.ts +2 -3
  90. package/src/components/left-navigation/side-navigation-links-internal.tsx +7 -5
  91. package/src/components/left-navigation/side-navigation-links.tsx +7 -1
  92. package/src/components/left-navigation/side-navigation.tsx +12 -10
  93. package/src/components/links.tsx +4 -1
  94. package/src/components/profile-dropdown/profile-dropdown.stories.tsx +4 -1
  95. package/src/components/profile-dropdown/profile-dropdown.tsx +10 -3
  96. package/src/index.ts +6 -1
  97. package/src/test/data.tsx +17 -18
  98. package/src/utils/counter-tag.ts +3 -9
  99. package/src/utils/navigation-context.tsx +15 -2
  100. package/src/utils/navigation-legacy.ts +104 -0
  101. package/src/utils/navigation.ts +15 -85
  102. package/src/utils/side-nav.ts +17 -9
@@ -17,12 +17,12 @@ import {
17
17
  useMemo,
18
18
  } from 'react';
19
19
  import {
20
- HeaderNavigationItemData,
21
- HeaderNavigationItemSubmenu,
22
- HeaderNavigationItemSubmenuLink,
20
+ NavigationItemData,
21
+ NavigationSubmenuData,
22
+ NavigationSubmenuItemData,
23
23
  } from '../../utils/navigation';
24
24
  import { NavigationComponentContext } from '../../utils/navigation-context';
25
- import { getSubmenuGroupTag } from '../../utils/side-nav';
25
+ import { getCounterTag, getSubmenuGroupTag } from '../../utils/side-nav';
26
26
  import { CounterTag } from '../counter-tag';
27
27
  import {
28
28
  SideNavigationExpandedState,
@@ -44,7 +44,7 @@ export interface SideNavigationProps {
44
44
  /** container id */
45
45
  id?: string;
46
46
  /** main navigation items */
47
- items?: HeaderNavigationItemData[];
47
+ items?: NavigationItemData[];
48
48
  /** additional components */
49
49
  children?: OptionalChildren<SideNavigationTopProps>;
50
50
  /** is menu expanded */
@@ -119,6 +119,7 @@ function SideNavigationElement({
119
119
  submenuExpanded={undefined}
120
120
  navigationComponent={NavigationComponent}
121
121
  {...item}
122
+ tag={getCounterTag(item.counter, item.tag)}
122
123
  />
123
124
  )
124
125
  )}
@@ -155,7 +156,7 @@ const SideNavigationTop: FC<SideNavigationTopProps> = SideNavigationTopElement;
155
156
 
156
157
  /** Side Navigation menu item */
157
158
  const SideNavigationGroupItem: FC<
158
- HeaderNavigationItemData &
159
+ NavigationItemData &
159
160
  SideNavigationExpandedProps &
160
161
  NavigationComponentProps & {
161
162
  onExpandedChange: undefined | ((expanded: SideNavigationExpandedState) => void);
@@ -178,7 +179,7 @@ const SideNavigationGroupItem: FC<
178
179
  [props.id, props.expanded, isSubmenuExpanded, onExpandedChange]
179
180
  );
180
181
 
181
- const tag = getSubmenuGroupTag(props.submenu, props.tag);
182
+ const tag = getSubmenuGroupTag(props.submenu, getCounterTag(props.counter, props.tag));
182
183
  const context = useContext(SideNavigationContext);
183
184
 
184
185
  return props.expanded?.bar ? (
@@ -226,7 +227,7 @@ const SideNavigationGroupItem: FC<
226
227
  </Popover>
227
228
  );
228
229
  };
229
- const SideNavigationGroupContent: FC<HeaderNavigationItemSubmenu & NavigationComponentProps> = ({
230
+ const SideNavigationGroupContent: FC<NavigationSubmenuData & NavigationComponentProps> = ({
230
231
  groups,
231
232
  navigationComponent,
232
233
  }) => {
@@ -258,8 +259,9 @@ const SideNavigationGroupContent: FC<HeaderNavigationItemSubmenu & NavigationCom
258
259
  </Fragment>
259
260
  );
260
261
  };
261
- const SideNavigationGroupLink: FC<HeaderNavigationItemSubmenuLink & NavigationComponentProps> = ({
262
+ const SideNavigationGroupLink: FC<NavigationSubmenuItemData & NavigationComponentProps> = ({
262
263
  id,
264
+ counter,
263
265
  tag,
264
266
  title,
265
267
  to,
@@ -279,7 +281,7 @@ const SideNavigationGroupLink: FC<HeaderNavigationItemSubmenuLink & NavigationCo
279
281
  activeClassName={Styles.submenuLinkActive}
280
282
  >
281
283
  <span>{title}</span>
282
- {!!tag && <CounterTag data={tag} className={Styles.submenuLinkCounter} />}
284
+ <CounterTag data={getCounterTag(counter, tag)} className={Styles.submenuLinkCounter} />
283
285
  </NavigationComponent>
284
286
  );
285
287
  };
@@ -1,6 +1,9 @@
1
1
  import { FC, useContext } from 'react';
2
- import { HeaderNavigationLinkProps, HeaderNavigationTriggerProps } from '../utils/navigation';
3
2
  import { NavigationLegacyContext } from '../utils/navigation-context';
3
+ import {
4
+ HeaderNavigationLinkProps,
5
+ HeaderNavigationTriggerProps,
6
+ } from '../utils/navigation-legacy';
4
7
  import {
5
8
  HeaderNavigationLink as HeaderNavigationLinkLegacy,
6
9
  HeaderNavigationTrigger as HeaderNavigationTriggerLegacy,
@@ -112,11 +112,14 @@ export const ProfileDropdownWithHintPopup = () => (
112
112
  onOpen={() => log('open profile dropdown')}
113
113
  onClose={() => log('close profile dropdown')}
114
114
  >
115
- <ProfileDropdown.Link id="first" to="https://google.com">
115
+ <ProfileDropdown.Link id="first" to="https://google.com" counter={12}>
116
116
  first item
117
117
  </ProfileDropdown.Link>
118
118
  <ProfileDropdown.Divider />
119
119
  <ProfileDropdown.Section id="second">second item</ProfileDropdown.Section>
120
+ <ProfileDropdown.Link id="third" to="https://google.com" tag={{ value: 1 }}>
121
+ third item
122
+ </ProfileDropdown.Link>
120
123
  </ProfileDropdown>
121
124
  );
122
125
 
@@ -18,11 +18,13 @@ import {
18
18
  useState,
19
19
  } from 'react';
20
20
 
21
+ import { CounterTagData, CounterTagValue } from '../../utils/counter-tag';
21
22
  import {
22
23
  NavigationComponentContext,
23
24
  NavigationLegacyContext,
24
25
  } from '../../utils/navigation-context';
25
- import { CounterTag, CounterTagPropsType } from '../counter-tag';
26
+ import { getCounterTag } from '../../utils/side-nav';
27
+ import { CounterTag } from '../counter-tag';
26
28
  import * as Styles from './profile-dropdown.module.less';
27
29
  import { ProfileLogo } from './profile-icon';
28
30
 
@@ -192,7 +194,8 @@ export interface ProfileDropdownLinkPropsStrict {
192
194
  external?: boolean;
193
195
  target?: HTMLAttributeAnchorTarget;
194
196
  to?: string;
195
- tag?: CounterTagPropsType;
197
+ tag?: CounterTagData;
198
+ counter?: CounterTagValue;
196
199
  onClick?: () => void;
197
200
  }
198
201
 
@@ -205,6 +208,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
205
208
  className,
206
209
  external,
207
210
  id,
211
+ counter,
208
212
  tag,
209
213
  target,
210
214
  to,
@@ -220,7 +224,10 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
220
224
 
221
225
  const isExternalLink = external ?? to?.startsWith('http');
222
226
 
223
- const tagElement = useMemo(() => <CounterTag data={tag} className={Styles.counter} />, [tag]);
227
+ const tagElement = useMemo(
228
+ () => <CounterTag data={getCounterTag(counter, tag)} className={Styles.counter} />,
229
+ [counter, tag]
230
+ );
224
231
 
225
232
  return isExternalLink ? (
226
233
  <a
package/src/index.ts CHANGED
@@ -7,4 +7,9 @@ export * from './components/counter-tag';
7
7
  export * from './components/left-navigation';
8
8
  export * from './components/links';
9
9
  export * from './utils/navigation';
10
- export { NavigationComponentContext } from './utils/navigation-context';
10
+ export {
11
+ NavigationComponentContext,
12
+ NavLinkComponentPropsStrict,
13
+ NavLinkComponentProps,
14
+ } from './utils/navigation-context';
15
+ export * from './utils/navigation-legacy';
package/src/test/data.tsx CHANGED
@@ -38,13 +38,9 @@ import { Fragment, forwardRef, useState } from 'react';
38
38
  // eslint-disable-next-line import/no-extraneous-dependencies
39
39
  import { MemoryRouter, Redirect, Switch, useHistory, useLocation } from 'react-router-dom';
40
40
  import { HeaderNavigationTrigger } from '../components/links';
41
- import {
42
- HeaderNavigationItemData,
43
- HeaderNavigationItemSubmenuGroup,
44
- HeaderNavigationItemSubmenuLink,
45
- NavLinkComponentProps,
46
- } from '../utils/navigation';
47
- import { NavigationComponentContext } from '../utils/navigation-context';
41
+ import { NavigationSubmenuGroupData, NavigationSubmenuItemData } from '../utils/navigation';
42
+ import { NavLinkComponentProps, NavigationComponentContext } from '../utils/navigation-context';
43
+ import { HeaderNavigationItemData } from '../utils/navigation-legacy';
48
44
  import * as Styles from './data-stories.module.less';
49
45
 
50
46
  export const NavLinkMock = forwardRef<any, NavLinkComponentProps>(
@@ -145,8 +141,8 @@ const getItem = (
145
141
 
146
142
  const getSubItem = (
147
143
  id: string,
148
- data: Partial<HeaderNavigationItemSubmenuLink>
149
- ): HeaderNavigationItemSubmenuLink => ({
144
+ data: Partial<NavigationSubmenuItemData>
145
+ ): NavigationSubmenuItemData => ({
150
146
  id,
151
147
  to: id,
152
148
  title: id[0].toUpperCase() + id.substring(1),
@@ -155,8 +151,8 @@ const getSubItem = (
155
151
 
156
152
  const getGroup = (
157
153
  title: string,
158
- links: HeaderNavigationItemSubmenuLink[]
159
- ): HeaderNavigationItemSubmenuGroup => ({
154
+ links: NavigationSubmenuItemData[]
155
+ ): NavigationSubmenuGroupData => ({
160
156
  title,
161
157
  links,
162
158
  });
@@ -176,7 +172,7 @@ export const items = {
176
172
  iconName: 'local_phone',
177
173
  icon: SvgCalls,
178
174
  iconActive: SvgCallsActive,
179
- tag: 12,
175
+ counter: 12,
180
176
  }),
181
177
  dashboard: getItem('dashboard', {
182
178
  iconName: 'odometer',
@@ -187,7 +183,7 @@ export const items = {
187
183
  iconName: 'location_disabled',
188
184
  icon: SvgDispatch,
189
185
  iconActive: SvgDispatchActive,
190
- tag: 1,
186
+ tag: { value: 3 },
191
187
  }),
192
188
  fleet: getItem('fleet', {
193
189
  iconName: 'fleet-pro',
@@ -241,7 +237,7 @@ export const items = {
241
237
  iconName: 'assignment',
242
238
  icon: SvgAccounting,
243
239
  iconActive: SvgAccountingActive,
244
- tag: true,
240
+ counter: true,
245
241
  }),
246
242
  accountingWithSubmenu: getItem('accounting', {
247
243
  iconName: 'assignment',
@@ -251,9 +247,12 @@ export const items = {
251
247
  groups: [
252
248
  getGroup('Accounts Receivable', [
253
249
  getSubItem('ar', { title: 'AR Management' }),
254
- getSubItem('export', { title: 'Batch/Export Transactions', tag: true }),
255
- getSubItem('invoices', { title: 'Invoices', tag: 3 }),
256
- getSubItem('payments', { title: 'Customer Payments', tag: 2 }),
250
+ getSubItem('export', {
251
+ title: 'Batch/Export Transactions',
252
+ counter: true,
253
+ }),
254
+ getSubItem('invoices', { title: 'Invoices', counter: 3 }),
255
+ getSubItem('payments', { title: 'Customer Payments', counter: 2 }),
257
256
  getSubItem('deposits', { title: 'Bank Deposits' }),
258
257
  ]),
259
258
  getGroup('Accounts Payable', [getSubItem('bills', { title: 'Bills' })]),
@@ -307,7 +306,7 @@ export const CallsNavigationTrigger = () => {
307
306
  <HeaderNavigationTrigger
308
307
  id="dialpad"
309
308
  iconName="phone"
310
- tag={2}
309
+ counter={2}
311
310
  icon={SvgPhone}
312
311
  iconActive={SvgPhoneActive}
313
312
  onClick={() => setOpen(!open)}
@@ -1,11 +1,5 @@
1
- import { CounterTagProps } from '../components/counter-tag';
1
+ export type CounterTagValue = boolean | number;
2
2
 
3
- export interface CounterTagPropsStrict {
4
- value: number | boolean;
5
- className?: string;
3
+ export interface CounterTagData {
4
+ value: CounterTagValue;
6
5
  }
7
-
8
- export type CounterTagType = boolean | number | CounterTagProps;
9
-
10
- export const isCounterPropsObject = (tag?: CounterTagType): tag is CounterTagProps =>
11
- !!tag && (tag as any).value !== undefined;
@@ -1,5 +1,18 @@
1
- import { FC, createContext } from 'react';
2
- import { NavLinkComponentProps } from './navigation';
1
+ import { FC, HTMLAttributeAnchorTarget, ReactNode, createContext } from 'react';
2
+
3
+ export interface NavLinkComponentPropsStrict {
4
+ to: string;
5
+ title?: string;
6
+ className?: string;
7
+ activeClassName?: string;
8
+ children: ReactNode;
9
+ isActive?: (pathname: string) => boolean;
10
+ target?: HTMLAttributeAnchorTarget;
11
+ }
12
+
13
+ export interface NavLinkComponentProps extends NavLinkComponentPropsStrict {
14
+ [key: string]: any;
15
+ }
3
16
 
4
17
  export const DefaultNavLinkComponent: FC<NavLinkComponentProps> = ({
5
18
  children,
@@ -0,0 +1,104 @@
1
+ import { IconProps } from '@servicetitan/anvil2';
2
+ import { IconPropsStrict } from '@servicetitan/design-system';
3
+ import { FC, HTMLAttributeAnchorTarget } from 'react';
4
+ import { CounterTagData, CounterTagValue } from './counter-tag';
5
+ import { NavigationSubmenuData } from './navigation';
6
+
7
+ export interface HeaderNavigationItemData extends HeaderNavigationItemLinkProps {
8
+ /** link description */
9
+ hint: string;
10
+
11
+ /** flag if the link is not shown (based on FG and/or user permissions) */
12
+ isHidden?: boolean;
13
+
14
+ /** custom className (can be used for mdi icons) */
15
+ iconClassName?: string;
16
+
17
+ /** anvil's icon name of item */
18
+ iconName?: IconPropsStrict['name'];
19
+
20
+ /** svg icon (anvil2) of inactive item */
21
+ icon: IconProps['svg'] | undefined;
22
+
23
+ /** svg icon (anvil2) of active item */
24
+ iconActive: IconProps['svg'] | undefined;
25
+
26
+ /** icon component of item (<svg />) */
27
+ iconComponent?: FC;
28
+
29
+ /** item tag (optional). shown if it is set and true or greater than 0 */
30
+ counter?: CounterTagValue;
31
+ tag?: CounterTagData;
32
+
33
+ /** class name of link item */
34
+ className?: string;
35
+
36
+ /** optional submenu of link item */
37
+ submenu?: NavigationSubmenuData;
38
+ }
39
+
40
+ export interface HeaderNavigationItemLinkProps {
41
+ /** link id */
42
+ id: string;
43
+
44
+ /** link href */
45
+ to: string;
46
+
47
+ /** link title */
48
+ title: string;
49
+
50
+ /** callback to return active state. By default, it compares link href with current pathname */
51
+ isActive?: boolean | ((pathname: string) => boolean);
52
+ }
53
+
54
+ export interface HeaderNavigationTriggerPropsStrict {
55
+ /** unique identifier */
56
+ id: string;
57
+ /** tooltip text */
58
+ tooltip?: string;
59
+ /** item description */
60
+ hint?: string;
61
+ /** container class name */
62
+ className?: string;
63
+ /** item label */
64
+ label?: string;
65
+ /** label class name */
66
+ labelClassName?: string;
67
+ /** isActive */
68
+ isActive?: boolean;
69
+ /** counter value shown for item */
70
+ counter?: CounterTagValue;
71
+ tag?: CounterTagData;
72
+ /** counter component class name */
73
+ counterClassName?: string;
74
+ /** icon component class name */
75
+ iconClassName?: string;
76
+ /** IconComponent custom icon component */
77
+ iconComponent?: FC;
78
+ /** iconName name of anvil icon */
79
+ iconName?: IconPropsStrict['name'];
80
+ /** svg icon (anvil2) of inactive item */
81
+ icon: IconProps['svg'] | undefined;
82
+ /** svg icon (anvil2) of active item */
83
+ iconActive: IconProps['svg'] | undefined;
84
+ }
85
+
86
+ export interface HeaderNavigationTriggerProps extends HeaderNavigationTriggerPropsStrict {
87
+ /** unstrict props */
88
+ [key: string]: any;
89
+ }
90
+
91
+ export interface HeaderNavigationLinkPropsStrict
92
+ extends Omit<HeaderNavigationTriggerPropsStrict, 'isActive'> {
93
+ /** link href */
94
+ to: string;
95
+ /** isActive */
96
+ isActive?: boolean | ((pathname: string) => boolean);
97
+ /** link html target */
98
+ target?: HTMLAttributeAnchorTarget;
99
+ }
100
+
101
+ export interface HeaderNavigationLinkProps extends HeaderNavigationLinkPropsStrict {
102
+ /** unstrict props */
103
+ [key: string]: any;
104
+ }
@@ -1,21 +1,14 @@
1
1
  import { IconProps } from '@servicetitan/anvil2';
2
- import { IconPropsStrict } from '@servicetitan/design-system';
3
- import { FC, HTMLAttributeAnchorTarget, ReactNode } from 'react';
4
- import { CounterTagPropsType } from '../components/counter-tag';
5
-
6
- export interface HeaderNavigationItemData extends HeaderNavigationItemLinkProps {
7
- /** link description */
8
- hint: string;
2
+ import { FC } from 'react';
3
+ import { CounterTagData, CounterTagValue } from './counter-tag';
9
4
 
5
+ export interface NavigationItemData extends NavigationLinkData {
10
6
  /** flag if the link is not shown (based on FG and/or user permissions) */
11
7
  isHidden?: boolean;
12
8
 
13
9
  /** custom className (can be used for mdi icons) */
14
10
  iconClassName?: string;
15
11
 
16
- /** anvil's icon name of item */
17
- iconName?: IconPropsStrict['name'];
18
-
19
12
  /** svg icon (anvil2) of inactive item */
20
13
  icon: IconProps['svg'] | undefined;
21
14
 
@@ -26,16 +19,17 @@ export interface HeaderNavigationItemData extends HeaderNavigationItemLinkProps
26
19
  iconComponent?: FC;
27
20
 
28
21
  /** item tag (optional). shown if it is set and true or greater than 0 */
29
- tag?: CounterTagPropsType;
22
+ counter?: CounterTagValue;
23
+ tag?: CounterTagData;
30
24
 
31
25
  /** class name of link item */
32
26
  className?: string;
33
27
 
34
28
  /** optional submenu of link item */
35
- submenu?: HeaderNavigationItemSubmenu;
29
+ submenu?: NavigationSubmenuData;
36
30
  }
37
31
 
38
- export interface HeaderNavigationItemLinkProps {
32
+ export interface NavigationLinkData {
39
33
  /** link id */
40
34
  id: string;
41
35
 
@@ -49,85 +43,21 @@ export interface HeaderNavigationItemLinkProps {
49
43
  isActive?: boolean | ((pathname: string) => boolean);
50
44
  }
51
45
 
52
- export interface HeaderNavigationItemSubmenu {
46
+ export interface NavigationSubmenuData {
53
47
  /** submenu groups */
54
- groups: HeaderNavigationItemSubmenuGroup[];
48
+ groups: NavigationSubmenuGroupData[];
55
49
  }
56
50
 
57
- export interface HeaderNavigationItemSubmenuLink extends HeaderNavigationItemLinkProps {
58
- /** item tag (optional). shown if it is set and true or greater than 0 */
59
- tag?: CounterTagPropsType;
51
+ export interface NavigationSubmenuItemData extends NavigationLinkData {
52
+ /** item tag (optional) value. shown if it is set and true or greater than 0 */
53
+ counter?: CounterTagValue;
54
+ tag?: CounterTagData;
60
55
  }
61
56
 
62
- export interface HeaderNavigationItemSubmenuGroup {
57
+ export interface NavigationSubmenuGroupData {
63
58
  /** submenu group title */
64
59
  title: string;
65
60
 
66
61
  /** submenu group links */
67
- links: HeaderNavigationItemSubmenuLink[];
68
- }
69
-
70
- export interface NavLinkComponentPropsStrict {
71
- to: string;
72
- title?: string;
73
- className?: string;
74
- activeClassName?: string;
75
- children: ReactNode;
76
- isActive?: (pathname: string) => boolean;
77
- target?: HTMLAttributeAnchorTarget;
78
- }
79
-
80
- export interface NavLinkComponentProps extends NavLinkComponentPropsStrict {
81
- [key: string]: any;
82
- }
83
-
84
- export interface HeaderNavigationTriggerPropsStrict {
85
- /** unique identifier */
86
- id: string;
87
- /** tooltip text */
88
- tooltip?: string;
89
- /** item description */
90
- hint?: string;
91
- /** container class name */
92
- className?: string;
93
- /** item label */
94
- label?: string;
95
- /** label class name */
96
- labelClassName?: string;
97
- /** isActive */
98
- isActive?: boolean;
99
- /** counter tag shown for item */
100
- tag?: CounterTagPropsType;
101
- /** counter component class name */
102
- counterClassName?: string;
103
- /** icon component class name */
104
- iconClassName?: string;
105
- /** IconComponent custom icon component */
106
- iconComponent?: FC;
107
- /** iconName name of anvil icon */
108
- iconName?: IconPropsStrict['name'];
109
- /** svg icon (anvil2) of inactive item */
110
- icon: IconProps['svg'] | undefined;
111
- /** svg icon (anvil2) of active item */
112
- iconActive: IconProps['svg'] | undefined;
113
- }
114
-
115
- export interface HeaderNavigationTriggerProps extends HeaderNavigationTriggerPropsStrict {
116
- /** unstrict props */
117
- [key: string]: any;
118
- }
119
-
120
- export interface HeaderNavigationLinkPropsStrict
121
- extends Omit<HeaderNavigationTriggerPropsStrict, 'isActive'> {
122
- /** link href */
123
- to: string;
124
- /** isActive */
125
- isActive?: boolean | ((pathname: string) => boolean);
126
- /** link html target */
127
- target?: HTMLAttributeAnchorTarget;
128
- }
129
-
130
- export interface HeaderNavigationLinkProps extends HeaderNavigationLinkPropsStrict {
131
- /** unstrict props */
132
- [key: string]: any;
62
+ links: NavigationSubmenuItemData[];
133
63
  }
@@ -1,10 +1,11 @@
1
- import { isCounterPropsObject } from './counter-tag';
2
- import { HeaderNavigationItemData, HeaderNavigationItemSubmenu } from './navigation';
1
+ import { CounterTagProps } from '../components/counter-tag';
2
+ import { CounterTagData, CounterTagValue } from './counter-tag';
3
+ import { NavigationSubmenuData } from './navigation';
3
4
 
4
5
  export function getSubmenuGroupTag(
5
- submenu: HeaderNavigationItemSubmenu | undefined,
6
- defaultTag: HeaderNavigationItemData['tag']
7
- ): HeaderNavigationItemData['tag'] {
6
+ submenu: NavigationSubmenuData | undefined,
7
+ defaultTag: CounterTagProps | undefined
8
+ ): CounterTagProps | undefined {
8
9
  if (!submenu) {
9
10
  return defaultTag;
10
11
  }
@@ -13,9 +14,7 @@ export function getSubmenuGroupTag(
13
14
 
14
15
  for (const group of submenu.groups) {
15
16
  for (const link of group.links) {
16
- const ltv: number | boolean | undefined = isCounterPropsObject(link.tag)
17
- ? link.tag.value
18
- : link.tag;
17
+ const ltv: number | boolean | undefined = link.counter;
19
18
 
20
19
  if (ltv) {
21
20
  if (typeof ltv === 'number') {
@@ -30,5 +29,14 @@ export function getSubmenuGroupTag(
30
29
  }
31
30
  }
32
31
 
33
- return tagValue ?? defaultTag;
32
+ return tagValue ? getCounterTag(tagValue) : defaultTag;
34
33
  }
34
+
35
+ export const getCounterTag = (
36
+ counter: CounterTagValue | undefined,
37
+ tag?: CounterTagData | undefined
38
+ ): CounterTagProps | undefined => {
39
+ const value = counter ?? tag?.value;
40
+
41
+ return value ? { value, className: '' } : undefined;
42
+ };