@servicetitan/navigation 9.0.1 → 9.2.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 (62) hide show
  1. package/dist/components/counter-tag.d.ts +1 -4
  2. package/dist/components/counter-tag.d.ts.map +1 -1
  3. package/dist/components/counter-tag.js.map +1 -1
  4. package/dist/components/left-navigation/header-navigation-tiny-links.d.ts.map +1 -1
  5. package/dist/components/left-navigation/header-navigation-tiny-links.js +1 -1
  6. package/dist/components/left-navigation/header-navigation-tiny-links.js.map +1 -1
  7. package/dist/components/left-navigation/index.d.ts +2 -0
  8. package/dist/components/left-navigation/index.d.ts.map +1 -1
  9. package/dist/components/left-navigation/index.js +2 -0
  10. package/dist/components/left-navigation/index.js.map +1 -1
  11. package/dist/components/left-navigation/interface-internal.d.ts +10 -0
  12. package/dist/components/left-navigation/interface-internal.d.ts.map +1 -0
  13. package/dist/components/left-navigation/interface-internal.js +2 -0
  14. package/dist/components/left-navigation/interface-internal.js.map +1 -0
  15. package/dist/components/left-navigation/interface.d.ts +19 -0
  16. package/dist/components/left-navigation/interface.d.ts.map +1 -0
  17. package/dist/components/left-navigation/interface.js +2 -0
  18. package/dist/components/left-navigation/interface.js.map +1 -0
  19. package/dist/components/left-navigation/side-navigation-context.d.ts +8 -0
  20. package/dist/components/left-navigation/side-navigation-context.d.ts.map +1 -0
  21. package/dist/components/left-navigation/side-navigation-context.js +7 -0
  22. package/dist/components/left-navigation/side-navigation-context.js.map +1 -0
  23. package/dist/components/left-navigation/side-navigation-links-internal.d.ts +23 -0
  24. package/dist/components/left-navigation/side-navigation-links-internal.d.ts.map +1 -0
  25. package/dist/components/left-navigation/side-navigation-links-internal.js +29 -0
  26. package/dist/components/left-navigation/side-navigation-links-internal.js.map +1 -0
  27. package/dist/components/left-navigation/side-navigation-links.d.ts +6 -0
  28. package/dist/components/left-navigation/side-navigation-links.d.ts.map +1 -0
  29. package/dist/components/left-navigation/side-navigation-links.js +26 -0
  30. package/dist/components/left-navigation/side-navigation-links.js.map +1 -0
  31. package/dist/components/left-navigation/side-navigation.d.ts +13 -13
  32. package/dist/components/left-navigation/side-navigation.d.ts.map +1 -1
  33. package/dist/components/left-navigation/side-navigation.js +45 -30
  34. package/dist/components/left-navigation/side-navigation.js.map +1 -1
  35. package/dist/components/left-navigation/side-navigation.module.less +11 -4
  36. package/dist/components/left-navigation/side-navigation.stories.d.ts +5 -1
  37. package/dist/components/left-navigation/side-navigation.stories.d.ts.map +1 -1
  38. package/dist/components/left-navigation/side-navigation.stories.js +21 -2
  39. package/dist/components/left-navigation/side-navigation.stories.js.map +1 -1
  40. package/dist/utils/counter-tag.d.ts +8 -0
  41. package/dist/utils/counter-tag.d.ts.map +1 -0
  42. package/dist/utils/counter-tag.js +2 -0
  43. package/dist/utils/counter-tag.js.map +1 -0
  44. package/dist/utils/side-nav.d.ts +3 -0
  45. package/dist/utils/side-nav.d.ts.map +1 -0
  46. package/dist/utils/side-nav.js +27 -0
  47. package/dist/utils/side-nav.js.map +1 -0
  48. package/package.json +2 -2
  49. package/src/components/counter-tag.tsx +1 -5
  50. package/src/components/left-navigation/header-navigation-tiny-links.tsx +3 -0
  51. package/src/components/left-navigation/index.ts +2 -0
  52. package/src/components/left-navigation/interface-internal.ts +11 -0
  53. package/src/components/left-navigation/interface.ts +23 -0
  54. package/src/components/left-navigation/side-navigation-context.tsx +13 -0
  55. package/src/components/left-navigation/side-navigation-links-internal.tsx +128 -0
  56. package/src/components/left-navigation/side-navigation-links.tsx +51 -0
  57. package/src/components/left-navigation/side-navigation.module.less +11 -4
  58. package/src/components/left-navigation/side-navigation.module.less.d.ts +2 -1
  59. package/src/components/left-navigation/side-navigation.stories.tsx +58 -4
  60. package/src/components/left-navigation/side-navigation.tsx +123 -163
  61. package/src/utils/counter-tag.ts +11 -0
  62. package/src/utils/side-nav.ts +34 -0
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Popover } from '@servicetitan/anvil2';
2
3
  import { Page } from '@servicetitan/design-system';
