@servicetitan/navigation 14.2.0 → 14.4.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 (97) hide show
  1. package/dist/components/titan-layout/__tests__/layout-sidebar-links-internal.test.d.ts +2 -0
  2. package/dist/components/titan-layout/__tests__/layout-sidebar-links-internal.test.d.ts.map +1 -0
  3. package/dist/components/titan-layout/__tests__/navigation-catalog-reset.test.d.ts +2 -0
  4. package/dist/components/titan-layout/__tests__/navigation-catalog-reset.test.d.ts.map +1 -0
  5. package/dist/components/titan-layout/interface.d.ts +66 -0
  6. package/dist/components/titan-layout/interface.d.ts.map +1 -1
  7. package/dist/components/titan-layout/interface.js.map +1 -1
  8. package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts +3 -0
  9. package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts.map +1 -1
  10. package/dist/components/titan-layout/layout-sidebar-links-internal.js +58 -13
  11. package/dist/components/titan-layout/layout-sidebar-links-internal.js.map +1 -1
  12. package/dist/components/titan-layout/layout-sidebar.d.ts +14 -0
  13. package/dist/components/titan-layout/layout-sidebar.d.ts.map +1 -1
  14. package/dist/components/titan-layout/layout-sidebar.js +169 -97
  15. package/dist/components/titan-layout/layout-sidebar.js.map +1 -1
  16. package/dist/components/titan-layout/layout-sidebar.module.less +230 -144
  17. package/dist/components/titan-layout/layout-sidebar.module.less.d.ts +16 -5
  18. package/dist/components/titan-layout/navigation-catalog/index.d.ts +3 -0
  19. package/dist/components/titan-layout/navigation-catalog/index.d.ts.map +1 -0
  20. package/dist/components/titan-layout/navigation-catalog/index.js +4 -0
  21. package/dist/components/titan-layout/navigation-catalog/index.js.map +1 -0
  22. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-footer.d.ts +8 -0
  23. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-footer.d.ts.map +1 -0
  24. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-footer.js +88 -0
  25. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-footer.js.map +1 -0
  26. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-trigger.d.ts +21 -0
  27. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-trigger.d.ts.map +1 -0
  28. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-trigger.js +138 -0
  29. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-trigger.js.map +1 -0
  30. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-trigger.module.less +89 -0
  31. package/dist/components/titan-layout/navigation-catalog/navigation-catalog-trigger.module.less.d.ts +9 -0
  32. package/dist/components/titan-layout/navigation-catalog/navigation-catalog.d.ts +14 -0
  33. package/dist/components/titan-layout/navigation-catalog/navigation-catalog.d.ts.map +1 -0
  34. package/dist/components/titan-layout/navigation-catalog/navigation-catalog.js +343 -0
  35. package/dist/components/titan-layout/navigation-catalog/navigation-catalog.js.map +1 -0
  36. package/dist/components/titan-layout/navigation-catalog/navigation-catalog.module.less +379 -0
  37. package/dist/components/titan-layout/navigation-catalog/navigation-catalog.module.less.d.ts +26 -0
  38. package/dist/components/titan-layout/navigation-scroll-indicators.d.ts +12 -0
  39. package/dist/components/titan-layout/navigation-scroll-indicators.d.ts.map +1 -0
  40. package/dist/components/titan-layout/navigation-scroll-indicators.js +48 -0
  41. package/dist/components/titan-layout/navigation-scroll-indicators.js.map +1 -0
  42. package/dist/components/titan-layout/titan-layout.d.ts +29 -1
  43. package/dist/components/titan-layout/titan-layout.d.ts.map +1 -1
  44. package/dist/components/titan-layout/titan-layout.js +46 -6
  45. package/dist/components/titan-layout/titan-layout.js.map +1 -1
  46. package/dist/components/titan-layout/titan-layout.module.less +2 -1
  47. package/dist/components/titan-layout/use-navigation-scroll.d.ts +20 -0
  48. package/dist/components/titan-layout/use-navigation-scroll.d.ts.map +1 -0
  49. package/dist/components/titan-layout/use-navigation-scroll.js +140 -0
  50. package/dist/components/titan-layout/use-navigation-scroll.js.map +1 -0
  51. package/dist/utils/__tests__/catalog-groups.test.d.ts +2 -0
  52. package/dist/utils/__tests__/catalog-groups.test.d.ts.map +1 -0
  53. package/dist/utils/__tests__/navigation-notifications.test.d.ts +2 -0
  54. package/dist/utils/__tests__/navigation-notifications.test.d.ts.map +1 -0
  55. package/dist/utils/__tests__/submenu-state.test.d.ts +2 -0
  56. package/dist/utils/__tests__/submenu-state.test.d.ts.map +1 -0
  57. package/dist/utils/catalog-groups.d.ts +11 -0
  58. package/dist/utils/catalog-groups.d.ts.map +1 -0
  59. package/dist/utils/catalog-groups.js +66 -0
  60. package/dist/utils/catalog-groups.js.map +1 -0
  61. package/dist/utils/navigation-notifications.d.ts +21 -0
  62. package/dist/utils/navigation-notifications.d.ts.map +1 -0
  63. package/dist/utils/navigation-notifications.js +39 -0
  64. package/dist/utils/navigation-notifications.js.map +1 -0
  65. package/dist/utils/side-nav.js +3 -1
  66. package/dist/utils/side-nav.js.map +1 -1
  67. package/dist/utils/submenu-state.d.ts +3 -0
  68. package/dist/utils/submenu-state.d.ts.map +1 -0
  69. package/dist/utils/submenu-state.js +15 -0
  70. package/dist/utils/submenu-state.js.map +1 -0
  71. package/package.json +2 -2
  72. package/src/components/titan-layout/__tests__/layout-sidebar-links-internal.test.tsx +225 -0
  73. package/src/components/titan-layout/__tests__/navigation-catalog-reset.test.tsx +190 -0
  74. package/src/components/titan-layout/interface.ts +73 -0
  75. package/src/components/titan-layout/layout-sidebar-links-internal.tsx +86 -14
  76. package/src/components/titan-layout/layout-sidebar.module.less +230 -144
  77. package/src/components/titan-layout/layout-sidebar.module.less.d.ts +16 -5
  78. package/src/components/titan-layout/layout-sidebar.tsx +193 -117
  79. package/src/components/titan-layout/navigation-catalog/index.ts +2 -0
  80. package/src/components/titan-layout/navigation-catalog/navigation-catalog-footer.tsx +88 -0
  81. package/src/components/titan-layout/navigation-catalog/navigation-catalog-trigger.module.less +89 -0
  82. package/src/components/titan-layout/navigation-catalog/navigation-catalog-trigger.module.less.d.ts +9 -0
  83. package/src/components/titan-layout/navigation-catalog/navigation-catalog-trigger.tsx +170 -0
  84. package/src/components/titan-layout/navigation-catalog/navigation-catalog.module.less +379 -0
  85. package/src/components/titan-layout/navigation-catalog/navigation-catalog.module.less.d.ts +26 -0
  86. package/src/components/titan-layout/navigation-catalog/navigation-catalog.tsx +430 -0
  87. package/src/components/titan-layout/navigation-scroll-indicators.tsx +80 -0
  88. package/src/components/titan-layout/titan-layout.module.less +2 -1
  89. package/src/components/titan-layout/titan-layout.tsx +81 -5
  90. package/src/components/titan-layout/use-navigation-scroll.ts +145 -0
  91. package/src/utils/__tests__/catalog-groups.test.ts +97 -0
  92. package/src/utils/__tests__/navigation-notifications.test.ts +70 -0
  93. package/src/utils/__tests__/submenu-state.test.ts +39 -0
  94. package/src/utils/catalog-groups.ts +57 -0
  95. package/src/utils/navigation-notifications.ts +59 -0
  96. package/src/utils/side-nav.ts +1 -1
  97. package/src/utils/submenu-state.ts +16 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=layout-sidebar-links-internal.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-sidebar-links-internal.test.d.ts","sourceRoot":"","sources":["../../../../src/components/titan-layout/__tests__/layout-sidebar-links-internal.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=navigation-catalog-reset.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation-catalog-reset.test.d.ts","sourceRoot":"","sources":["../../../../src/components/titan-layout/__tests__/navigation-catalog-reset.test.tsx"],"names":[],"mappings":""}
