@servicetitan/navigation 9.2.1 → 10.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 (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 +9 -8
  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 +12 -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 +22 -15
  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
@@ -4,15 +4,16 @@ import SvgGroupExpand from '@servicetitan/anvil2/assets/icons/material/round/exp
4
4
 
5
5
  import classNames from 'classnames';
6
6
  import { FC, Fragment } from 'react';
7
- import { HeaderNavigationItemData } from '../../utils/navigation';
8
- import { CounterTag } from '../counter-tag';
7
+ import { NavigationItemData } from '../../utils/navigation';
8
+ import { CounterTag, CounterTagProps } from '../counter-tag';
9
9
  import { SideNavigationTriggerProps } from './interface';
10
10
  import { NavigationComponentProps, SideNavigationExpandedProps } from './interface-internal';
11
11
  import * as Styles from './side-navigation.module.less';
12
12
 
13
13
  export interface InternalSideNavigationItemContentProps
14
- extends Omit<HeaderNavigationItemData, 'iconName' | 'to' | ''> {
14
+ extends Omit<NavigationItemData, 'iconName' | 'to' | 'counter' | 'tag'> {
15
15
  submenuExpanded: boolean | undefined;
16
+ tag: CounterTagProps | undefined;
16
17
  }
17
18
 
18
19
  export const InternalSideNavigationItemContent: FC<InternalSideNavigationItemContentProps> = ({
@@ -76,11 +77,12 @@ export const InternalSideNavigationItemContent: FC<InternalSideNavigationItemCon
76
77
  );
77
78
 
78
79
  export interface InternalSideNavigationLinkProps
79
- extends Omit<HeaderNavigationItemData, 'iconName'>,
80
+ extends Omit<NavigationItemData, 'iconName' | 'counter' | 'tag'>,
80
81
  NavigationComponentProps,
81
82
  SideNavigationExpandedProps {
82
83
  submenuExpanded: boolean | undefined;
83
84
  dataPrefix?: string;
85
+ tag: CounterTagProps | undefined;
84
86
  }
85
87
 
86
88
  export const internalNavigationContentContainerProps = ({
@@ -91,7 +93,7 @@ export const internalNavigationContentContainerProps = ({
91
93
  id,
92
94
  isActive,
93
95
  prefix,
94
- }: Omit<SideNavigationTriggerProps, 'isActive'> & { prefix: string; isActive?: any }) => ({
96
+ }: Omit<SideNavigationTriggerProps, 'isActive' | 'tag'> & { prefix: string; isActive?: any }) => ({
95
97
  'data-cy': `${prefix}-${id}`,
96
98
  'data-pendo': `${prefix}-${id}`,
97
99
  'className': classNames(Styles.navigationItem, className, {
@@ -1,6 +1,7 @@
1
1
  import classNames from 'classnames';
2
2
  import { FC, ReactElement, useContext } from 'react';
3
3
  import { NavigationComponentContext } from '../../utils/navigation-context';
4
+ import { getCounterTag } from '../../utils/side-nav';
4
5
  import { SideNavigationLinkProps, SideNavigationTriggerProps } from './interface';
5
6
  import { SideNavigationContext } from './side-navigation-context';
6
7
  import {
@@ -27,6 +28,7 @@ export function SideNavigationLink({ wrapper, ...props }: SideNavigationLinkProp
27
28
  navigationComponent={NavigationComponent}
28
29
  submenuExpanded={undefined}
29
30
  dataPrefix="navigation-link"
31
+ tag={getCounterTag(props.counter, props.tag)}
30
32
  />
31
33
  );
32
34
 
@@ -44,7 +46,11 @@ export function SideNavigationTrigger({ wrapper, ...props }: SideNavigationTrigg
44
46
  isActive: props.isActive,
45
47
  })}
46
48
  >
47
- <InternalSideNavigationItemContent submenuExpanded={undefined} {...props} />
49
+ <InternalSideNavigationItemContent
50
+ submenuExpanded={undefined}
51
+ {...props}
52
+ tag={getCounterTag(props.counter, props.tag)}
53
+ />
48
54
  </div>
49
55
  );
50
56
  return wrapper ? <WrappedLink wrapper={wrapper}>{element}</WrappedLink> : element;
@@ -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
  }) => {
@@ -237,29 +238,35 @@ const SideNavigationGroupContent: FC<HeaderNavigationItemSubmenu & NavigationCom
237
238
  return out;
238
239
  }
239
240
 
240
- const key = `:group:${index}:title`;
241
+ /* eslint-disable react/no-array-index-key */
241
242
  out.push(
242
- <Text key={key} variant="eyebrow" className={Styles.submenuGroupHeader}>
243
+ <Text
244
+ key={`:group:${index}:title`}
245
+ variant="eyebrow"
246
+ className={Styles.submenuGroupHeader}
247
+ >
243
248
  {group.title}
244
249
  </Text>
245
250
  );
246
-
247
251
  out.push(
248
- ...group.links.map(link => (
252
+ ...group.links.map((link, index) => (
249
253
  <SideNavigationGroupLink
250
- key={link.id}
254
+ key={`:${link.id}:${index}`}
251
255
  {...link}
252
256
  navigationComponent={navigationComponent}
253
257
  />
254
258
  ))
255
259
  );
260
+ /* eslint-enable react/no-array-index-key */
261
+
256
262
  return out;
257
263
  }, [] as ReactElement[])}
258
264
  </Fragment>
259
265
  );
260
266
  };
261
- const SideNavigationGroupLink: FC<HeaderNavigationItemSubmenuLink & NavigationComponentProps> = ({
267
+ const SideNavigationGroupLink: FC<NavigationSubmenuItemData & NavigationComponentProps> = ({
262
268
  id,
269
+ counter,
263
270
  tag,
264
271
  title,
265
272
  to,
@@ -279,7 +286,7 @@ const SideNavigationGroupLink: FC<HeaderNavigationItemSubmenuLink & NavigationCo
279
286
  activeClassName={Styles.submenuLinkActive}
280
287
  >
281
288
  <span>{title}</span>
282
- {!!tag && <CounterTag data={tag} className={Styles.submenuLinkCounter} />}
289
+ <CounterTag data={getCounterTag(counter, tag)} className={Styles.submenuLinkCounter} />
283
290
  </NavigationComponent>
284
291
  );
285
292
  };
@@ -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
  }