3
4
  import { useState } from 'react';
4
5
  import { LocationInfo, items, withAnvil, withDefaultRedirects, withMemoryRouter, } from '../../test/data';
5
- import { SideNavigation } from './';
6
+ import { SideNavigation, SideNavigationLink, SideNavigationTrigger, } from './';
6
7
  const layout = (Story) => {
7
8
  return (_jsxs("div", { className: "d-f border", style: { height: '800px' }, children: [_jsx(Story, {}), _jsx("div", { className: "flex-grow-1 flex-basis-0", children: _jsx(Page, { children: _jsx(LocationInfo, {}) }) })] }));
8
9
  };
@@ -27,7 +28,7 @@ export const DefaultSideNavigation = () => {
27
28
  items.priceBook,
28
29
  items.pointOfSale,
29
30
  items.reports,
30
- ], itemsTop: [items.tasks] }));
31
+ ], children: _jsx(SideNavigation.Top, { children: _jsx(SideNavigationLink, { ...items.tasks }) }) }));
31
32
  };
32
33
  export const SideNavigationLinksOnly = () => {
33
34
  const [expanded, setExpanded] = useState(undefined);
@@ -61,4 +62,22 @@ export const SideNavigationWithSubmenu = () => {
61
62
  items.projects,
62
63
  ] }));
63
64
  };
65
+ const SideLinkPopoverWrapper = ({ children, context }) => {
66
+ return (_jsxs(Popover, { placement: "right", openOnHover: true, children: [_jsx(Popover.Trigger, { children: props => _jsx("div", { ...props, children: children }) }), _jsx(Popover.Content, { style: context.styles.popoverContent, children: "popover content" })] }));
67
+ };
68
+ export const SideNavigationWithCustomTopElements = () => {
69
+ const [expanded, setExpanded] = useState(undefined);
70
+ return (_jsx(SideNavigation, { expanded: expanded, onExpandedChange: setExpanded, items: [
71
+ items.dashboard,
72
+ items.schedule,
73
+ items.dispatch,
74
+ items.accountingWithSubmenu,
75
+ items.purchasingWithSubmenu,
76
+ items.followUpsWithSubmenu,
77
+ items.reports,
78
+ items.marketing,
79
+ items.priceBook,
80
+ items.projects,
81
+ ], children: _jsxs(SideNavigation.Top, { children: [_jsx(SideNavigationLink, { ...items.calls }), _jsx(SideNavigationLink, { ...items.tasks }), _jsx(SideNavigationTrigger, { ...items.marketing, isActive: false, wrapper: SideLinkPopoverWrapper })] }) }));
82
+ };
64
83
  //# sourceMappingURL=side-navigation.stories.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"side-navigation.stories.js","sourceRoot":"","sources":["../../../src/components/left-navigation/side-navigation.stories.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"side-navigation.stories.js","sourceRoot":"","sources":["../../../src/components/left-navigation/side-navigation.stories.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { CounterTagProps } from '../components/counter-tag';
