@servicetitan/navigation 8.2.1 → 9.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 (56) hide show
  1. package/dist/components/counter-tag.d.ts +2 -4
  2. package/dist/components/counter-tag.d.ts.map +1 -1
  3. package/dist/components/counter-tag.js +3 -4
  4. package/dist/components/counter-tag.js.map +1 -1
  5. package/dist/components/header-navigation/header-navigation-content.d.ts +2 -2
  6. package/dist/components/header-navigation/header-navigation-content.d.ts.map +1 -1
  7. package/dist/components/header-navigation/header-navigation-content.js +4 -4
  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.js +4 -4
  12. package/dist/components/header-navigation/header-navigation-links.js.map +1 -1
  13. package/dist/components/header-navigation/header-navigation-stacked.stories.js +1 -1
  14. package/dist/components/header-navigation/header-navigation-stacked.stories.js.map +1 -1
  15. package/dist/components/header-navigation/header-navigation.module.less +2 -1
  16. package/dist/components/header-navigation/header-navigation.stories.js +1 -1
  17. package/dist/components/header-navigation/header-navigation.stories.js.map +1 -1
  18. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts +1 -1
  19. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts.map +1 -1
  20. package/dist/components/left-navigation/header-navigation-tiny-links.js +6 -6
  21. package/dist/components/left-navigation/header-navigation-tiny-links.js.map +1 -1
  22. package/dist/components/left-navigation/header-navigation-tiny.stories.js +2 -2
  23. package/dist/components/left-navigation/header-navigation-tiny.stories.js.map +1 -1
  24. package/dist/components/left-navigation/side-navigation.d.ts +8 -4
  25. package/dist/components/left-navigation/side-navigation.d.ts.map +1 -1
  26. package/dist/components/left-navigation/side-navigation.js +31 -20
  27. package/dist/components/left-navigation/side-navigation.js.map +1 -1
  28. package/dist/components/left-navigation/side-navigation.module.less +20 -12
  29. package/dist/components/left-navigation/side-navigation.stories.js +3 -3
  30. package/dist/components/left-navigation/side-navigation.stories.js.map +1 -1
  31. package/dist/components/profile-dropdown/profile-dropdown.d.ts +1 -1
  32. package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
  33. package/dist/components/profile-dropdown/profile-dropdown.js +3 -3
  34. package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
  35. package/dist/test/data.d.ts.map +1 -1
  36. package/dist/test/data.js +7 -6
  37. package/dist/test/data.js.map +1 -1
  38. package/dist/utils/navigation.d.ts +9 -5
  39. package/dist/utils/navigation.d.ts.map +1 -1
  40. package/package.json +4 -4
  41. package/src/components/counter-tag.tsx +12 -9
  42. package/src/components/header-navigation/header-navigation-content.tsx +7 -7
  43. package/src/components/header-navigation/header-navigation-extra.stories.tsx +3 -3
  44. package/src/components/header-navigation/header-navigation-links.tsx +4 -4
  45. package/src/components/header-navigation/header-navigation-stacked.stories.tsx +2 -2
  46. package/src/components/header-navigation/header-navigation.module.less +2 -1
  47. package/src/components/header-navigation/header-navigation.stories.tsx +2 -2
  48. package/src/components/left-navigation/header-navigation-tiny-links.tsx +8 -8
  49. package/src/components/left-navigation/header-navigation-tiny.stories.tsx +2 -2
  50. package/src/components/left-navigation/side-navigation.module.less +20 -12
  51. package/src/components/left-navigation/side-navigation.module.less.d.ts +1 -0
  52. package/src/components/left-navigation/side-navigation.stories.tsx +4 -4
  53. package/src/components/left-navigation/side-navigation.tsx +62 -41
  54. package/src/components/profile-dropdown/profile-dropdown.tsx +6 -9
  55. package/src/test/data.tsx +11 -10
  56. package/src/utils/navigation.ts +10 -5