@@ -1,6 +1,7 @@
1
1
  import { IconProps } from '@servicetitan/anvil2';
2
2
  import { ComponentPropsWithoutRef, FC, ReactNode } from 'react';
3
3
  import { CounterTagData, CounterTagValue } from '../../utils/counter-tag';
4
+ import { NavigationItemData } from '../../utils/navigation';
4
5
  import { TitanLayoutSidebarContextType } from './layout-context';
5
6
  export interface TitanLayoutLinkWrapperProps {
6
7
  children: ReactNode;
@@ -8,6 +9,71 @@ export interface TitanLayoutLinkWrapperProps {
8
9
  isMobile: boolean;
9
10
  }
10
11
  export type TitanLayoutLinkWrapper = FC<TitanLayoutLinkWrapperProps>;
12
+ /** A titled section of the navigation catalog. */
13
+ export interface NavigationCatalogGroup {
14
+ /** section heading */
15
+ title: string;
16
+ /**
17
+ * The destinations in this section.
18
+ *
19
+ * `id` is treated as an opaque pin id and is compared verbatim against `pinnedIds`, so the host
20
+ * is responsible for handing over ids in whatever form it stores them. Any `submenu` links are
21
+ * offered as separately pinnable pages beneath their item, and their `id`s are pin ids too.
22
+ */
23
+ items: NavigationItemData[];
24
+ }
25
+ /**
26
+ * Turns the navigation catalog on.
27
+ *
28
+ * Supplying this renders a catalog trigger in the sidebar and the dialog behind it; omitting it
29
+ * leaves the navigation exactly as it was. The layout owns the dialog, its open state and the
30
+ * keyboard shortcut, and nothing else about pinning: it proposes a new list, or reports that the
31
+ * user confirmed a reset, and the host decides what to do with either.
32
+ */
33
+ export interface PinnedNavigationConfig {
34
+ /**
35
+ * Every destination on offer, resolved on demand.
36
+ *
37
+ * A function rather than an array because resolving a catalog is not free for every host: one
38
+ * whose submenus are dynamic pays a request per module to enumerate its pages. The dialog is
39
+ * mounted only while open, so taking the groups as a thunk keeps that cost — and any failure
40
+ * in it — inside the dialog instead of on every page load of the shell.
41
+ *
42
+ * Called once per open, and again only if the function's identity changes, so a host should
43
+ * memoize it against whatever its resolution actually depends on.
44
+ */
45
+ groups: () => NavigationCatalogGroup[];
46
+ /** The pinned ids, in display order. */
47
+ pinnedIds: string[];
48
+ /**
49
+ * Ids the user may not pin or unpin.
50
+ *
51
+ * A locked destination is always present in the navigation whether or not it appears in
52
+ * `pinnedIds`, so the catalog shows a lock where the pin control would be and never proposes a
53
+ * list that adds or removes one.
54
+ */
55
+ lockedIds?: string[];
56
+ /**
57
+ * The list the user just asked for through a star control, in full.
58
+ *
59
+ * Fully controlled: nothing changes until `pinnedIds` comes back different. A host that
60
+ * declines the proposal simply does not apply it, and the control returns to its previous
61
+ * state on its own. Confirming a reset calls `onResetToDefaults` instead.
62
+ */
63
+ onPinnedIdsChange: (pinnedIds: string[]) => void;
64
+ /**
65
+ * Called once the user confirms Restore Default Favorites.
66
+ *
67
+ * The catalog reports the intent and proposes nothing: what the defaults are, whether locked
68
+ * destinations survive and how the reset is persisted are all the host's. Favourites move only
69
+ * when the host sends new `pinnedIds` down, and the catalog does not also call
70
+ * `onPinnedIdsChange`.
71
+ *
72
+ * Omit it to hide the restore control — including when the host offers defaults but the user
73
+ * has not strayed from them, which only the host can know.
74
+ */
75
+ onResetToDefaults?: () => void;
76
+ }
11
77
  export interface TitanLayoutLinkExtraProps {
12
78
  /** link's title should be shown (for extra links we show icon only by default) */
13
79
  showTitle?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAEjE,MAAM,WAAW,2BAA2B;IACxC,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,EAAE,6BAA6B,CAAC;IACvC,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,sBAAsB,GAAG,EAAE,CAAC,2BAA2B,CAAC,CAAC;AAErE,MAAM,WAAW,yBAAyB;IACtC,kFAAkF;IAClF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACrC,6CAA6C;IAC7C,OAAO,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,MAAM,oBAAoB,GAAG;IAC/B,cAAc;IACd,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;IACrD,yCAAyC;IACzC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;IACnC,uCAAuC;IACvC,UAAU,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;IACzC,kFAAkF;IAClF,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,mCAAmC;IACnC,KAAK,CAAC,EAAE,yBAAyB,CAAC;IAClC,uDAAuD;IACvD,IAAI,CAAC,EAAE,wBAAwB,CAAC;CACnC,GAAG,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC;AAE9D,MAAM,MAAM,uBAAuB,GAAG;IAClC,cAAc;IACd,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;IACnC,uCAAuC;IACvC,UAAU,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;IACzC,kFAAkF;IAClF,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,mCAAmC;IACnC,KAAK,CAAC,EAAE,yBAAyB,CAAC;IAClC,kDAAkD;IAClD,IAAI,CAAC,EAAE,wBAAwB,CAAC;CACnC,GAAG,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/interface.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/titan-layout/interface.ts"],"sourcesContent":["import { IconProps } from '@servicetitan/anvil2';\nimport { ComponentPropsWithoutRef, FC, ReactNode } from 'react';\nimport { CounterTagData, CounterTagValue } from '../../utils/counter-tag';\nimport { TitanLayoutSidebarContextType } from './layout-context';\n\nexport interface TitanLayoutLinkWrapperProps {\n children: ReactNode;\n context: TitanLayoutSidebarContextType;\n isMobile: boolean;\n}\n\nexport type TitanLayoutLinkWrapper = FC<TitanLayoutLinkWrapperProps>;\n\nexport interface TitanLayoutLinkExtraProps {\n /** link's title should be shown (for extra links we show icon only by default) */\n showTitle?: boolean;\n /** link is flashing */\n flashing?: boolean;\n}\n\nexport interface TitanLayoutLinkSideProps {\n /** counter value used only for side links */\n counter: CounterTagValue;\n}\n\nexport type TitanLayoutLinkProps = {\n /** link id */\n id: string;\n /** link href */\n to: string;\n /** link title */\n title: string;\n /** callback to return active state. By default, it compares link href with current pathname */\n isActive?: boolean | ((pathname: string) => boolean);\n /** svg icon (anvil2) of inactive item */\n icon: IconProps['svg'] | undefined;\n /** svg icon (anvil2) of active item */\n iconActive: IconProps['svg'] | undefined;\n /** item tag (optional). shown if it is set and value is true or greater than 0 */\n tag?: CounterTagData;\n counter?: CounterTagValue;\n /** class name of link item */\n className?: string;\n\n /** tooltip text (for extra links) */\n tooltip?: string;\n /** wrapper component for link element (used for side links) */\n wrapper?: TitanLayoutLinkWrapper;\n /** props for extra link element */\n extra?: TitanLayoutLinkExtraProps;\n /** props for side nav link element (mobile version) */\n side?: TitanLayoutLinkSideProps;\n} & Omit<ComponentPropsWithoutRef<'a'>, 'children' | 'title'>;\n\nexport type TitanLayoutTriggerProps = {\n /** link id */\n id: string;\n /** link title */\n title: string;\n /** active state */\n isActive?: boolean;\n /** svg icon (anvil2) of inactive item */\n icon: IconProps['svg'] | undefined;\n /** svg icon (anvil2) of active item */\n iconActive: IconProps['svg'] | undefined;\n /** item tag (optional). shown if it is set and value is true or greater than 0 */\n tag?: CounterTagData;\n counter?: CounterTagValue;\n /** class name of link item */\n className?: string;\n\n /** tooltip text (for extra links) */\n tooltip?: string;\n /** wrapper component for link element (used for side links) */\n wrapper?: TitanLayoutLinkWrapper;\n /** props for extra link element */\n extra?: TitanLayoutLinkExtraProps;\n /** props for nav link element (mobile version) */\n side?: TitanLayoutLinkSideProps;\n} & Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'title'>;\n"],"names":[],"mappings":"AAsDA,WAyBgE"}
1
+ {"version":3,"sources":["../../../src/components/titan-layout/interface.ts"],"sourcesContent":["import { IconProps } from '@servicetitan/anvil2';\nimport { ComponentPropsWithoutRef, FC, ReactNode } from 'react';\nimport { CounterTagData, CounterTagValue } from '../../utils/counter-tag';\nimport { NavigationItemData } from '../../utils/navigation';\nimport { TitanLayoutSidebarContextType } from './layout-context';\n\nexport interface TitanLayoutLinkWrapperProps {\n children: ReactNode;\n context: TitanLayoutSidebarContextType;\n isMobile: boolean;\n}\n\nexport type TitanLayoutLinkWrapper = FC<TitanLayoutLinkWrapperProps>;\n\n/** A titled section of the navigation catalog. */\nexport interface NavigationCatalogGroup {\n /** section heading */\n title: string;\n\n /**\n * The destinations in this section.\n *\n * `id` is treated as an opaque pin id and is compared verbatim against `pinnedIds`, so the host\n * is responsible for handing over ids in whatever form it stores them. Any `submenu` links are\n * offered as separately pinnable pages beneath their item, and their `id`s are pin ids too.\n */\n items: NavigationItemData[];\n}\n\n/**\n * Turns the navigation catalog on.\n *\n * Supplying this renders a catalog trigger in the sidebar and the dialog behind it; omitting it\n * leaves the navigation exactly as it was. The layout owns the dialog, its open state and the\n * keyboard shortcut, and nothing else about pinning: it proposes a new list, or reports that the\n * user confirmed a reset, and the host decides what to do with either.\n */\nexport interface PinnedNavigationConfig {\n /**\n * Every destination on offer, resolved on demand.\n *\n * A function rather than an array because resolving a catalog is not free for every host: one\n * whose submenus are dynamic pays a request per module to enumerate its pages. The dialog is\n * mounted only while open, so taking the groups as a thunk keeps that cost — and any failure\n * in it — inside the dialog instead of on every page load of the shell.\n *\n * Called once per open, and again only if the function's identity changes, so a host should\n * memoize it against whatever its resolution actually depends on.\n */\n groups: () => NavigationCatalogGroup[];\n\n /** The pinned ids, in display order. */\n pinnedIds: string[];\n\n /**\n * Ids the user may not pin or unpin.\n *\n * A locked destination is always present in the navigation whether or not it appears in\n * `pinnedIds`, so the catalog shows a lock where the pin control would be and never proposes a\n * list that adds or removes one.\n */\n lockedIds?: string[];\n\n /**\n * The list the user just asked for through a star control, in full.\n *\n * Fully controlled: nothing changes until `pinnedIds` comes back different. A host that\n * declines the proposal simply does not apply it, and the control returns to its previous\n * state on its own. Confirming a reset calls `onResetToDefaults` instead.\n */\n onPinnedIdsChange: (pinnedIds: string[]) => void;\n\n /**\n * Called once the user confirms Restore Default Favorites.\n *\n * The catalog reports the intent and proposes nothing: what the defaults are, whether locked\n * destinations survive and how the reset is persisted are all the host's. Favourites move only\n * when the host sends new `pinnedIds` down, and the catalog does not also call\n * `onPinnedIdsChange`.\n *\n * Omit it to hide the restore control — including when the host offers defaults but the user\n * has not strayed from them, which only the host can know.\n */\n onResetToDefaults?: () => void;\n}\n\nexport interface TitanLayoutLinkExtraProps {\n /** link's title should be shown (for extra links we show icon only by default) */\n showTitle?: boolean;\n /** link is flashing */\n flashing?: boolean;\n}\n\nexport interface TitanLayoutLinkSideProps {\n /** counter value used only for side links */\n counter: CounterTagValue;\n}\n\nexport type TitanLayoutLinkProps = {\n /** link id */\n id: string;\n /** link href */\n to: string;\n /** link title */\n title: string;\n /** callback to return active state. By default, it compares link href with current pathname */\n isActive?: boolean | ((pathname: string) => boolean);\n /** svg icon (anvil2) of inactive item */\n icon: IconProps['svg'] | undefined;\n /** svg icon (anvil2) of active item */\n iconActive: IconProps['svg'] | undefined;\n /** item tag (optional). shown if it is set and value is true or greater than 0 */\n tag?: CounterTagData;\n counter?: CounterTagValue;\n /** class name of link item */\n className?: string;\n\n /** tooltip text (for extra links) */\n tooltip?: string;\n /** wrapper component for link element (used for side links) */\n wrapper?: TitanLayoutLinkWrapper;\n /** props for extra link element */\n extra?: TitanLayoutLinkExtraProps;\n /** props for side nav link element (mobile version) */\n side?: TitanLayoutLinkSideProps;\n} & Omit<ComponentPropsWithoutRef<'a'>, 'children' | 'title'>;\n\nexport type TitanLayoutTriggerProps = {\n /** link id */\n id: string;\n /** link title */\n title: string;\n /** active state */\n isActive?: boolean;\n /** svg icon (anvil2) of inactive item */\n icon: IconProps['svg'] | undefined;\n /** svg icon (anvil2) of active item */\n iconActive: IconProps['svg'] | undefined;\n /** item tag (optional). shown if it is set and value is true or greater than 0 */\n tag?: CounterTagData;\n counter?: CounterTagValue;\n /** class name of link item */\n className?: string;\n\n /** tooltip text (for extra links) */\n tooltip?: string;\n /** wrapper component for link element (used for side links) */\n wrapper?: TitanLayoutLinkWrapper;\n /** props for extra link element */\n extra?: TitanLayoutLinkExtraProps;\n /** props for nav link element (mobile version) */\n side?: TitanLayoutLinkSideProps;\n} & Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'title'>;\n"],"names":[],"mappings":"AA+HA,WAyBgE"}
@@ -18,6 +18,7 @@ export declare const InternalSideNavigationLink: FC<NavigationComponentProps & {
18
18
  iconActive: IconProps['svg'] | undefined;
19
19
  className: string | undefined;
20
20
  tag: BadgeTagProps | undefined;
21
+ notificationCount?: number;
21
22
  } & Omit<ComponentPropsWithoutRef<'a'>, 'children' | 'title'>>;
22
23
  /** Side Navigation menu trigger (for internal usage) */
23
24
  export declare const InternalSideNavigationTrigger: FC<{
@@ -28,6 +29,7 @@ export declare const InternalSideNavigationTrigger: FC<{
28
29
  iconActive: IconProps['svg'] | undefined;
29
30
  className: string | undefined;
30
31
  tag: BadgeTagProps | undefined;
32
+ notificationCount?: number;
31
33
  onClick?: (e: MouseEvent<never>) => void;
32
34
  } & Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'title'>>;
33
35
  export declare const InternalSideNavigationGroupLink: FC<NavigationComponentProps & {
@@ -58,6 +60,7 @@ export declare const InternalSideNavigationGroup: FC<NavigationComponentProps &
58
60
  iconActive: IconProps['svg'] | undefined;
59
61
  className: string | undefined;
60
62
  tag: BadgeTagProps | undefined;
63
+ notificationCount?: number;
61
64
  children: ReactNode;
62
65
  submenuOpened: boolean;
63
66
  onClick?: (e: MouseEvent<never>) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"layout-sidebar-links-internal.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/layout-sidebar-links-internal.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout-sidebar-links-internal.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/layout-sidebar-links-internal.tsx"],"names":[],"mappings":"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"}
@@ -3,7 +3,8 @@ import { Button, Icon } from '@servicetitan/anvil2';
3
3
  import SvgGroupCollapse from '@servicetitan/anvil2/assets/icons/material/round/expand_less.svg';
4
4
  import SvgGroupExpand from '@servicetitan/anvil2/assets/icons/material/round/expand_more.svg';
5
5
  import classNames from 'classnames';
6
- import { Fragment } from 'react';
6
+ import { Fragment, useId } from 'react';
7
+ import { getNotificationCount } from '../../utils/navigation-notifications';
7
8
  import { BadgeTag } from '../badge-tag';
8
9
  import * as Styles from './layout-sidebar.module.less';
9
10
  import { withTooltip } from './with-tooltip';
@@ -33,18 +34,17 @@ const InternalSideNavigationItemContent = ({ icon, iconActive, tag, title })=>/*
33
34
  ]
34
35
  }),
35
36
  /*#__PURE__*/ _jsx("div", {
36
- className: classNames(Styles.navItemTextCollapsed, {
37
- [Styles.navItemTextSmall]: !!title && title.length >= 10
38
- }),
37
+ className: Styles.navItemTextCollapsed,
39
38
  "data-cy": "nav-item-label",
40
39
  children: title
41
40
  })
42
41
  ]
43
42
  });