2
+ export interface CounterTagPropsStrict {
3
+ value: number | boolean;
4
+ className?: string;
5
+ }
6
+ export type CounterTagType = boolean | number | CounterTagProps;
7
+ export declare const isCounterPropsObject: (tag?: CounterTagType) => tag is CounterTagProps;
8
+ //# sourceMappingURL=counter-tag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"counter-tag.d.ts","sourceRoot":"","sources":["../../src/utils/counter-tag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,eAAe,CAAC;AAEhE,eAAO,MAAM,oBAAoB,SAAU,cAAc,KAAG,GAAG,IAAI,eACtB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const isCounterPropsObject = (tag) => !!tag && tag.value !== undefined;
2
+ //# sourceMappingURL=counter-tag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"counter-tag.js","sourceRoot":"","sources":["../../src/utils/counter-tag.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAoB,EAA0B,EAAE,CACjF,CAAC,CAAC,GAAG,IAAK,GAAW,CAAC,KAAK,KAAK,SAAS,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { HeaderNavigationItemData, HeaderNavigationItemSubmenu } from './navigation';
2
+ export declare function getSubmenuGroupTag(submenu: HeaderNavigationItemSubmenu | undefined, defaultTag: HeaderNavigationItemData['tag']): HeaderNavigationItemData['tag'];
3
+ //# sourceMappingURL=side-nav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"side-nav.d.ts","sourceRoot":"","sources":["../../src/utils/side-nav.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAErF,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,2BAA2B,GAAG,SAAS,EAChD,UAAU,EAAE,wBAAwB,CAAC,KAAK,CAAC,GAC5C,wBAAwB,CAAC,KAAK,CAAC,CA2BjC"}
@@ -0,0 +1,27 @@
1
+ import { isCounterPropsObject } from './counter-tag';
2
+ export function getSubmenuGroupTag(submenu, defaultTag) {
3
+ if (!submenu) {
4
+ return defaultTag;
5
+ }
6
+ let tagValue = undefined;
7
+ for (const group of submenu.groups) {
8
+ for (const link of group.links) {
9
+ const ltv = isCounterPropsObject(link.tag)
10
+ ? link.tag.value
11
+ : link.tag;
12
+ if (ltv) {
13
+ if (typeof ltv === 'number') {
14
+ if (typeof tagValue !== 'number') {
15
+ tagValue = 0;
16
+ }
17
+ tagValue += ltv;
18
+ }
19
+ else if (typeof tagValue !== 'number') {
20
+ tagValue = true;
21
+ }
22
+ }
23
+ }
24
+ }
25
+ return tagValue !== null && tagValue !== void 0 ? tagValue : defaultTag;
26
+ }
27
+ //# sourceMappingURL=side-nav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"side-nav.js","sourceRoot":"","sources":["../../src/utils/side-nav.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGrD,MAAM,UAAU,kBAAkB,CAC9B,OAAgD,EAChD,UAA2C;IAE3C,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,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC;gBACpE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;gBAChB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAEf,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,aAAR,QAAQ,cAAR,QAAQ,GAAI,UAAU,CAAC;AAClC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/navigation",
3
- "version": "9.0.1",
3
+ "version": "9.2.0",
4
4
  "description": "Navigation components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -43,5 +43,5 @@
43
43
  "less": true,
44
44
  "webpack": false
45
45
  },
46
- "gitHead": "17e9d04bdccaff2925c01f9aa1216b6f53df61f5"
46
+ "gitHead": "97dd433c1d3ad452a2445174e297ffa4b23c0a05"
47
47
  }
@@ -1,11 +1,7 @@
1
1
  import { Tag } from '@servicetitan/design-system';
2
2
  import classNames from 'classnames';
3
3
  import { FC } from 'react';