@@ -9,13 +9,13 @@ import { withTooltip } from './with-tooltip';
9
9
 
10
10
  /** Content for navigation items */
11
11
  export const HeaderNavigationItemContent: FC<{
12
- counter?: CounterTagPropsType;
12
+ tag?: CounterTagPropsType;
13
13
  counterClassName?: string;
14
14
  icon: IconProps['svg'] | undefined;
15
15
  iconActive: IconProps['svg'] | undefined;
16
16
  label?: string;
17
17
  labelClassName?: string;
18
- }> = ({ counter, counterClassName, icon, iconActive, label, labelClassName }) => {
18
+ }> = ({ counterClassName, icon, iconActive, label, labelClassName, tag }) => {
19
19
  return (
20
20
  <Fragment>
21
21
  {!!icon && <Icon svg={icon} className={Styles.navigationIcon} />}
@@ -32,9 +32,9 @@ export const HeaderNavigationItemContent: FC<{
32
32
  </span>
33
33
  )}
34
34
 
35
- {!!counter && (
35
+ {!!tag && (
36
36
  <CounterTag
37
- data={counter}
37
+ data={tag}
38
38
  className={classNames(Styles.navigationItemCounter, counterClassName)}
39
39
  longClassName={Styles.navigationItemCounterLong}
40
40
  />
@@ -49,13 +49,13 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
49
49
  to,
50
50
  hint,
51
51
  tooltip,
52
- counter,
53
52
  className,
54
53
  icon,
55
54
  iconActive,
56
55
  isActive,
57
56
  label,
58
57
  labelClassName,
58
+ tag,
59
59
  target,
60
60
  ...rest
61
61
  }) => {
@@ -78,7 +78,7 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
78
78
  target={target}
79
79
  >
80
80
  <HeaderNavigationItemContent
81
- counter={counter}
81
+ tag={tag}
82
82
  icon={icon}
83
83
  iconActive={iconActive}
84
84
  label={label}
@@ -93,13 +93,13 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
93
93
  export const HeaderNavigationTrigger: FC<HeaderNavigationTriggerProps> = ({
94
94
  id,
95
95
  className,
96
- counter,
97
96
  icon,
98
97
  iconActive,
99
98
  isActive,
100
99
  hint,
101
100
  label,
102
101
  labelClassName,
102
+ tag,
103
103
  tooltip,
104
104
  title,
105
105
  titleClassName,
@@ -122,7 +122,7 @@ export const HeaderNavigationTrigger: FC<HeaderNavigationTriggerProps> = ({
122
122
  )}
123
123
  >
124
124
  <HeaderNavigationItemContent
125
- counter={counter}
125
+ tag={tag}
126
126
  icon={icon}
127
127
  iconActive={iconActive}
128
128
  label={label}
@@ -86,7 +86,7 @@ export const WithAllMonolithData = () => (
86
86
  />
87
87
 
88
88
  <ProfileDropdown>
89
- <ProfileDropdown.Link id="tasks" to="https://googgle.com" counter={10}>
89
+ <ProfileDropdown.Link id="tasks" to="https://googgle.com" tag={10}>
90
90
  Task Management
91
91
  </ProfileDropdown.Link>
92
92
  <ProfileDropdown.Divider />
@@ -152,7 +152,7 @@ export const WithAllMonolithDataCommercial = () => (
152
152
  />
153
153
 
154
154
  <ProfileDropdown>
155
- <ProfileDropdown.Link id="tasks" to="https://googgle.com" counter={10}>
155
+ <ProfileDropdown.Link id="tasks" to="https://googgle.com" tag={10}>
156
156
  Task Management
157
157
  </ProfileDropdown.Link>
158
158
  <ProfileDropdown.Divider />
@@ -73,7 +73,6 @@
73
73
 
74
74
  .navigation-item {
75
75
  flex-direction: row;
76
- margin-bottom: @spacing-half;
77
76
  margin-left: @spacing-1;
78
77
  margin-right: @spacing-1;
79
78
 
@@ -85,9 +84,13 @@
85
84
  .navigation-item-text {
86
85
  font-family: @base-font-family;
87
86
  font-size: @typescale-3;
88
- padding-left: @spacing-2;
87
+ padding-left: @spacing-1;
89
88
  flex: 1;
90
89
  }
90
+
91
+ .navigation-item-counter {
92
+ margin-right: @spacing-1;
93
+ }
91
94
  }
92
95
 
93
96
  .options-item {
@@ -189,6 +192,8 @@
189
192
  .navigation-item-counter {
190
193
  color: @color-white;
191
194
  font-weight: @font-weight-semibold;
195
+ min-width: 12px !important;
196
+ min-height: 12px !important;
192
197
  }
193
198
 
194
199
  .navigation-item-group-toggle[data-anv][data-anv] {
@@ -215,16 +220,6 @@
215
220
  margin-bottom: @spacing-1;
216
221
  position: relative;
217
222
 
218
- &:before {
219
- content: '';
220
- position: absolute;
221
- border-left: 1px solid @color-neutral-100;
222
- width: 1px;
223
- top: @spacing-2;
224
- bottom: @spacing-1;
225
- left: 0;
226
- }
227
-
228
223
  .submenu-group-header[data-anv][data-anv] {
229
224
  padding-top: @spacing-2;
230
225
  padding-bottom: @spacing-half;
@@ -305,12 +300,25 @@
305
300
  color: @text-color;
306
301
  font-size: @typescale-2;
307
302
  border-radius: @border-radius-2;
303
+ display: flex;
304
+ flex-direction: row;
305
+ justify-content: space-between;
306
+ align-items: center;
308
307
  }
309
308
 
310
309
  .submenu-link-active {
311
310
  color: @text-color-active;
312
311
  }
313
312
 
313
+ .submenu-link-counter {
314
+ min-height: 19px !important;
315
+ min-width: 19px !important;
316
+
317
+ > span:first-child {
318
+ color: @color-black;
319
+ }
320
+ }
321
+
314
322
  .submenu-link:hover:not(.submenu-link-active) {
315
323
  background-color: @bg-color-hover;
316
324
  }
@@ -25,5 +25,6 @@ export const submenu: string;
25
25
  export const submenuGroupHeader: string;
26
26
  export const submenuLink: string;
27
27
  export const submenuLinkActive: string;
28
+ export const submenuLinkCounter: string;
28
29
  export const submenuPopover: string;
29
30
 
@@ -1,7 +1,7 @@
1
1
  import { Page, Sidebar } from '@servicetitan/design-system';
2
2
  import { ComponentType, useState } from 'react';
3
3
  import { LocationInfo, items, withAnvil, withMemoryRouter } from '../../test/data';
4
- import { SideNavigation } from './';
4
+ import { SideNavigation, SideNavigationExpandedState } from './';
5
5
 
6
6
  const layout = (Story: ComponentType) => {
7
7
  return (
@@ -23,7 +23,7 @@ export default {
23
23
  };
24
24
 
25
25
  export const DefaultSideNavigation = () => {
26
- const [expanded, setExpanded] = useState(false);
26
+ const [expanded, setExpanded] = useState<SideNavigationExpandedState | undefined>(undefined);
27
27
  return (
28
28
  <SideNavigation
29
29
  expanded={expanded}
@@ -50,7 +50,7 @@ export const DefaultSideNavigation = () => {
50
50
  };
51
51
 
52
52
  export const SideNavigationLinksOnly = () => {
53
- const [expanded, setExpanded] = useState(false);
53
+ const [expanded, setExpanded] = useState<SideNavigationExpandedState | undefined>(undefined);
54
54
  return (
55
55
  <SideNavigation
56
56
  expanded={expanded}
@@ -76,7 +76,7 @@ export const SideNavigationLinksOnly = () => {
76
76
  };
77
77
 
78
78
  export const SideNavigationWithSubmenu = () => {
79
- const [expanded, setExpanded] = useState(false);
79
+ const [expanded, setExpanded] = useState<SideNavigationExpandedState | undefined>(undefined);
80
80
  return (
81
81
  <SideNavigation
82
82
  expanded={expanded}
@@ -14,12 +14,11 @@ import {
14
14
  ReactElement,
15
15
  useCallback,
16
16
  useContext,
17
- useState,
18
17
  } from 'react';
19
18
  import {
20
19
  HeaderNavigationItemData,
21
- HeaderNavigationItemLinkProps,
22
20
  HeaderNavigationItemSubmenu,
21
+ HeaderNavigationItemSubmenuLink,
23
22
  NavLinkComponentProps,
24
23
  } from '../../utils/navigation';
25
24
  import { NavigationComponentContext } from '../../utils/navigation-context';
@@ -27,6 +26,11 @@ import { CounterTag } from '../counter-tag';
27
26
  import * as Styles from './side-navigation.module.less';
28
27
  import { withTooltip } from './with-tooltip';
29
28
 
29
+ export interface SideNavigationExpandedState {
30
+ bar: boolean;
31
+ submenus?: string[];
32
+ }
33
+
30
34
  export interface SideNavigationProps {
31
35
  /** container class name */
32
36
  className?: string;
@@ -37,9 +41,9 @@ export interface SideNavigationProps {
37
41
  /** top navigation items */
38
42
  itemsTop?: HeaderNavigationItemData[];
39
43
  /** is menu expanded */
40
- expanded?: boolean;
44
+ expanded?: SideNavigationExpandedState;
41
45
  /** expand change handler */
42
- onExpandedChange(expanded: boolean): void;
46
+ onExpandedChange?(expanded: SideNavigationExpandedState): void;
43
47
  }
44
48
 
45
49
  export const SideNavigation: FC<SideNavigationProps> = ({
@@ -55,7 +59,7 @@ export const SideNavigation: FC<SideNavigationProps> = ({
55
59
  <div
56
60
  className={classNames(
57
61
  Styles.sideNav,
58
- expanded ? Styles.sideNavExpanded : Styles.sideNavSlim,
62
+ expanded?.bar ? Styles.sideNavExpanded : Styles.sideNavSlim,
59
63
  className
60
64
  )}
61
65
  id={id}
@@ -82,6 +86,7 @@ export const SideNavigation: FC<SideNavigationProps> = ({
82
86
  <SideNavigationGroupItem
83
87
  key={item.id}
84
88
  expanded={expanded}
89
+ onExpandedChange={onExpandedChange}
85
90
  navigationComponent={NavigationComponent}
86
91
  {...item}
87
92
  />
@@ -111,18 +116,14 @@ interface NavigationComponentProps {
111
116
  }
112
117
 
113
118
  interface SideNavigationItemProps extends HeaderNavigationItemData, NavigationComponentProps {
114
- expanded?: boolean;
115
- submenuExpanded?: boolean;
119
+ expanded?: SideNavigationExpandedState;
116
120
  }
117
121
 
118
122
  /** Side Navigation menu item */
119
123
  const SideNavigationItem: FC<SideNavigationItemProps> = ({
120
124
  id,
121
- submenuExpanded,
122
125
  to,
123
126
  title,
124
- hint,
125
- counter,
126
127
  className,
127
128
  iconClassName,
128
129
  iconComponent: IconComponent,
@@ -130,10 +131,12 @@ const SideNavigationItem: FC<SideNavigationItemProps> = ({
130
131
  iconActive,
131
132
  isActive,
132
133
  navigationComponent: NavigationComponent,
134
+ tag,
133
135
  expanded,
136
+ submenu,
134
137
  }) => {
135
138
  const iconSwitch = !!icon && !!iconActive && !IconComponent;
136
- const hasSubmenu = submenuExpanded === true || submenuExpanded === false;
139
+ const hasSubmenu = !!submenu;
137
140
 
138
141
  return (
139
142
  <NavigationComponent
@@ -141,7 +144,6 @@ const SideNavigationItem: FC<SideNavigationItemProps> = ({
141
144
  data-pendo={`navigation-item-${id}`}
142
145
  key={id}
143
146
  to={to}
144
- title={hint}
145
147
  className={classNames(Styles.navigationItem, className, {
146
148
  [Styles.navigationItemActive]: isActive === true,
147
149
  [Styles.navigationItemIconSwitch]: iconSwitch,
@@ -179,19 +181,17 @@ const SideNavigationItem: FC<SideNavigationItemProps> = ({
179
181
  </Fragment>
180
182
  )}
181
183
 
182
- {!!expanded && <div className={Styles.navigationItemText}>{title}</div>}
183
- {!!counter && (
184
- <CounterTag data={counter} className={Styles.navigationItemCounter} />
185
- )}
186
- {hasSubmenu && !!expanded && (
184
+ {!!expanded?.bar && <div className={Styles.navigationItemText}>{title}</div>}
185
+ {!!tag && <CounterTag data={tag} className={Styles.navigationItemCounter} />}
186
+ {hasSubmenu && !!expanded?.bar && (
187
187
  <Icon
188
- svg={submenuExpanded ? SvgGroupCollapse : SvgGroupExpand}
188
+ svg={expanded?.submenus?.includes(id) ? SvgGroupCollapse : SvgGroupExpand}
189
189
  className={Styles.navigationItemGroupToggle}
190
190
  />
191
191
  )}
192
192
  </div>
193
193
 
194
- {!expanded && (
194
+ {!expanded?.bar && (
195
195
  <div
196
196
  className={classNames(Styles.navigationItemText, {
197
197
  [Styles.navigationItemTextSmall]: title.length >= 10,
@@ -205,28 +205,44 @@ const SideNavigationItem: FC<SideNavigationItemProps> = ({
205
205
  };
206
206
 
207
207
  const submenuPopoverStyles = { '--background-color-strong': '#24323C' } as CSSProperties;
208
+ const getFirstSubmenuLinkTo = (
209
+ submenu: HeaderNavigationItemSubmenu | undefined,
210
+ defaultTo: string
211
+ ) => submenu?.groups[0]?.links?.[0].to ?? defaultTo;
208
212
 
209
213
  /** Side Navigation menu item */
210
- const SideNavigationGroupItem: FC<SideNavigationItemProps> = ({ ...props }) => {
211
- const [submenuExpanded, setSubmenuExpanded] = useState(false);
214
+ const SideNavigationGroupItem: FC<
215
+ SideNavigationItemProps & {
216
+ onExpandedChange: undefined | ((expanded: SideNavigationExpandedState) => void);
217
+ }
218
+ > = ({ onExpandedChange, ...props }) => {
212
219
  const triggerClick = useCallback(
213
220
  (e: MouseEvent<HTMLDivElement>) => {
214
221
  e.stopPropagation();
215
222
  e.preventDefault();
216
223
 
217
- if (props.expanded) {
218
- setSubmenuExpanded(exp => !exp);
219
- }
224
+ const isSubmenuExpanded = props.expanded?.submenus?.includes(props.id);
225
+ onExpandedChange?.({
226
+ bar: !!props.expanded?.bar,
227
+ submenus: [
228
+ ...(props.expanded?.submenus?.filter(id => id !== props.id) ?? []),
229
+ ...(isSubmenuExpanded ? [] : [props.id]),
230
+ ],
231
+ });
220
232
  },
221
- [props.expanded]
233
+ [props.id, props.expanded, onExpandedChange]
222
234
  );
223
235
 
224
- return props.expanded ? (
236
+ const tag = props.submenu?.groups.some(group => group.links.some(link => !!link.tag))
237
+ ? true
238
+ : props.tag;
239
+
240
+ return props.expanded?.bar ? (
225
241
  <Fragment>
226
242
  <div onClickCapture={triggerClick}>
227
- <SideNavigationItem {...props} submenuExpanded={submenuExpanded} />
243
+ <SideNavigationItem {...props} tag={tag} />
228
244
  </div>
229
- <Collapsible open={submenuExpanded} animate>
245
+ <Collapsible open={props.expanded?.submenus?.includes(props.id)} animate>
230
246
  <div className={Styles.submenu}>
231
247
  <SideNavigationGroupContent
232
248
  groups={props.submenu?.groups ?? []}
@@ -239,8 +255,12 @@ const SideNavigationGroupItem: FC<SideNavigationItemProps> = ({ ...props }) => {
239
255
  <Popover placement="right-start" openOnHover>
240
256
  <Popover.Trigger>
241
257
  {(triggerProps: PopoverTriggerProps) => (
242
- <div {...triggerProps} onClickCapture={triggerClick}>
243
- <SideNavigationItem {...props} />
258
+ <div {...triggerProps}>
259
+ <SideNavigationItem
260
+ {...props}
261
+ to={getFirstSubmenuLinkTo(props.submenu, props.to)}
262
+ tag={tag}
263
+ />
244
264
  </div>
245
265
  )}
246
266
  </Popover.Trigger>
@@ -264,17 +284,14 @@ const SideNavigationGroupContent: FC<HeaderNavigationItemSubmenu & NavigationCom
264
284
  }) => {
265
285
  return (
266
286
  <Fragment>
267
- {groups.reduce((out, group) => {
287
+ {groups.reduce((out, group, index) => {
268
288
  if (!group.links.length) {
269
289
  return out;
270
290
  }
271
291
 
292
+ const key = `:group:${index}:title`;
272
293
  out.push(
273
- <Text
274
- key=":group:title"
275
- variant="eyebrow"
276
- className={Styles.submenuGroupHeader}
277
- >
294
+ <Text key={key} variant="eyebrow" className={Styles.submenuGroupHeader}>
278
295
  {group.title}
279
296
  </Text>
280
297
  );
@@ -293,8 +310,9 @@ const SideNavigationGroupContent: FC<HeaderNavigationItemSubmenu & NavigationCom
293
310
  </Fragment>
294
311
  );
295
312
  };
296
- const SideNavigationGroupLink: FC<HeaderNavigationItemLinkProps & NavigationComponentProps> = ({
313
+ const SideNavigationGroupLink: FC<HeaderNavigationItemSubmenuLink & NavigationComponentProps> = ({
297
314
  id,
315
+ tag,
298
316
  title,
299
317
  to,
300
318
  isActive,
@@ -312,22 +330,25 @@ const SideNavigationGroupLink: FC<HeaderNavigationItemLinkProps & NavigationComp
312
330
  isActive={typeof isActive === 'function' ? isActive : undefined}
313
331
  activeClassName={Styles.submenuLinkActive}
314
332
  >
315
- {title}
333
+ <span>{title}</span>
334
+ {!!tag && <CounterTag data={tag} className={Styles.submenuLinkCounter} />}
316
335
  </NavigationComponent>
317
336
  );
318
337
  };
319
338
 
320
339
  /** Side Navigation options toggle */
321
340
  export const SideNavigationOptionsToggle: FC<{
322
- expanded?: boolean;
323
- onExpandedChange(expanded: boolean): void;
341
+ expanded?: SideNavigationExpandedState;
342
+ onExpandedChange?(expanded: SideNavigationExpandedState): void;
324
343
  }> = ({ expanded, onExpandedChange }) =>
325
344
  withTooltip(
326
345
  <div
327
346
  data-cy="navigation-left-options"
328
347
  data-pendo="navigation-left-options"
329
348
  className={classNames(Styles.optionsItem)}
330
- onClick={() => onExpandedChange(!expanded)}
349
+ onClick={() =>
350
+ onExpandedChange?.({ bar: !expanded?.bar, submenus: expanded?.submenus })
351
+ }
331
352
  >
332
353
  <div className={Styles.optionsIconWrapper}>
333
354
  <Icon className={Styles.optionsIcon} svg={expanded ? SvgCollapse : SvgExpand} />
@@ -192,7 +192,7 @@ export interface ProfileDropdownLinkPropsStrict {
192
192
  external?: boolean;
193
193
  target?: HTMLAttributeAnchorTarget;
194
194
  to?: string;
195
- counter?: CounterTagPropsType;
195
+ tag?: CounterTagPropsType;
196
196
  onClick?: () => void;
197
197
  }
198
198
 
@@ -203,9 +203,9 @@ export interface ProfileDropdownLinkProps extends ProfileDropdownLinkPropsStrict
203
203
  export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
204
204
  children,
205
205
  className,
206
- counter,
207
206
  external,
208
207
  id,
208
+ tag,
209
209
  target,
210
210
  to,
211
211
  onClick,
@@ -220,10 +220,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
220
220
 
221
221
  const isExternalLink = external ?? to?.startsWith('http');
222
222
 
223
- const counterElement = useMemo(
224
- () => <CounterTag data={counter} className={Styles.counter} />,
225
- [counter]
226
- );
223
+ const tagElement = useMemo(() => <CounterTag data={tag} className={Styles.counter} />, [tag]);
227
224
 
228
225
  return isExternalLink ? (
229
226
  <a
@@ -235,7 +232,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
235
232
  {...rest}
236
233
  >
237
234
  {children}
238
- {counterElement}
235
+ {tagElement}
239
236
  </a>
240
237
  ) : to ? (
241
238
  <NavigationComponent
@@ -247,7 +244,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
247
244
  {...rest}
248
245
  >
249
246
  {children}
250
- {counterElement}
247
+ {tagElement}
251
248
  </NavigationComponent>
252
249
  ) : (
253
250
  <a
@@ -258,7 +255,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
258
255
  {...rest}
259
256
  >
260
257
  {children}
261
- {counterElement}
258
+ {tagElement}
262
259
  </a>
263
260
  );
264
261
  };
package/src/test/data.tsx CHANGED
@@ -40,8 +40,8 @@ import { MemoryRouter, useHistory, useLocation } from 'react-router-dom';
40
40
  import { HeaderNavigationTrigger } from '../components/links';
41
41
  import {
42
42
  HeaderNavigationItemData,
43
- HeaderNavigationItemLinkProps,
44
43
  HeaderNavigationItemSubmenuGroup,
44
+ HeaderNavigationItemSubmenuLink,
45
45
  NavLinkComponentProps,
46
46
  } from '../utils/navigation';
47
47
  import { NavigationComponentContext } from '../utils/navigation-context';
@@ -145,8 +145,8 @@ const getItem = (
145
145
 
146
146
  const getSubItem = (
147
147
  id: string,
148
- data: Partial<HeaderNavigationItemLinkProps>
149
- ): HeaderNavigationItemLinkProps => ({
148
+ data: Partial<HeaderNavigationItemSubmenuLink>
149
+ ): HeaderNavigationItemSubmenuLink => ({
150
150
  id,
151
151
  to: id,
152
152
  title: id[0].toUpperCase() + id.substring(1),
@@ -155,7 +155,7 @@ const getSubItem = (
155
155
 
156
156
  const getGroup = (
157
157
  title: string,
158
- links: HeaderNavigationItemLinkProps[]
158
+ links: HeaderNavigationItemSubmenuLink[]
159
159
  ): HeaderNavigationItemSubmenuGroup => ({
160
160
  title,
161
161
  links,
@@ -176,7 +176,7 @@ export const items = {
176
176
  iconName: 'local_phone',
177
177
  icon: SvgCalls,
178
178
  iconActive: SvgCallsActive,
179
- counter: 12,
179
+ tag: 12,
180
180
  }),
181
181
  dashboard: getItem('dashboard', {
182
182
  iconName: 'odometer',
@@ -187,7 +187,7 @@ export const items = {
187
187
  iconName: 'location_disabled',
188
188
  icon: SvgDispatch,
189
189
  iconActive: SvgDispatchActive,
190
- counter: 1,
190
+ tag: 1,
191
191
  }),
192
192
  fleet: getItem('fleet', {
193
193
  iconName: 'fleet-pro',
@@ -241,6 +241,7 @@ export const items = {
241
241
  iconName: 'assignment',
242
242
  icon: SvgAccounting,
243
243
  iconActive: SvgAccountingActive,
244
+ tag: true,
244
245
  }),
245
246
  accountingWithSubmenu: getItem('accounting', {
246
247
  iconName: 'assignment',
@@ -250,9 +251,9 @@ export const items = {
250
251
  groups: [
251
252
  getGroup('Accounts Receivable', [
252
253
  getSubItem('ar', { title: 'AR Management' }),
253
- getSubItem('export', { title: 'Batch/Export Transactions' }),
254
- getSubItem('invoices', { title: 'Invoices' }),
255
- getSubItem('payments', { title: 'Customer Payments' }),
254
+ getSubItem('export', { title: 'Batch/Export Transactions', tag: true }),
255
+ getSubItem('invoices', { title: 'Invoices', tag: 3 }),
256
+ getSubItem('payments', { title: 'Customer Payments', tag: 2 }),
256
257
  getSubItem('deposits', { title: 'Bank Deposits' }),
257
258
  ]),
258
259
  getGroup('Accounts Payable', [getSubItem('bills', { title: 'Bills' })]),
@@ -306,7 +307,7 @@ export const CallsNavigationTrigger = () => {
306
307
  <HeaderNavigationTrigger
307
308
  id="dialpad"
308
309
  iconName="phone"
309
- counter={2}
310
+ tag={2}
310
311
  icon={SvgPhone}
311
312
  iconActive={SvgPhoneActive}
312
313
  onClick={() => setOpen(!open)}
@@ -25,8 +25,8 @@ export interface HeaderNavigationItemData extends HeaderNavigationItemLinkProps
25
25
  /** icon component of item (<svg />) */
26
26
  iconComponent?: FC;
27
27
 
28
- /** item counter (optional). shown if it is set and greater than 0 */
29
- counter?: CounterTagPropsType;
28
+ /** item tag (optional). shown if it is set and true or greater than 0 */
29
+ tag?: CounterTagPropsType;
30
30
 
31
31
  /** class name of link item */
32
32
  className?: string;
@@ -54,12 +54,17 @@ export interface HeaderNavigationItemSubmenu {
54
54
  groups: HeaderNavigationItemSubmenuGroup[];
55
55
  }
56
56
 
57
+ export interface HeaderNavigationItemSubmenuLink extends HeaderNavigationItemLinkProps {
58
+ /** item tag (optional). shown if it is set and true or greater than 0 */
59
+ tag?: CounterTagPropsType;
60
+ }
61
+
57
62
  export interface HeaderNavigationItemSubmenuGroup {
58
63
  /** submenu group title */
59
64
  title: string;
60
65
 
61
66
  /** submenu group links */
62
- links: HeaderNavigationItemLinkProps[];
67
+ links: HeaderNavigationItemSubmenuLink[];
63
68
  }
64
69
 
65
70
  export interface NavLinkComponentPropsStrict {
@@ -91,8 +96,8 @@ export interface HeaderNavigationTriggerPropsStrict {
91
96
  labelClassName?: string;
92
97
  /** isActive */
93
98
  isActive?: boolean;
94
- /** counter shown for item */
95
- counter?: CounterTagPropsType;
99
+ /** counter tag shown for item */
100
+ tag?: CounterTagPropsType;
96
101
  /** counter component class name */
97
102
  counterClassName?: string;
98
103
  /** icon component class name */