44
- /** Side Navigation menu item (for internal usage) */ export const InternalSideNavigationLink = ({ id, to, title, isActive, icon, iconActive, className, tag, navigationComponent: NavigationComponent, ...rest })=>{
43
+ /** Side Navigation menu item (for internal usage) */ export const InternalSideNavigationLink = ({ id, to, title, isActive, icon, iconActive, className, tag, notificationCount = getNotificationCount(tag === null || tag === void 0 ? void 0 : tag.value), navigationComponent: NavigationComponent, ...rest })=>{
45
44
  return /*#__PURE__*/ _jsx(NavigationComponent, {
46
45
  "data-cy": `navigation-item-${id}`,
47
46
  "data-pendo": `navigation-item-${id}`,
47
+ "data-navigation-notification-count": notificationCount || undefined,
48
48
  ...rest,
49
49
  className: classNames(Styles.navItem, Styles.navLink, className, {
50
50
  [Styles.navItemActive]: isActive === true,
@@ -62,10 +62,11 @@ const InternalSideNavigationItemContent = ({ icon, iconActive, tag, title })=>/*
62
62
  })
63
63
  });
64
64
  };
65
- /** Side Navigation menu trigger (for internal usage) */ export const InternalSideNavigationTrigger = ({ id, title, isActive, icon, iconActive, className, tag, ...rest })=>{
65
+ /** Side Navigation menu trigger (for internal usage) */ export const InternalSideNavigationTrigger = ({ id, title, isActive, icon, iconActive, className, tag, notificationCount = getNotificationCount(tag === null || tag === void 0 ? void 0 : tag.value), ...rest })=>{
66
66
  return /*#__PURE__*/ _jsx("div", {
67
67
  "data-cy": `navigation-item-${id}`,
68
68
  "data-pendo": `navigation-item-${id}`,
69
+ "data-navigation-notification-count": notificationCount || undefined,
69
70
  tabIndex: rest.onClick ? 0 : -1,
70
71
  ...rest,
71
72
  className: classNames(Styles.navItem, className, {
@@ -88,6 +89,7 @@ export const InternalSideNavigationGroupLink = ({ id, to, title, isActive, class
88
89
  children: /*#__PURE__*/ _jsxs(NavigationComponent, {
89
90
  "data-cy": `navigation-item-${parentId}--${id}`,
90
91
  "data-pendo": `navigation-item-${parentId}--${id}`,
92
+ "data-navigation-notification-count": getNotificationCount(tag === null || tag === void 0 ? void 0 : tag.value) || undefined,
91
93
  ...rest,
92
94
  to: to,
93
95
  className: classNames(Styles.submenuItem, Styles.submenuLink, className, {
@@ -110,6 +112,7 @@ export const InternalSideNavigationGroupLink = ({ id, to, title, isActive, class
110
112
  export const InternalSideNavigationGroupTrigger = ({ id, title, isActive, className, tag, ...rest })=>{
111
113
  return /*#__PURE__*/ _jsxs("div", {
112
114
  "data-cy": `navigation-item-${id}`,
115
+ "data-navigation-notification-count": getNotificationCount(tag === null || tag === void 0 ? void 0 : tag.value) || undefined,
113
116
  "data-pendo": `navigation-item-${id}`,
114
117
  ...rest,
115
118
  className: classNames(Styles.submenuItem, {
@@ -132,19 +135,49 @@ export const InternalSideNavigationGroupDivider = ()=>{
132
135
  className: Styles.divider
133
136
  });
134
137
  };
135
- export const InternalSideNavigationGroup = ({ id, to, title, isActive, icon, iconActive, className, tag, children, submenuOpened, onSubmenuOpen, onClick, navigationComponent, ...rest })=>{
138
+ export const InternalSideNavigationGroup = ({ id, to, title, isActive, icon, iconActive, className, tag, notificationCount, children, submenuOpened, onSubmenuOpen, onClick, navigationComponent, ...rest })=>{
139
+ const submenuId = useId();
136
140
  const onToggleClick = (e)=>{
137
- onSubmenuOpen(id, !submenuOpened);
138
141
  e.preventDefault();
139
142
  e.stopPropagation();
143
+ onSubmenuOpen(id, !submenuOpened);
140
144
  };
141
145
  return /*#__PURE__*/ _jsxs("div", {
142
- className: classNames(Styles.navGroupWrapper),
146
+ className: classNames(Styles.navGroupWrapper, {
147
+ [Styles.navGroupOpened]: submenuOpened
148
+ }),
143
149
  children: [
144
150
  /*#__PURE__*/ _jsxs("div", {
145
151
  className: Styles.navGroupItem,
146
152
  children: [
147
153
  /*#__PURE__*/ _jsx("div", {
154
+ // Update expansion before the host link handles navigation to its destination.
155
+ onClickCapture: (event)=>{
156
+ if (!to) {
157
+ onToggleClick(event);
158
+ } else if (/*
159
+ * A module name only ever opens. It navigates into the module, so
160
+ * collapsing would hide the very page the click is about to land on —
161
+ * the destination is `to`, whether that is a page itself or an entry
162
+ * route the host redirects to the module's default page. Collapsing an
163
+ * open module is the chevron's job.
164
+ */ !submenuOpened && event.button === 0 && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
165
+ onSubmenuOpen(id, true);
166
+ }
167
+ },
168
+ onClick: (event)=>event.stopPropagation(),
169
+ onKeyDownCapture: (event)=>{
170
+ if ((event.key === 'Enter' || event.key === ' ') && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
171
+ if (to) {
172
+ var _event_currentTarget_querySelector;
173
+ event.preventDefault();
174
+ event.stopPropagation();
175
+ (_event_currentTarget_querySelector = event.currentTarget.querySelector('a')) === null || _event_currentTarget_querySelector === void 0 ? void 0 : _event_currentTarget_querySelector.click();
176
+ } else {
177
+ onToggleClick(event);
178
+ }
179
+ }
180
+ },
148
181
  children: to ? /*#__PURE__*/ _jsx(InternalSideNavigationLink, {
149
182
  id: id,
150
183
  to: to,
@@ -153,8 +186,11 @@ export const InternalSideNavigationGroup = ({ id, to, title, isActive, icon, ico
153
186
  icon: icon,
154
187
  iconActive: iconActive,
155
188
  tag: tag,
189
+ notificationCount: notificationCount,
156
190
  className: className,
157
191
  ...rest,
192
+ "aria-expanded": submenuOpened,
193
+ "aria-controls": submenuId,
158
194
  navigationComponent: navigationComponent
159
195
  }) : /*#__PURE__*/ _jsx(InternalSideNavigationTrigger, {
160
196
  id: id,
@@ -163,19 +199,27 @@ export const InternalSideNavigationGroup = ({ id, to, title, isActive, icon, ico
163
199
  icon: icon,
164
200
  iconActive: iconActive,
165
201
  tag: tag,
202
+ notificationCount: notificationCount,
166
203
  className: className,
167
- ...rest
204
+ ...rest,
205
+ role: "button",
206
+ tabIndex: 0,
207
+ onClick: onToggleClick,
208
+ "aria-expanded": submenuOpened,
209
+ "aria-controls": submenuId
168
210
  })
169
211
  }),
170
212
  /*#__PURE__*/ _jsx("div", {
171
213
  className: Styles.navItemGroupToggleWrapper,
172
214
  children: withTooltip(/*#__PURE__*/ _jsx(Button, {
173
- appearance: "secondary",
174
- size: "small",
215
+ appearance: "ghost",
216
+ size: "xsmall",
175
217
  icon: submenuOpened ? SvgGroupCollapse : SvgGroupExpand,
176
218
  className: Styles.navItemGroupToggle,
177
219
  onClick: onToggleClick,
178
- "aria-label": "Toggle submenu",
220
+ "aria-label": `${submenuOpened ? 'Collapse' : 'Expand'} ${title} submenu`,
221
+ "aria-expanded": submenuOpened,
222
+ "aria-controls": submenuId,
179
223
  "data-cy": "nav-item-group-expand"
180
224
  }), // hide submenu tooltip for now
181
225
  icon ? undefined : submenuOpened ? 'Hide Submenu' : 'View Submenu', {
@@ -186,6 +230,7 @@ export const InternalSideNavigationGroup = ({ id, to, title, isActive, icon, ico
186
230
  ]
187
231
  }),
188
232
  submenuOpened && /*#__PURE__*/ _jsx("div", {
233
+ id: submenuId,
189
234
  className: classNames(Styles.submenuWrapper, {
190
235
  [Styles.submenuWrapperCollapsed]: !submenuOpened
191
236
  }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/titan-layout/layout-sidebar-links-internal.tsx"],"sourcesContent":["import { Button, Icon, IconProps } from '@servicetitan/anvil2';\nimport SvgGroupCollapse from '@servicetitan/anvil2/assets/icons/material/round/expand_less.svg';\nimport SvgGroupExpand from '@servicetitan/anvil2/assets/icons/material/round/expand_more.svg';\nimport classNames from 'classnames';\nimport { ComponentPropsWithoutRef, FC, Fragment, MouseEvent, ReactNode } from 'react';\n\nimport { BadgeTag, BadgeTagProps } from '../badge-tag';\nimport { NavigationComponentProps } from './interface-internal';\nimport * as Styles from './layout-sidebar.module.less';\nimport { withTooltip } from './with-tooltip';\n\nexport interface InternalSideNavigationItemContentProps {\n icon: IconProps['svg'] | undefined;\n iconActive: IconProps['svg'] | undefined;\n title: string;\n tag: BadgeTagProps | undefined;\n}\n\nconst InternalSideNavigationItemContent: FC<InternalSideNavigationItemContentProps> = ({\n icon,\n iconActive,\n tag,\n title,\n}) => (\n <Fragment>\n <div className={Styles.navItemIconWrapper}>\n {icon && (\n <Icon svg={icon} className={classNames(Styles.navIcon, Styles.navIconInactive)} />\n )}\n {iconActive && (\n <Icon\n svg={iconActive}\n className={classNames(Styles.navIcon, Styles.navIconActive)}\n />\n )}\n\n <div className={Styles.navItemTextExpanded} data-cy=\"nav-item-label\">\n {title}\n </div>\n {!!tag && (\n <BadgeTag\n data={tag}\n className={Styles.navItemCounter}\n longClassName={Styles.navItemCounterLong}\n />\n )}\n </div>\n\n <div\n className={classNames(Styles.navItemTextCollapsed, {\n [Styles.navItemTextSmall]: !!title && title.length >= 10,\n })}\n data-cy=\"nav-item-label\"\n >\n {title}\n </div>\n </Fragment>\n);\n\n/** Side Navigation menu item (for internal usage) */\nexport const InternalSideNavigationLink: FC<\n NavigationComponentProps & {\n id: string;\n to: string;\n title: string;\n isActive: boolean | ((pathname: string) => boolean) | undefined;\n icon: IconProps['svg'] | undefined;\n iconActive: IconProps['svg'] | undefined;\n className: string | undefined;\n tag: BadgeTagProps | undefined;\n } & Omit<ComponentPropsWithoutRef<'a'>, 'children' | 'title'>\n> = ({\n id,\n to,\n title,\n isActive,\n icon,\n iconActive,\n className,\n tag,\n\n navigationComponent: NavigationComponent,\n ...rest\n}) => {\n return (\n <NavigationComponent\n data-cy={`navigation-item-${id}`}\n data-pendo={`navigation-item-${id}`}\n {...rest}\n className={classNames(Styles.navItem, Styles.navLink, className, {\n [Styles.navItemActive]: isActive === true,\n [Styles.navItemIconSwitch]: !!icon && !!iconActive,\n })}\n to={to}\n isActive={typeof isActive === 'function' ? isActive : undefined}\n activeClassName={Styles.navItemActive}\n tabIndex={0}\n >\n <InternalSideNavigationItemContent\n icon={icon}\n iconActive={iconActive}\n title={title}\n tag={tag}\n />\n </NavigationComponent>\n );\n};\n\n/** Side Navigation menu trigger (for internal usage) */\nexport const InternalSideNavigationTrigger: FC<\n {\n id: string;\n title: string;\n isActive: boolean | undefined;\n icon: IconProps['svg'] | undefined;\n iconActive: IconProps['svg'] | undefined;\n className: string | undefined;\n\n tag: BadgeTagProps | undefined;\n onClick?: (e: MouseEvent<never>) => void;\n } & Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'title'>\n> = ({\n id,\n title,\n isActive,\n icon,\n iconActive,\n className,\n\n tag,\n ...rest\n}) => {\n return (\n <div\n data-cy={`navigation-item-${id}`}\n data-pendo={`navigation-item-${id}`}\n tabIndex={rest.onClick ? 0 : -1}\n {...rest}\n className={classNames(Styles.navItem, className, {\n [Styles.navLink]: !!rest.onClick,\n [Styles.navItemActive]: isActive === true,\n [Styles.navItemIconSwitch]: !!icon && !!iconActive,\n })}\n >\n <InternalSideNavigationItemContent\n icon={icon}\n iconActive={iconActive}\n title={title}\n tag={tag}\n />\n </div>\n );\n};\n\nexport const InternalSideNavigationGroupLink: FC<\n NavigationComponentProps & {\n id: string;\n to: string;\n title: string;\n isActive: boolean | ((pathname: string) => boolean) | undefined;\n className: string | undefined;\n tag: BadgeTagProps | undefined;\n\n parentId: string;\n onLinkClick?: (parentItemId: string, itemId: string) => void;\n }\n> = ({\n id,\n to,\n title,\n isActive,\n className,\n tag,\n\n parentId,\n onLinkClick,\n navigationComponent: NavigationComponent,\n ...rest\n}) => {\n return (\n <div\n onClickCapture={onLinkClick ? () => onLinkClick(parentId, id) : undefined}\n className={Styles.submenuItemWrapper}\n >\n <NavigationComponent\n key={id}\n data-cy={`navigation-item-${parentId}--${id}`}\n data-pendo={`navigation-item-${parentId}--${id}`}\n {...rest}\n to={to}\n className={classNames(Styles.submenuItem, Styles.submenuLink, className, {\n [Styles.submenuLinkActive]: isActive === true,\n })}\n isActive={typeof isActive === 'function' ? isActive : undefined}\n activeClassName={Styles.submenuLinkActive}\n >\n <span>{title}</span>\n <BadgeTag data={tag} className={Styles.submenuLinkCounter} />\n </NavigationComponent>\n </div>\n );\n};\n\nexport const InternalSideNavigationGroupTrigger: FC<{\n id: string;\n title: string;\n isActive: boolean | ((pathname: string) => boolean) | undefined;\n className: string | undefined;\n tag: BadgeTagProps | undefined;\n\n onClick?: (e: MouseEvent<any>) => void;\n}> = ({\n id,\n title,\n isActive,\n className,\n tag,\n\n ...rest\n}) => {\n return (\n <div\n data-cy={`navigation-item-${id}`}\n data-pendo={`navigation-item-${id}`}\n key={id}\n {...rest}\n className={classNames(Styles.submenuItem, {\n [Styles.submenuLink]: !!rest.onClick,\n [Styles.submenuLinkActive]: isActive === true,\n })}\n >\n <span>{title}</span>\n <BadgeTag data={tag} className={Styles.submenuLinkCounter} />\n </div>\n );\n};\n\nexport const InternalSideNavigationGroupDivider = () => {\n return <div className={Styles.divider} />;\n};\n\nexport const InternalSideNavigationGroup: FC<\n NavigationComponentProps & {\n id: string;\n to: string | undefined;\n title: string;\n isActive: boolean | ((pathname: string) => boolean) | undefined;\n icon: IconProps['svg'] | undefined;\n iconActive: IconProps['svg'] | undefined;\n className: string | undefined;\n tag: BadgeTagProps | undefined;\n\n children: ReactNode;\n submenuOpened: boolean;\n onClick?: (e: MouseEvent<never>) => void;\n onSubmenuOpen(id: string, opened: boolean): void;\n }\n> = ({\n id,\n to,\n title,\n isActive,\n icon,\n iconActive,\n className,\n tag,\n\n children,\n submenuOpened,\n onSubmenuOpen,\n onClick,\n navigationComponent,\n ...rest\n}) => {\n const onToggleClick = (e: MouseEvent<never>) => {\n onSubmenuOpen(id, !submenuOpened);\n e.preventDefault();\n e.stopPropagation();\n };\n\n return (\n <div className={classNames(Styles.navGroupWrapper)}>\n <div className={Styles.navGroupItem}>\n <div>\n {to ? (\n <InternalSideNavigationLink\n id={id}\n to={to}\n title={title}\n isActive={isActive}\n icon={icon}\n iconActive={iconActive}\n tag={tag}\n className={className}\n {...rest}\n navigationComponent={navigationComponent}\n />\n ) : (\n <InternalSideNavigationTrigger\n id={id}\n title={title}\n isActive={isActive === true || undefined}\n icon={icon}\n iconActive={iconActive}\n tag={tag}\n className={className}\n {...rest}\n />\n )}\n </div>\n\n <div className={Styles.navItemGroupToggleWrapper}>\n {withTooltip(\n <Button\n appearance=\"secondary\"\n size=\"small\"\n icon={submenuOpened ? SvgGroupCollapse : SvgGroupExpand}\n className={Styles.navItemGroupToggle}\n onClick={onToggleClick}\n aria-label=\"Toggle submenu\"\n data-cy=\"nav-item-group-expand\"\n />,\n // hide submenu tooltip for now\n icon ? undefined : submenuOpened ? 'Hide Submenu' : 'View Submenu',\n { placement: 'right', delay: 1000 }\n )}\n </div>\n </div>\n {submenuOpened && (\n <div\n className={classNames(Styles.submenuWrapper, {\n [Styles.submenuWrapperCollapsed]: !submenuOpened,\n })}\n data-cy={`navigation-submenu-${id}`}\n >\n <div className={Styles.submenu}>{children}</div>\n </div>\n )}\n </div>\n );\n};\n"],"names":["Button","Icon","SvgGroupCollapse","SvgGroupExpand","classNames","Fragment","BadgeTag","Styles","withTooltip","InternalSideNavigationItemContent","icon","iconActive","tag","title","div","className","navItemIconWrapper","svg","navIcon","navIconInactive","navIconActive","navItemTextExpanded","data-cy","data","navItemCounter","longClassName","navItemCounterLong","navItemTextCollapsed","navItemTextSmall","length","InternalSideNavigationLink","id","to","isActive","navigationComponent","NavigationComponent","rest","data-pendo","navItem","navLink","navItemActive","navItemIconSwitch","undefined","activeClassName","tabIndex","InternalSideNavigationTrigger","onClick","InternalSideNavigationGroupLink","parentId","onLinkClick","onClickCapture","submenuItemWrapper","submenuItem","submenuLink","submenuLinkActive","span","submenuLinkCounter","InternalSideNavigationGroupTrigger","InternalSideNavigationGroupDivider","divider","InternalSideNavigationGroup","children","submenuOpened","onSubmenuOpen","onToggleClick","e","preventDefault","stopPropagation","navGroupWrapper","navGroupItem","navItemGroupToggleWrapper","appearance","size","navItemGroupToggle","aria-label","placement","delay","submenuWrapper","submenuWrapperCollapsed","submenu"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/titan-layout/layout-sidebar-links-internal.tsx"],"sourcesContent":["import { Button, Icon, IconProps } from '@servicetitan/anvil2';\nimport SvgGroupCollapse from '@servicetitan/anvil2/assets/icons/material/round/expand_less.svg';\nimport SvgGroupExpand from '@servicetitan/anvil2/assets/icons/material/round/expand_more.svg';\nimport classNames from 'classnames';\nimport {\n ComponentPropsWithoutRef,\n FC,\n Fragment,\n MouseEvent,\n ReactNode,\n SyntheticEvent,\n useId,\n} from 'react';\nimport { getNotificationCount } from '../../utils/navigation-notifications';\n\nimport { BadgeTag, BadgeTagProps } from '../badge-tag';\nimport { NavigationComponentProps } from './interface-internal';\nimport * as Styles from './layout-sidebar.module.less';\nimport { withTooltip } from './with-tooltip';\n\nexport interface InternalSideNavigationItemContentProps {\n icon: IconProps['svg'] | undefined;\n iconActive: IconProps['svg'] | undefined;\n title: string;\n tag: BadgeTagProps | undefined;\n}\n\nconst InternalSideNavigationItemContent: FC<InternalSideNavigationItemContentProps> = ({\n icon,\n iconActive,\n tag,\n title,\n}) => (\n <Fragment>\n <div className={Styles.navItemIconWrapper}>\n {icon && (\n <Icon svg={icon} className={classNames(Styles.navIcon, Styles.navIconInactive)} />\n )}\n {iconActive && (\n <Icon\n svg={iconActive}\n className={classNames(Styles.navIcon, Styles.navIconActive)}\n />\n )}\n\n <div className={Styles.navItemTextExpanded} data-cy=\"nav-item-label\">\n {title}\n </div>\n {!!tag && (\n <BadgeTag\n data={tag}\n className={Styles.navItemCounter}\n longClassName={Styles.navItemCounterLong}\n />\n )}\n </div>\n\n <div className={Styles.navItemTextCollapsed} data-cy=\"nav-item-label\">\n {title}\n </div>\n </Fragment>\n);\n\n/** Side Navigation menu item (for internal usage) */\nexport const InternalSideNavigationLink: FC<\n NavigationComponentProps & {\n id: string;\n to: string;\n title: string;\n isActive: boolean | ((pathname: string) => boolean) | undefined;\n icon: IconProps['svg'] | undefined;\n iconActive: IconProps['svg'] | undefined;\n className: string | undefined;\n tag: BadgeTagProps | undefined;\n notificationCount?: number;\n } & Omit<ComponentPropsWithoutRef<'a'>, 'children' | 'title'>\n> = ({\n id,\n to,\n title,\n isActive,\n icon,\n iconActive,\n className,\n tag,\n notificationCount = getNotificationCount(tag?.value),\n\n navigationComponent: NavigationComponent,\n ...rest\n}) => {\n return (\n <NavigationComponent\n data-cy={`navigation-item-${id}`}\n data-pendo={`navigation-item-${id}`}\n data-navigation-notification-count={notificationCount || undefined}\n {...rest}\n className={classNames(Styles.navItem, Styles.navLink, className, {\n [Styles.navItemActive]: isActive === true,\n [Styles.navItemIconSwitch]: !!icon && !!iconActive,\n })}\n to={to}\n isActive={typeof isActive === 'function' ? isActive : undefined}\n activeClassName={Styles.navItemActive}\n tabIndex={0}\n >\n <InternalSideNavigationItemContent\n icon={icon}\n iconActive={iconActive}\n title={title}\n tag={tag}\n />\n </NavigationComponent>\n );\n};\n\n/** Side Navigation menu trigger (for internal usage) */\nexport const InternalSideNavigationTrigger: FC<\n {\n id: string;\n title: string;\n isActive: boolean | undefined;\n icon: IconProps['svg'] | undefined;\n iconActive: IconProps['svg'] | undefined;\n className: string | undefined;\n\n tag: BadgeTagProps | undefined;\n notificationCount?: number;\n onClick?: (e: MouseEvent<never>) => void;\n } & Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'title'>\n> = ({\n id,\n title,\n isActive,\n icon,\n iconActive,\n className,\n\n tag,\n notificationCount = getNotificationCount(tag?.value),\n ...rest\n}) => {\n return (\n <div\n data-cy={`navigation-item-${id}`}\n data-pendo={`navigation-item-${id}`}\n data-navigation-notification-count={notificationCount || undefined}\n tabIndex={rest.onClick ? 0 : -1}\n {...rest}\n className={classNames(Styles.navItem, className, {\n [Styles.navLink]: !!rest.onClick,\n [Styles.navItemActive]: isActive === true,\n [Styles.navItemIconSwitch]: !!icon && !!iconActive,\n })}\n >\n <InternalSideNavigationItemContent\n icon={icon}\n iconActive={iconActive}\n title={title}\n tag={tag}\n />\n </div>\n );\n};\n\nexport const InternalSideNavigationGroupLink: FC<\n NavigationComponentProps & {\n id: string;\n to: string;\n title: string;\n isActive: boolean | ((pathname: string) => boolean) | undefined;\n className: string | undefined;\n tag: BadgeTagProps | undefined;\n\n parentId: string;\n onLinkClick?: (parentItemId: string, itemId: string) => void;\n }\n> = ({\n id,\n to,\n title,\n isActive,\n className,\n tag,\n\n parentId,\n onLinkClick,\n navigationComponent: NavigationComponent,\n ...rest\n}) => {\n return (\n <div\n onClickCapture={onLinkClick ? () => onLinkClick(parentId, id) : undefined}\n className={Styles.submenuItemWrapper}\n >\n <NavigationComponent\n key={id}\n data-cy={`navigation-item-${parentId}--${id}`}\n data-pendo={`navigation-item-${parentId}--${id}`}\n data-navigation-notification-count={getNotificationCount(tag?.value) || undefined}\n {...rest}\n to={to}\n className={classNames(Styles.submenuItem, Styles.submenuLink, className, {\n [Styles.submenuLinkActive]: isActive === true,\n })}\n isActive={typeof isActive === 'function' ? isActive : undefined}\n activeClassName={Styles.submenuLinkActive}\n >\n <span>{title}</span>\n <BadgeTag data={tag} className={Styles.submenuLinkCounter} />\n </NavigationComponent>\n </div>\n );\n};\n\nexport const InternalSideNavigationGroupTrigger: FC<{\n id: string;\n title: string;\n isActive: boolean | ((pathname: string) => boolean) | undefined;\n className: string | undefined;\n tag: BadgeTagProps | undefined;\n\n onClick?: (e: MouseEvent<any>) => void;\n}> = ({\n id,\n title,\n isActive,\n className,\n tag,\n\n ...rest\n}) => {\n return (\n <div\n data-cy={`navigation-item-${id}`}\n data-navigation-notification-count={getNotificationCount(tag?.value) || undefined}\n data-pendo={`navigation-item-${id}`}\n key={id}\n {...rest}\n className={classNames(Styles.submenuItem, {\n [Styles.submenuLink]: !!rest.onClick,\n [Styles.submenuLinkActive]: isActive === true,\n })}\n >\n <span>{title}</span>\n <BadgeTag data={tag} className={Styles.submenuLinkCounter} />\n </div>\n );\n};\n\nexport const InternalSideNavigationGroupDivider = () => {\n return <div className={Styles.divider} />;\n};\n\nexport const InternalSideNavigationGroup: FC<\n NavigationComponentProps & {\n id: string;\n to: string | undefined;\n title: string;\n isActive: boolean | ((pathname: string) => boolean) | undefined;\n icon: IconProps['svg'] | undefined;\n iconActive: IconProps['svg'] | undefined;\n className: string | undefined;\n tag: BadgeTagProps | undefined;\n\n notificationCount?: number;\n children: ReactNode;\n submenuOpened: boolean;\n onClick?: (e: MouseEvent<never>) => void;\n onSubmenuOpen(id: string, opened: boolean): void;\n }\n> = ({\n id,\n to,\n title,\n isActive,\n icon,\n iconActive,\n className,\n tag,\n\n notificationCount,\n children,\n submenuOpened,\n onSubmenuOpen,\n onClick,\n navigationComponent,\n ...rest\n}) => {\n const submenuId = useId();\n const onToggleClick = (e: SyntheticEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuOpen(id, !submenuOpened);\n };\n\n return (\n <div\n className={classNames(Styles.navGroupWrapper, {\n [Styles.navGroupOpened]: submenuOpened,\n })}\n >\n <div className={Styles.navGroupItem}>\n <div\n // Update expansion before the host link handles navigation to its destination.\n onClickCapture={event => {\n if (!to) {\n onToggleClick(event);\n } else if (\n /*\n * A module name only ever opens. It navigates into the module, so\n * collapsing would hide the very page the click is about to land on —\n * the destination is `to`, whether that is a page itself or an entry\n * route the host redirects to the module's default page. Collapsing an\n * open module is the chevron's job.\n */\n !submenuOpened &&\n event.button === 0 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n onSubmenuOpen(id, true);\n }\n }}\n onClick={event => event.stopPropagation()}\n onKeyDownCapture={event => {\n if (\n (event.key === 'Enter' || event.key === ' ') &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey\n ) {\n if (to) {\n event.preventDefault();\n event.stopPropagation();\n event.currentTarget.querySelector('a')?.click();\n } else {\n onToggleClick(event);\n }\n }\n }}\n >\n {to ? (\n <InternalSideNavigationLink\n id={id}\n to={to}\n title={title}\n isActive={isActive}\n icon={icon}\n iconActive={iconActive}\n tag={tag}\n notificationCount={notificationCount}\n className={className}\n {...rest}\n aria-expanded={submenuOpened}\n aria-controls={submenuId}\n navigationComponent={navigationComponent}\n />\n ) : (\n <InternalSideNavigationTrigger\n id={id}\n title={title}\n isActive={isActive === true || undefined}\n icon={icon}\n iconActive={iconActive}\n tag={tag}\n notificationCount={notificationCount}\n className={className}\n {...rest}\n role=\"button\"\n tabIndex={0}\n onClick={onToggleClick}\n aria-expanded={submenuOpened}\n aria-controls={submenuId}\n />\n )}\n </div>\n\n <div className={Styles.navItemGroupToggleWrapper}>\n {withTooltip(\n <Button\n appearance=\"ghost\"\n size=\"xsmall\"\n icon={submenuOpened ? SvgGroupCollapse : SvgGroupExpand}\n className={Styles.navItemGroupToggle}\n onClick={onToggleClick}\n aria-label={`${submenuOpened ? 'Collapse' : 'Expand'} ${title} submenu`}\n aria-expanded={submenuOpened}\n aria-controls={submenuId}\n data-cy=\"nav-item-group-expand\"\n />,\n // hide submenu tooltip for now\n icon ? undefined : submenuOpened ? 'Hide Submenu' : 'View Submenu',\n { placement: 'right', delay: 1000 }\n )}\n </div>\n </div>\n {submenuOpened && (\n <div\n id={submenuId}\n className={classNames(Styles.submenuWrapper, {\n [Styles.submenuWrapperCollapsed]: !submenuOpened,\n })}\n data-cy={`navigation-submenu-${id}`}\n >\n <div className={Styles.submenu}>{children}</div>\n </div>\n )}\n </div>\n );\n};\n"],"names":["Button","Icon","SvgGroupCollapse","SvgGroupExpand","classNames","Fragment","useId","getNotificationCount","BadgeTag","Styles","withTooltip","InternalSideNavigationItemContent","icon","iconActive","tag","title","div","className","navItemIconWrapper","svg","navIcon","navIconInactive","navIconActive","navItemTextExpanded","data-cy","data","navItemCounter","longClassName","navItemCounterLong","navItemTextCollapsed","InternalSideNavigationLink","id","to","isActive","notificationCount","value","navigationComponent","NavigationComponent","rest","data-pendo","data-navigation-notification-count","undefined","navItem","navLink","navItemActive","navItemIconSwitch","activeClassName","tabIndex","InternalSideNavigationTrigger","onClick","InternalSideNavigationGroupLink","parentId","onLinkClick","onClickCapture","submenuItemWrapper","submenuItem","submenuLink","submenuLinkActive","span","submenuLinkCounter","InternalSideNavigationGroupTrigger","InternalSideNavigationGroupDivider","divider","InternalSideNavigationGroup","children","submenuOpened","onSubmenuOpen","submenuId","onToggleClick","e","preventDefault","stopPropagation","navGroupWrapper","navGroupOpened","navGroupItem","event","button","altKey","ctrlKey","metaKey","shiftKey","onKeyDownCapture","key","currentTarget","querySelector","click","aria-expanded","aria-controls","role","navItemGroupToggleWrapper","appearance","size","navItemGroupToggle","aria-label","placement","delay","submenuWrapper","submenuWrapperCollapsed","submenu"],"mappings":"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"}
@@ -1,11 +1,24 @@
1
1
  import { FC, ReactElement } from 'react';
2
2
  import { NavigationItemData } from '../../utils/navigation';
3
3
  import { NavLinkComponentProps } from '../../utils/navigation-context';
4
+ import { PinnedNavigationConfig } from './interface';
4
5
  export interface LayoutSidebarProps {
5
6
  className?: string;
6
7
  top?: ReactElement[];
8
+ /**
9
+ * Destinations rendered above the divider, ahead of `top`.
10
+ *
11
+ * Separate from `top` rather than widening it: that one takes elements a host builds itself
12
+ * and renders them as-is, which is what a bespoke control needs. This takes navigation items
13
+ * and puts them through the same renderer as `mainItems`, so one with pages beneath it is an
14
+ * expandable group instead of being flattened to a bare link.
15
+ */
16
+ topItems?: NavigationItemData[];
17
+ /** Whether the rail shows the scroll and overflow-notification indicators. */
18
+ scrollIndicators?: boolean;
7
19
  bottom?: ReactElement;
8
20
  mainItems?: NavigationItemData[];
21
+ pinnedNavigation?: PinnedNavigationConfig;
9
22
  barExpanded: boolean;
10
23
  submenusOpened: string[] | undefined;
11
24
  drawerOpened: boolean;
@@ -15,6 +28,7 @@ export interface LayoutSidebarProps {
15
28
  onBarExpandChange(expanded: boolean): void;
16
29
  onDrawerOpenChange(expanded: boolean): void;
17
30
  onSubmenuOpenChange(id: string, opened: boolean): void;
31
+ onSubmenusOpenChange?(ids: string[], opened: boolean): void;
18
32
  onNavigationLinkClick?(itemId: string, submenuItemId?: string): void;
19
33
  }
20
34
  export declare const LayoutSidebar: FC<LayoutSidebarProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"layout-sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/layout-sidebar.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAY,EAAE,EAAY,YAAY,EAAkB,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAyB,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAYvE,MAAM,WAAW,kBAAkB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC;IAC/C,iBAAiB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,kBAAkB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvD,qBAAqB,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxE;AAED,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CA2GhD,CAAC"}
1
+ {"version":3,"file":"layout-sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/layout-sidebar.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAY,EAAE,EAAY,YAAY,EAAkB,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAyB,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAGvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAcrD,MAAM,WAAW,kBAAkB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC;IAErB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAEhC,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACjC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC;IAC/C,iBAAiB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,kBAAkB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvD,oBAAoB,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5D,qBAAqB,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxE;AAED,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CA8KhD,CAAC"}