4
-
5
- export interface CounterTagPropsStrict {
6
- value: number | boolean;
7
- className?: string;
8
- }
4
+ import { CounterTagPropsStrict } from '../utils/counter-tag';
9
5
 
10
6
  export interface CounterTagProps extends CounterTagPropsStrict {
11
7
  [key: string]: any;
@@ -52,6 +52,9 @@ export const HeaderNavigationLink: FC<HeaderNavigationLinkProps> = ({
52
52
  className,
53
53
  icon,
54
54
  iconActive,
55
+ iconClassName,
56
+ iconComponent,
57
+ iconName,
55
58
  isActive,
56
59
  label,
57
60
  labelClassName,
@@ -1,2 +1,4 @@
1
1
  export * from './header-navigation-tiny';
2
2
  export * from './side-navigation';
3
+ export * from './side-navigation-links';
4
+ export * from './interface';
@@ -0,0 +1,11 @@
1
+ import { FC } from 'react';
2
+ import { NavLinkComponentProps } from '../../utils/navigation';
3
+ import { SideNavigationExpandedState } from './interface';
4
+
5
+ export interface NavigationComponentProps {
6
+ navigationComponent: FC<NavLinkComponentProps>;
7
+ }
8
+
9
+ export interface SideNavigationExpandedProps {
10
+ expanded?: SideNavigationExpandedState;
11
+ }
@@ -0,0 +1,23 @@
1
+ import { FC, ReactElement } from 'react';
2
+ import { HeaderNavigationItemData } from '../../utils/navigation';
3
+ import { SideNavigationContextType } from './side-navigation-context';
4
+
5
+ export interface SideNavigationExpandedState {
6
+ bar: boolean;
7
+ submenus?: string[];
8
+ }
9
+
10
+ export interface SideNavigationLinkWrapperProps {
11
+ children: ReactElement<SideNavigationLinkProps> | ReactElement<SideNavigationTriggerProps>;
12
+ context: SideNavigationContextType;
13
+ }
14
+
15
+ export interface SideNavigationLinkProps
16
+ extends Omit<HeaderNavigationItemData, 'iconName' | 'submenu'> {
17
+ wrapper?: FC<SideNavigationLinkWrapperProps>;
18
+ }
19
+ export interface SideNavigationTriggerProps
20
+ extends Omit<SideNavigationLinkProps, 'to' | 'isActive'> {
21
+ isActive?: boolean;
22
+ wrapper?: FC<SideNavigationLinkWrapperProps>;
23
+ }
@@ -0,0 +1,13 @@
1
+ import { CSSProperties, createContext } from 'react';
2
+
3
+ export interface SideNavigationContextType {
4
+ styles: {
5
+ popoverContent: CSSProperties;
6
+ };
7
+ }
8
+
9
+ export const SideNavigationContext = createContext<SideNavigationContextType>({
10
+ styles: {
11
+ popoverContent: {},
12
+ },
13
+ });
@@ -0,0 +1,128 @@
1
+ import { Icon } from '@servicetitan/anvil2';
2
+ import SvgGroupCollapse from '@servicetitan/anvil2/assets/icons/material/round/expand_less.svg';
3
+ import SvgGroupExpand from '@servicetitan/anvil2/assets/icons/material/round/expand_more.svg';
4
+
5
+ import classNames from 'classnames';
6
+ import { FC, Fragment } from 'react';
7
+ import { HeaderNavigationItemData } from '../../utils/navigation';
8
+ import { CounterTag } from '../counter-tag';
9
+ import { SideNavigationTriggerProps } from './interface';
10
+ import { NavigationComponentProps, SideNavigationExpandedProps } from './interface-internal';
11
+ import * as Styles from './side-navigation.module.less';
12
+
13
+ export interface InternalSideNavigationItemContentProps
14
+ extends Omit<HeaderNavigationItemData, 'iconName' | 'to' | ''> {
15
+ submenuExpanded: boolean | undefined;
16
+ }
17
+
18
+ export const InternalSideNavigationItemContent: FC<InternalSideNavigationItemContentProps> = ({
19
+ icon,
20
+ iconActive,
21
+ iconClassName,
22
+ iconComponent: IconComponent,
23
+ tag,
24
+ title,
25
+ submenuExpanded,
26
+ }) => (
27
+ <Fragment>
28
+ <div className={Styles.navigationItemIconWrapper}>
29
+ {IconComponent ? (
30
+ <i className={classNames(Styles.navigationIcon, iconClassName)}>
31
+ <IconComponent />
32
+ </i>
33
+ ) : (
34
+ <Fragment>
35
+ {icon && (
36
+ <Icon
37
+ svg={icon}
38
+ className={classNames(
39
+ Styles.navigationIcon,
40
+ Styles.navigationIconInactive,
41
+ iconClassName
42
+ )}
43
+ />
44
+ )}
45
+ {iconActive && (
46
+ <Icon
47
+ svg={iconActive}
48
+ className={classNames(
49
+ Styles.navigationIcon,
50
+ Styles.navigationIconActive,
51
+ iconClassName
52
+ )}
53
+ />
54
+ )}
55
+ </Fragment>
56
+ )}
57
+
58
+ <div className={Styles.navigationItemTextExpanded}>{title}</div>
59
+ {!!tag && <CounterTag data={tag} className={Styles.navigationItemCounter} />}
60
+ {typeof submenuExpanded === 'boolean' && (
61
+ <Icon
62
+ svg={submenuExpanded ? SvgGroupCollapse : SvgGroupExpand}
63
+ className={Styles.navigationItemGroupToggle}
64
+ />
65
+ )}
66
+ </div>
67
+
68
+ <div
69
+ className={classNames(Styles.navigationItemTextCollapsed, {
70
+ [Styles.navigationItemTextSmall]: title.length >= 10,
71
+ })}
72
+ >
73
+ {title}
74
+ </div>
75
+ </Fragment>
76
+ );
77
+
78
+ export interface InternalSideNavigationLinkProps
79
+ extends Omit<HeaderNavigationItemData, 'iconName'>,
80
+ NavigationComponentProps,
81
+ SideNavigationExpandedProps {
82
+ submenuExpanded: boolean | undefined;
83
+ dataPrefix?: string;
84
+ }
85
+
86
+ export const internalNavigationContentContainerProps = ({
87
+ className,
88
+ icon,
89
+ iconActive,
90
+ iconComponent,
91
+ id,
92
+ isActive,
93
+ prefix,
94
+ }: Omit<SideNavigationTriggerProps, 'isActive'> & { prefix: string; isActive?: any }) => ({
95
+ 'data-cy': `${prefix}-${id}`,
96
+ 'data-pendo': `${prefix}-${id}`,
97
+ 'className': classNames(Styles.navigationItem, className, {
98
+ [Styles.navigationItemActive]: isActive === true,
99
+ [Styles.navigationItemIconSwitch]: !!icon && !!iconActive && !iconComponent,
100
+ }),
101
+ });
102
+
103
+ /** Side Navigation menu item (for internal usage) */
104
+ export const InternalSideNavigationLink: FC<InternalSideNavigationLinkProps> = ({
105
+ to,
106
+ className,
107
+ dataPrefix,
108
+ isActive,
109
+ navigationComponent: NavigationComponent,
110
+ submenuExpanded,
111
+ ...props
112
+ }) => {
113
+ return (
114
+ <NavigationComponent
115
+ {...internalNavigationContentContainerProps({
116
+ ...props,
117
+ prefix: dataPrefix ?? 'navigation-item',
118
+ className,
119
+ isActive,
120
+ })}
121
+ to={to}
122
+ isActive={typeof isActive === 'function' ? isActive : undefined}
123
+ activeClassName={Styles.navigationItemActive}
124
+ >
125
+ <InternalSideNavigationItemContent submenuExpanded={submenuExpanded} {...props} />
126
+ </NavigationComponent>
127
+ );
128
+ };
@@ -0,0 +1,51 @@
1
+ import classNames from 'classnames';
2
+ import { FC, ReactElement, useContext } from 'react';
3
+ import { NavigationComponentContext } from '../../utils/navigation-context';
4
+ import { SideNavigationLinkProps, SideNavigationTriggerProps } from './interface';
5
+ import { SideNavigationContext } from './side-navigation-context';
6
+ import {
7
+ InternalSideNavigationItemContent,
8
+ InternalSideNavigationLink,
9
+ internalNavigationContentContainerProps,
10
+ } from './side-navigation-links-internal';
11
+
12
+ const WrappedLink: FC<{
13
+ children: ReactElement;
14
+ wrapper: NonNullable<SideNavigationLinkProps['wrapper']>;
15
+ }> = ({ children, wrapper: WrapperComponent }) => {
16
+ return (
17
+ <WrapperComponent context={useContext(SideNavigationContext)}>{children}</WrapperComponent>
18
+ );
19
+ };
20
+ /** Side Navigation menu link */
21
+ export function SideNavigationLink({ wrapper, ...props }: SideNavigationLinkProps) {
22
+ const NavigationComponent = useContext(NavigationComponentContext);
23
+
24
+ const element = (
25
+ <InternalSideNavigationLink
26
+ {...props}
27
+ navigationComponent={NavigationComponent}
28
+ submenuExpanded={undefined}
29
+ dataPrefix="navigation-link"
30
+ />
31
+ );
32
+
33
+ return wrapper ? <WrappedLink wrapper={wrapper}>{element}</WrappedLink> : element;
34
+ }
35
+
36
+ /** Side Navigation menu trigger */
37
+ export function SideNavigationTrigger({ wrapper, ...props }: SideNavigationTriggerProps) {
38
+ const element = (
39
+ <div
40
+ {...internalNavigationContentContainerProps({
41
+ ...props,
42
+ prefix: 'navigation-trigger',
43
+ className: classNames(props.className, 'cursor-pointer'),
44
+ isActive: props.isActive,
45
+ })}
46
+ >
47
+ <InternalSideNavigationItemContent submenuExpanded={undefined} {...props} />
48
+ </div>
49
+ );
50
+ return wrapper ? <WrappedLink wrapper={wrapper}>{element}</WrappedLink> : element;
51
+ }
@@ -44,7 +44,10 @@
44
44
  padding: @spacing-half;
45
45
  }
46
46
 
47
- .navigation-item-text {
47
+ .navigation-item-text-expanded {
48
+ display: none;
49
+ }
50
+ .navigation-item-text-collapsed {
48
51
  font-family: @base-font-family;
49
52
  font-size: 11px;
50
53
  line-height: 11px;
@@ -52,7 +55,7 @@
52
55
  text-align: center;
53
56
  }
54
57
 
55
- .navigation-item-text.navigation-item-text-small {
58
+ .navigation-item-text-collapsed.navigation-item-text-small {
56
59
  font-size: 10.5px;
57
60
  }
58
61
  }
@@ -81,13 +84,17 @@
81
84
  padding: @spacing-1 @spacing-half;
82
85
  }
83
86
 
84
- .navigation-item-text {
87
+ .navigation-item-text-expanded {
85
88
  font-family: @base-font-family;
86
89
  font-size: @typescale-3;
87
90
  padding-left: @spacing-1;
88
91
  flex: 1;
89
92
  }
90
93
 
94
+ .navigation-item-text-collapsed {
95
+ display: none;
96
+ }
97
+
91
98
  .navigation-item-counter {
92
99
  margin-right: @spacing-1;
93
100
  }
@@ -190,7 +197,7 @@
190
197
  }
191
198
 
192
199
  .navigation-item-counter {
193
- color: @color-white;
200
+ color: @color-black;
194
201
  font-weight: @font-weight-semibold;
195
202
  min-width: 12px !important;
196
203
  min-height: 12px !important;
@@ -9,7 +9,8 @@ export const navigationItemCounter: string;
9
9
  export const navigationItemGroupToggle: string;
10
10
  export const navigationItemIconSwitch: string;
11
11
  export const navigationItemIconWrapper: string;
12
- export const navigationItemText: string;
12
+ export const navigationItemTextCollapsed: string;
13
+ export const navigationItemTextExpanded: string;
13
14
  export const navigationItemTextSmall: string;
14
15
  export const optionsIcon: string;
15
16
  export const optionsIconWrapper: string;
@@ -1,5 +1,6 @@
1
+ import { Popover } from '@servicetitan/anvil2';
1
2
  import { Page } from '@servicetitan/design-system';
2
- import { ComponentType, useState } from 'react';
3
+ import { ComponentType, FC, useState } from 'react';
3
4
  import {
4
5
  LocationInfo,
5
6
  items,
@@ -7,7 +8,13 @@ import {
7
8
  withDefaultRedirects,
8
9
  withMemoryRouter,
9
10
  } from '../../test/data';
10
- import { SideNavigation, SideNavigationExpandedState } from './';
11
+ import {
12
+ SideNavigation,
13
+ SideNavigationExpandedState,
14
+ SideNavigationLink,
15
+ SideNavigationLinkWrapperProps,
16
+ SideNavigationTrigger,
17
+ } from './';
11
18
 
12
19
  const layout = (Story: ComponentType) => {
13
20
  return (
@@ -50,8 +57,11 @@ export const DefaultSideNavigation = () => {
50
57
  items.pointOfSale,
51
58
  items.reports,
52
59
  ]}
53
- itemsTop={[items.tasks]}
54
- />
60
+ >
61
+ <SideNavigation.Top>
62
+ <SideNavigationLink {...items.tasks} />
63
+ </SideNavigation.Top>
64
+ </SideNavigation>
55
65
  );
56
66
  };
57
67
 
@@ -106,3 +116,47 @@ export const SideNavigationWithSubmenu = () => {
106
116
  />
107
117
  );
108
118
  };
119
+
120
+ const SideLinkPopoverWrapper: FC<SideNavigationLinkWrapperProps> = ({ children, context }) => {
121
+ return (
122
+ <Popover placement="right" openOnHover>
123
+ <Popover.Trigger>{props => <div {...props}>{children}</div>}</Popover.Trigger>
124
+ <Popover.Content style={context.styles.popoverContent}>popover content</Popover.Content>
125
+ </Popover>
126
+ );
127
+ };
128
+
129
+ export const SideNavigationWithCustomTopElements = () => {
130
+ const [expanded, setExpanded] = useState<SideNavigationExpandedState | undefined>(undefined);
131
+ return (
132
+ <SideNavigation
133
+ expanded={expanded}
134
+ onExpandedChange={setExpanded}
135
+ items={[
136
+ items.dashboard,
137
+ items.schedule,
138
+ items.dispatch,
139
+
140
+ items.accountingWithSubmenu,
141
+ items.purchasingWithSubmenu,
142
+
143
+ items.followUpsWithSubmenu,
144
+ items.reports,
145
+ items.marketing,
146
+ items.priceBook,
147
+
148
+ items.projects,
149
+ ]}
150
+ >
151
+ <SideNavigation.Top>
152
+ <SideNavigationLink {...items.calls} />
153
+ <SideNavigationLink {...items.tasks} />
154
+ <SideNavigationTrigger
155
+ {...items.marketing}
156
+ isActive={false}
157
+ wrapper={SideLinkPopoverWrapper}
158
+ />
159
+ </SideNavigation.Top>
160
+ </SideNavigation>
161
+ );
162
+ };