@instructure/ui-top-nav-bar 8.30.1-snapshot-15

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 (238) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +30 -0
  3. package/es/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.js +47 -0
  4. package/es/TopNavBar/TopNavBarActionItems/index.js +215 -0
  5. package/es/TopNavBar/TopNavBarActionItems/props.js +36 -0
  6. package/es/TopNavBar/TopNavBarActionItems/styles.js +76 -0
  7. package/es/TopNavBar/TopNavBarActionItems/theme.js +46 -0
  8. package/es/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.js +57 -0
  9. package/es/TopNavBar/TopNavBarBrand/index.js +117 -0
  10. package/es/TopNavBar/TopNavBarBrand/props.js +37 -0
  11. package/es/TopNavBar/TopNavBarBrand/styles.js +91 -0
  12. package/es/TopNavBar/TopNavBarBrand/theme.js +42 -0
  13. package/es/TopNavBar/TopNavBarContext.js +37 -0
  14. package/es/TopNavBar/TopNavBarItem/TopNavBarItemLocator.js +114 -0
  15. package/es/TopNavBar/TopNavBarItem/index.js +634 -0
  16. package/es/TopNavBar/TopNavBarItem/props.js +64 -0
  17. package/es/TopNavBar/TopNavBarItem/styles.js +124 -0
  18. package/es/TopNavBar/TopNavBarItem/theme.js +54 -0
  19. package/es/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.js +86 -0
  20. package/es/TopNavBar/TopNavBarLayout/DesktopLayout/index.js +119 -0
  21. package/es/TopNavBar/TopNavBarLayout/DesktopLayout/props.js +31 -0
  22. package/es/TopNavBar/TopNavBarLayout/DesktopLayout/styles.js +115 -0
  23. package/es/TopNavBar/TopNavBarLayout/DesktopLayout/theme.js +61 -0
  24. package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.js +126 -0
  25. package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.js +454 -0
  26. package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.js +31 -0
  27. package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.js +158 -0
  28. package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.js +61 -0
  29. package/es/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.js +36 -0
  30. package/es/TopNavBar/TopNavBarLayout/index.js +118 -0
  31. package/es/TopNavBar/TopNavBarLayout/props.js +69 -0
  32. package/es/TopNavBar/TopNavBarLayout/theme.js +40 -0
  33. package/es/TopNavBar/TopNavBarLocator.js +29 -0
  34. package/es/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.js +54 -0
  35. package/es/TopNavBar/TopNavBarMenuItems/index.js +210 -0
  36. package/es/TopNavBar/TopNavBarMenuItems/props.js +35 -0
  37. package/es/TopNavBar/TopNavBarMenuItems/styles.js +65 -0
  38. package/es/TopNavBar/TopNavBarMenuItems/theme.js +45 -0
  39. package/es/TopNavBar/TopNavBarUser/TopNavBarUserLocator.js +29 -0
  40. package/es/TopNavBar/TopNavBarUser/index.js +109 -0
  41. package/es/TopNavBar/TopNavBarUser/props.js +32 -0
  42. package/es/TopNavBar/TopNavBarUser/styles.js +45 -0
  43. package/es/TopNavBar/index.js +110 -0
  44. package/es/TopNavBar/props.js +33 -0
  45. package/es/TopNavBar/utils/exampleHelpers.js +211 -0
  46. package/es/TopNavBar/utils/exampleSvgFiles.js +86 -0
  47. package/es/TopNavBar/utils/mapItemsForDrilldown.js +142 -0
  48. package/es/index.js +24 -0
  49. package/lib/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.js +59 -0
  50. package/lib/TopNavBar/TopNavBarActionItems/index.js +222 -0
  51. package/lib/TopNavBar/TopNavBarActionItems/props.js +50 -0
  52. package/lib/TopNavBar/TopNavBarActionItems/styles.js +84 -0
  53. package/lib/TopNavBar/TopNavBarActionItems/theme.js +54 -0
  54. package/lib/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.js +68 -0
  55. package/lib/TopNavBar/TopNavBarBrand/index.js +115 -0
  56. package/lib/TopNavBar/TopNavBarBrand/props.js +48 -0
  57. package/lib/TopNavBar/TopNavBarBrand/styles.js +99 -0
  58. package/lib/TopNavBar/TopNavBarBrand/theme.js +50 -0
  59. package/lib/TopNavBar/TopNavBarContext.js +46 -0
  60. package/lib/TopNavBar/TopNavBarItem/TopNavBarItemLocator.js +131 -0
  61. package/lib/TopNavBar/TopNavBarItem/index.js +650 -0
  62. package/lib/TopNavBar/TopNavBarItem/props.js +79 -0
  63. package/lib/TopNavBar/TopNavBarItem/styles.js +132 -0
  64. package/lib/TopNavBar/TopNavBarItem/theme.js +62 -0
  65. package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.js +102 -0
  66. package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/index.js +113 -0
  67. package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/props.js +40 -0
  68. package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/styles.js +123 -0
  69. package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/theme.js +69 -0
  70. package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.js +143 -0
  71. package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.js +472 -0
  72. package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.js +40 -0
  73. package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.js +166 -0
  74. package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.js +69 -0
  75. package/lib/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.js +48 -0
  76. package/lib/TopNavBar/TopNavBarLayout/index.js +113 -0
  77. package/lib/TopNavBar/TopNavBarLayout/props.js +94 -0
  78. package/lib/TopNavBar/TopNavBarLayout/theme.js +52 -0
  79. package/lib/TopNavBar/TopNavBarLocator.js +39 -0
  80. package/lib/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.js +66 -0
  81. package/lib/TopNavBar/TopNavBarMenuItems/index.js +213 -0
  82. package/lib/TopNavBar/TopNavBarMenuItems/props.js +48 -0
  83. package/lib/TopNavBar/TopNavBarMenuItems/styles.js +73 -0
  84. package/lib/TopNavBar/TopNavBarMenuItems/theme.js +53 -0
  85. package/lib/TopNavBar/TopNavBarUser/TopNavBarUserLocator.js +39 -0
  86. package/lib/TopNavBar/TopNavBarUser/index.js +104 -0
  87. package/lib/TopNavBar/TopNavBarUser/props.js +45 -0
  88. package/lib/TopNavBar/TopNavBarUser/styles.js +53 -0
  89. package/lib/TopNavBar/index.js +110 -0
  90. package/lib/TopNavBar/props.js +44 -0
  91. package/lib/TopNavBar/utils/exampleHelpers.js +255 -0
  92. package/lib/TopNavBar/utils/exampleSvgFiles.js +75 -0
  93. package/lib/TopNavBar/utils/mapItemsForDrilldown.js +165 -0
  94. package/lib/index.js +13 -0
  95. package/lib/package.json +1 -0
  96. package/package.json +64 -0
  97. package/src/TopNavBar/README.md +2329 -0
  98. package/src/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.ts +53 -0
  99. package/src/TopNavBar/TopNavBarActionItems/index.tsx +299 -0
  100. package/src/TopNavBar/TopNavBarActionItems/props.ts +152 -0
  101. package/src/TopNavBar/TopNavBarActionItems/styles.ts +92 -0
  102. package/src/TopNavBar/TopNavBarActionItems/theme.ts +51 -0
  103. package/src/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.ts +44 -0
  104. package/src/TopNavBar/TopNavBarBrand/index.tsx +139 -0
  105. package/src/TopNavBar/TopNavBarBrand/props.ts +146 -0
  106. package/src/TopNavBar/TopNavBarBrand/styles.ts +102 -0
  107. package/src/TopNavBar/TopNavBarBrand/theme.ts +48 -0
  108. package/src/TopNavBar/TopNavBarContext.ts +47 -0
  109. package/src/TopNavBar/TopNavBarItem/TopNavBarItemLocator.ts +111 -0
  110. package/src/TopNavBar/TopNavBarItem/index.tsx +752 -0
  111. package/src/TopNavBar/TopNavBarItem/props.ts +331 -0
  112. package/src/TopNavBar/TopNavBarItem/styles.ts +142 -0
  113. package/src/TopNavBar/TopNavBarItem/theme.ts +60 -0
  114. package/src/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.ts +84 -0
  115. package/src/TopNavBar/TopNavBarLayout/DesktopLayout/index.tsx +148 -0
  116. package/src/TopNavBar/TopNavBarLayout/DesktopLayout/props.ts +104 -0
  117. package/src/TopNavBar/TopNavBarLayout/DesktopLayout/styles.ts +136 -0
  118. package/src/TopNavBar/TopNavBarLayout/DesktopLayout/theme.ts +66 -0
  119. package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.ts +125 -0
  120. package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.tsx +600 -0
  121. package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.ts +187 -0
  122. package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.ts +184 -0
  123. package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.ts +69 -0
  124. package/src/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.ts +46 -0
  125. package/src/TopNavBar/TopNavBarLayout/index.tsx +149 -0
  126. package/src/TopNavBar/TopNavBarLayout/props.ts +209 -0
  127. package/src/TopNavBar/TopNavBarLayout/theme.ts +47 -0
  128. package/src/TopNavBar/TopNavBarLocator.ts +31 -0
  129. package/src/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.ts +56 -0
  130. package/src/TopNavBar/TopNavBarMenuItems/index.tsx +275 -0
  131. package/src/TopNavBar/TopNavBarMenuItems/props.ts +133 -0
  132. package/src/TopNavBar/TopNavBarMenuItems/styles.ts +72 -0
  133. package/src/TopNavBar/TopNavBarMenuItems/theme.ts +51 -0
  134. package/src/TopNavBar/TopNavBarUser/TopNavBarUserLocator.ts +32 -0
  135. package/src/TopNavBar/TopNavBarUser/index.tsx +133 -0
  136. package/src/TopNavBar/TopNavBarUser/props.ts +83 -0
  137. package/src/TopNavBar/TopNavBarUser/styles.ts +47 -0
  138. package/src/TopNavBar/index.tsx +142 -0
  139. package/src/TopNavBar/props.ts +108 -0
  140. package/src/TopNavBar/utils/exampleHelpers.tsx +342 -0
  141. package/src/TopNavBar/utils/exampleSvgFiles.tsx +76 -0
  142. package/src/TopNavBar/utils/mapItemsForDrilldown.tsx +228 -0
  143. package/src/index.ts +62 -0
  144. package/tsconfig.build.json +37 -0
  145. package/tsconfig.build.tsbuildinfo +1 -0
  146. package/tsconfig.json +4 -0
  147. package/types/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.d.ts +2116 -0
  148. package/types/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.d.ts.map +1 -0
  149. package/types/TopNavBar/TopNavBarActionItems/index.d.ts +40 -0
  150. package/types/TopNavBar/TopNavBarActionItems/index.d.ts.map +1 -0
  151. package/types/TopNavBar/TopNavBarActionItems/props.d.ts +59 -0
  152. package/types/TopNavBar/TopNavBarActionItems/props.d.ts.map +1 -0
  153. package/types/TopNavBar/TopNavBarActionItems/styles.d.ts +15 -0
  154. package/types/TopNavBar/TopNavBarActionItems/styles.d.ts.map +1 -0
  155. package/types/TopNavBar/TopNavBarActionItems/theme.d.ts +10 -0
  156. package/types/TopNavBar/TopNavBarActionItems/theme.d.ts.map +1 -0
  157. package/types/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.d.ts +592 -0
  158. package/types/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.d.ts.map +1 -0
  159. package/types/TopNavBar/TopNavBarBrand/index.d.ts +30 -0
  160. package/types/TopNavBar/TopNavBarBrand/index.d.ts.map +1 -0
  161. package/types/TopNavBar/TopNavBarBrand/props.d.ts +60 -0
  162. package/types/TopNavBar/TopNavBarBrand/props.d.ts.map +1 -0
  163. package/types/TopNavBar/TopNavBarBrand/styles.d.ts +15 -0
  164. package/types/TopNavBar/TopNavBarBrand/styles.d.ts.map +1 -0
  165. package/types/TopNavBar/TopNavBarBrand/theme.d.ts +10 -0
  166. package/types/TopNavBar/TopNavBarBrand/theme.d.ts.map +1 -0
  167. package/types/TopNavBar/TopNavBarContext.d.ts +17 -0
  168. package/types/TopNavBar/TopNavBarContext.d.ts.map +1 -0
  169. package/types/TopNavBar/TopNavBarItem/TopNavBarItemLocator.d.ts +642 -0
  170. package/types/TopNavBar/TopNavBarItem/TopNavBarItemLocator.d.ts.map +1 -0
  171. package/types/TopNavBar/TopNavBarItem/index.d.ts +64 -0
  172. package/types/TopNavBar/TopNavBarItem/index.d.ts.map +1 -0
  173. package/types/TopNavBar/TopNavBarItem/props.d.ts +188 -0
  174. package/types/TopNavBar/TopNavBarItem/props.d.ts.map +1 -0
  175. package/types/TopNavBar/TopNavBarItem/styles.d.ts +15 -0
  176. package/types/TopNavBar/TopNavBarItem/styles.d.ts.map +1 -0
  177. package/types/TopNavBar/TopNavBarItem/theme.d.ts +10 -0
  178. package/types/TopNavBar/TopNavBarItem/theme.d.ts.map +1 -0
  179. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.d.ts +5737 -0
  180. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.d.ts.map +1 -0
  181. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/index.d.ts +31 -0
  182. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/index.d.ts.map +1 -0
  183. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/props.d.ts +29 -0
  184. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/props.d.ts.map +1 -0
  185. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/styles.d.ts +15 -0
  186. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/styles.d.ts.map +1 -0
  187. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/theme.d.ts +10 -0
  188. package/types/TopNavBar/TopNavBarLayout/DesktopLayout/theme.d.ts.map +1 -0
  189. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.d.ts +4357 -0
  190. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.d.ts.map +1 -0
  191. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.d.ts +58 -0
  192. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.d.ts.map +1 -0
  193. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.d.ts +89 -0
  194. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.d.ts.map +1 -0
  195. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.d.ts +15 -0
  196. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.d.ts.map +1 -0
  197. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.d.ts +10 -0
  198. package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.d.ts.map +1 -0
  199. package/types/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.d.ts +7 -0
  200. package/types/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.d.ts.map +1 -0
  201. package/types/TopNavBar/TopNavBarLayout/index.d.ts +34 -0
  202. package/types/TopNavBar/TopNavBarLayout/index.d.ts.map +1 -0
  203. package/types/TopNavBar/TopNavBarLayout/props.d.ts +83 -0
  204. package/types/TopNavBar/TopNavBarLayout/props.d.ts.map +1 -0
  205. package/types/TopNavBar/TopNavBarLayout/theme.d.ts +10 -0
  206. package/types/TopNavBar/TopNavBarLayout/theme.d.ts.map +1 -0
  207. package/types/TopNavBar/TopNavBarLocator.d.ts +566 -0
  208. package/types/TopNavBar/TopNavBarLocator.d.ts.map +1 -0
  209. package/types/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.d.ts +1351 -0
  210. package/types/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.d.ts.map +1 -0
  211. package/types/TopNavBar/TopNavBarMenuItems/index.d.ts +38 -0
  212. package/types/TopNavBar/TopNavBarMenuItems/index.d.ts.map +1 -0
  213. package/types/TopNavBar/TopNavBarMenuItems/props.d.ts +53 -0
  214. package/types/TopNavBar/TopNavBarMenuItems/props.d.ts.map +1 -0
  215. package/types/TopNavBar/TopNavBarMenuItems/styles.d.ts +15 -0
  216. package/types/TopNavBar/TopNavBarMenuItems/styles.d.ts.map +1 -0
  217. package/types/TopNavBar/TopNavBarMenuItems/theme.d.ts +10 -0
  218. package/types/TopNavBar/TopNavBarMenuItems/theme.d.ts.map +1 -0
  219. package/types/TopNavBar/TopNavBarUser/TopNavBarUserLocator.d.ts +566 -0
  220. package/types/TopNavBar/TopNavBarUser/TopNavBarUserLocator.d.ts.map +1 -0
  221. package/types/TopNavBar/TopNavBarUser/index.d.ts +31 -0
  222. package/types/TopNavBar/TopNavBarUser/index.d.ts.map +1 -0
  223. package/types/TopNavBar/TopNavBarUser/props.d.ts +29 -0
  224. package/types/TopNavBar/TopNavBarUser/props.d.ts.map +1 -0
  225. package/types/TopNavBar/TopNavBarUser/styles.d.ts +14 -0
  226. package/types/TopNavBar/TopNavBarUser/styles.d.ts.map +1 -0
  227. package/types/TopNavBar/index.d.ts +38 -0
  228. package/types/TopNavBar/index.d.ts.map +1 -0
  229. package/types/TopNavBar/props.d.ts +43 -0
  230. package/types/TopNavBar/props.d.ts.map +1 -0
  231. package/types/TopNavBar/utils/exampleHelpers.d.ts +70 -0
  232. package/types/TopNavBar/utils/exampleHelpers.d.ts.map +1 -0
  233. package/types/TopNavBar/utils/exampleSvgFiles.d.ts +7 -0
  234. package/types/TopNavBar/utils/exampleSvgFiles.d.ts.map +1 -0
  235. package/types/TopNavBar/utils/mapItemsForDrilldown.d.ts +19 -0
  236. package/types/TopNavBar/utils/mapItemsForDrilldown.d.ts.map +1 -0
  237. package/types/index.d.ts +11 -0
  238. package/types/index.d.ts.map +1 -0
@@ -0,0 +1,2329 @@
1
+ ---
2
+ describes: TopNavBar
3
+ ---
4
+
5
+ The `TopNavBar` component is a navigation bar component that helps to consistently position the site navigation items and actions throughout all pages and applications. It’s used for branding, navigation, user login and actions.
6
+
7
+ TopNavBar adapts to small screen widths by truncating nav items and displaying a more specialised view.
8
+
9
+ ### Playground
10
+
11
+ Click on the button below to open up an interactive, fullscreen example, where you can toggle the elements of TopNavBar on and off. You can test the "desktop" and "smallViewport" views, several layout versions, states, menu item variants, and many more.
12
+
13
+ ```js
14
+ ---
15
+ example: true
16
+ render: false
17
+ ---
18
+ class PlaygroundExample extends React.Component {
19
+ state = {
20
+ rtlMode: false,
21
+ isSecondaryNavigation: false,
22
+ hasBrandSection: true,
23
+ hasMenuItemsSection: true,
24
+ hasActionItemsSection: true,
25
+ hasUserSection: true,
26
+ hideActionsUserSeparator: true,
27
+ useAlternativeTitle: false,
28
+ renderName: true,
29
+ renderIcon: true,
30
+ nameBackground: false,
31
+ iconBackground: true,
32
+ extraMenuItems: false,
33
+ extraActionItems: false,
34
+ actionItemShowChevronForSubmenu: false,
35
+ actionItemVariant: 'icon',
36
+ userShowChevronForSubmenu: true,
37
+ userVariant: 'avatar',
38
+ disableMenuItem: false,
39
+ disableMenuItemWithSubmenu: false,
40
+ disableSubmenuItem: false,
41
+ disableAction: false,
42
+ disableUser: false,
43
+ isModalOpen: false,
44
+ exampleViewport: 'desktop',
45
+ isSearchOpen: false,
46
+ currentPageId: 'overview',
47
+ activeIds: ['overview'],
48
+ breadcrumbs: ['Overview'],
49
+ searchInputValue: '',
50
+ }
51
+
52
+ canvasNavbarHeight = '3.5rem'
53
+ activeOptionStyle = {
54
+ display: 'inline-block',
55
+ fontWeight: 'bold',
56
+ paddingBottom: '0.125rem',
57
+ borderBottom: '0.125rem solid currentColor'
58
+ }
59
+
60
+ fillerText = lorem.paragraphs(4)
61
+
62
+ navItems = [
63
+ {
64
+ id: 'overview',
65
+ label: 'Overview',
66
+ href: '#Overview'
67
+ },
68
+ {
69
+ id: 'admin',
70
+ label: 'Admin',
71
+ submenu: [
72
+ {
73
+ id: 'manage',
74
+ label: 'Manage',
75
+ submenu: { /* submenu */ }
76
+ },
77
+ {
78
+ id: 'reporting',
79
+ label: 'Reporting',
80
+ submenu: { /* submenu */ }
81
+ },
82
+ {
83
+ id: 'assessment',
84
+ label: 'Assessment',
85
+ submenu: { /* submenu */ }
86
+ },
87
+ {
88
+ id: 'itemBank',
89
+ label: 'Item Bank',
90
+ href: '/#TopNavBar'
91
+ },
92
+ {
93
+ id: 'progressReports',
94
+ label: 'Progress Reports',
95
+ href: '/#TopNavBar'
96
+ }
97
+ ],
98
+ },
99
+ {
100
+ id: 'contact',
101
+ label: 'Contact',
102
+ customPopoverConfig: {
103
+ on: 'click',
104
+ shouldContainFocus: true,
105
+ children: (
106
+ <View
107
+ as="div"
108
+ padding="medium"
109
+ width="25rem"
110
+ role="dialog"
111
+ tabIndex={0}
112
+ aria-label="Contact information"
113
+ position="relative"
114
+ borderRadius="small"
115
+ >
116
+ <Heading level="h3">Contact information</Heading>
117
+ <p>{lorem.sentence()}</p>
118
+ <Button color="primary" margin="x-small 0 small">Help Center</Button>
119
+ <hr aria-hidden="true" />
120
+ <View as="div" margin="medium 0 0">
121
+ <Text weight="bold">
122
+ <div>Contact person</div>
123
+ <Link href="/#TopNavBar" isWithinText={false}>
124
+ contact.person@example.com
125
+ </Link>
126
+ <div>(801) 123-4567</div>
127
+ </Text>
128
+ </View>
129
+ </View>
130
+ )
131
+ }
132
+ },
133
+ {
134
+ id: 'data',
135
+ label: 'Data',
136
+ onClick: () => console.log('"Data" menu item clicked')
137
+ },
138
+ ]
139
+
140
+ toggleSearch(isOpen) {
141
+ this.setState({ isSearchOpen: isOpen })
142
+ }
143
+
144
+ generateSubmenu(navItem) {
145
+ const { id: rootItemId, submenu } = navItem
146
+
147
+ return (
148
+ <Drilldown rootPageId={`root_${rootItemId}`}>
149
+ {[
150
+ <Drilldown.Page id={`root_${rootItemId}`} key={`root_${rootItemId}`}>
151
+ {[
152
+ ...submenu.map(submenuItem => {
153
+ const isActive = this.state.activeIds.includes(submenuItem.id)
154
+ const isCurrentPage = this.state.activeIds[this.state.activeIds.length - 1] === submenuItem.id
155
+ let onOptionClick = submenuItem.onClick
156
+
157
+ if (submenuItem.href && !submenuItem.submenu) {
158
+ onOptionClick = (() => {
159
+ this.setState({
160
+ currentPageId: rootItemId,
161
+ activeIds: [rootItemId, submenuItem.id],
162
+ breadcrumbs: [
163
+ this.navItems.find(item => item.id === rootItemId).label,
164
+ submenuItem.label
165
+ ]
166
+ })
167
+ })
168
+ }
169
+
170
+ return (
171
+ <Drilldown.Option
172
+ key={`${submenuItem.id}_option`}
173
+ id={`${submenuItem.id}_option`}
174
+ aria-current={isCurrentPage ? "page" : undefined}
175
+ subPageId={submenuItem.submenu ? `${submenuItem.id}_page` : undefined}
176
+ href={!submenuItem.submenu ? submenuItem.href : undefined}
177
+ onOptionClick={onOptionClick}
178
+ afterLabelContentVAlign="center"
179
+ renderBeforeLabel={submenuItem.renderIcon}
180
+ {...this.state.disableSubmenuItem
181
+ && submenuItem.label === 'Item Bank'
182
+ && { disabled: true }
183
+ }
184
+ >
185
+ {isActive ? (
186
+ <span style={this.activeOptionStyle}>
187
+ {submenuItem.label}
188
+ </span>
189
+ ) : submenuItem.label}
190
+ </Drilldown.Option>
191
+ )
192
+ })
193
+ ]}
194
+ </Drilldown.Page>,
195
+
196
+ ...submenu.filter(item => item.submenu).map(
197
+ (submenuItem) => (
198
+ <Drilldown.Page id={`${submenuItem.id}_page`} key={`${submenuItem.id}_page`}>
199
+ {Array.from(Array(5)).map((_item, idx) => {
200
+ const id = `${submenuItem.id}_subItem-${idx}`
201
+ const label = `${submenuItem.label} Lvl 2 Item`
202
+ const isActive = this.state.activeIds.includes(id)
203
+ const isCurrentPage = this.state.activeIds[this.state.activeIds.length - 1] === id
204
+ return (
205
+ <Drilldown.Option
206
+ id={id}
207
+ key={id}
208
+ href="/#TopNavBar"
209
+ aria-current={isCurrentPage ? "page" : undefined}
210
+ onOptionClick={() => {
211
+ this.setState({
212
+ currentPageId: rootItemId,
213
+ activeIds: [rootItemId, submenuItem.id, id],
214
+ breadcrumbs: [
215
+ this.navItems.find(item => item.id === rootItemId).label,
216
+ submenuItem.label,
217
+ label
218
+ ]
219
+ })
220
+ }}
221
+ afterLabelContentVAlign="center"
222
+ >
223
+ {isActive ? (
224
+ <span style={this.activeOptionStyle}>
225
+ {label}
226
+ </span>
227
+ ) : label}
228
+ </Drilldown.Option>
229
+ )
230
+ })}
231
+ </Drilldown.Page>
232
+ )
233
+ )
234
+ ]}
235
+ </Drilldown>
236
+ )
237
+ }
238
+
239
+ renderSearch(currentLayout, closeInPlaceDialog) {
240
+ return (
241
+ <View as="div" padding="x-small">
242
+ <TextInput
243
+ id="searchInput"
244
+ width="100%"
245
+ display="block"
246
+ renderLabel={<ScreenReaderContent>Search</ScreenReaderContent>}
247
+ renderBeforeInput={() => <IconSearchLine inline={false} />}
248
+ placeholder="Search..."
249
+ onChange={(_event, value) => {
250
+ this.setState({ searchInputValue: value })
251
+ }}
252
+ value={this.state.searchInputValue}
253
+ onKeyDown={(event) => {
254
+ if (event.key === 'Enter') {
255
+ event.preventDefault()
256
+ event.stopPropagation()
257
+
258
+ console.log(`Search input submitted value "${this.state.searchInputValue}".`)
259
+
260
+ this.setState({ searchInputValue: '' })
261
+
262
+ if (currentLayout === 'smallViewport' && typeof closeInPlaceDialog === 'function') {
263
+ closeInPlaceDialog()
264
+ } else {
265
+ this.toggleSearch(false)
266
+ }
267
+ }
268
+ }}
269
+ themeOverride={
270
+ this.state.isSecondaryNavigation
271
+ ? undefined
272
+ : (_theme, globalTheme) => ({
273
+ focusOutlineColor: globalTheme.colors.borderLightest
274
+ })
275
+ }
276
+ />
277
+ </View>
278
+ )
279
+ }
280
+
281
+ renderExampleSettings() {
282
+ const settings = {
283
+ viewport: {
284
+ label: 'Example settings',
285
+ radios: {
286
+ exampleViewport: ['desktop', 'smallViewport']
287
+ },
288
+ checkboxes: ['rtlMode']
289
+ },
290
+ inverseColor: {
291
+ label: 'Inverse color mode',
292
+ checkboxes: [
293
+ 'isSecondaryNavigation',
294
+ ]
295
+ },
296
+ global: {
297
+ label: 'Global settings',
298
+ checkboxes: [
299
+ 'hasBrandSection',
300
+ 'hasMenuItemsSection',
301
+ 'hasActionItemsSection',
302
+ 'hasUserSection',
303
+ ]
304
+ },
305
+ desktopLayout: {
306
+ label: 'Desktop layout settings',
307
+ checkboxes: [
308
+ 'hideActionsUserSeparator'
309
+ ]
310
+ },
311
+ smallViewportLayout: {
312
+ label: 'Small viewport layout settings',
313
+ checkboxes: [
314
+ 'useAlternativeTitle'
315
+ ]
316
+ },
317
+ brand: {
318
+ label: 'TopNavBar.Brand settings',
319
+ checkboxes: [
320
+ 'renderName',
321
+ 'renderIcon',
322
+ 'nameBackground',
323
+ 'iconBackground',
324
+ ]
325
+ },
326
+ menuItems: {
327
+ label: 'TopNavBar.MenuItems settings',
328
+ checkboxes: [
329
+ 'extraMenuItems',
330
+ ]
331
+ },
332
+ actionItems: {
333
+ label: 'TopNavBar.ActionItems settings',
334
+ checkboxes: [
335
+ 'extraActionItems',
336
+ 'actionItemShowChevronForSubmenu',
337
+ ],
338
+ radios: {
339
+ actionItemVariant: [
340
+ 'icon', 'default', 'default with icon', 'button', 'button with icon'
341
+ ]
342
+ }
343
+ },
344
+ user: {
345
+ label: 'TopNavBar.User settings',
346
+ checkboxes: [
347
+ 'userShowChevronForSubmenu',
348
+ ],
349
+ radios: {
350
+ userVariant: ['avatar', 'avatar with user name', 'user name', 'login text', 'login button']
351
+ }
352
+ },
353
+ disabledSection: {
354
+ label: 'Disabled state',
355
+ checkboxes: [
356
+ 'disableMenuItem',
357
+ 'disableMenuItemWithSubmenu',
358
+ 'disableSubmenuItem',
359
+ 'disableAction',
360
+ 'disableUser',
361
+ ],
362
+ },
363
+ }
364
+
365
+ const settingLabels = {
366
+ exampleViewport: 'Toggle example viewport',
367
+ rtlMode: 'RTL mode',
368
+ isSecondaryNavigation: 'Display as secondary navigation',
369
+ hasBrandSection: '"renderBrand" prop',
370
+ hasMenuItemsSection: '"renderMenuItems" prop',
371
+ hasActionItemsSection: '"renderActionItems" prop',
372
+ hasUserSection: '"renderUser" prop',
373
+ useAlternativeTitle: '"alternativeTitle" prop',
374
+ extraMenuItems: 'Display extra menu items',
375
+ extraActionItems: 'Display extra action items',
376
+ actionItemShowChevronForSubmenu: '"showSubmenuChevron" prop',
377
+ userShowChevronForSubmenu: '"showSubmenuChevron" prop',
378
+ actionItemVariant: 'Display action items as variant:',
379
+ userVariant: 'Display user menu as:',
380
+ disableMenuItem: 'menu item',
381
+ disableMenuItemWithSubmenu: 'menu item with submenu',
382
+ disableSubmenuItem: 'submenu item',
383
+ disableAction: 'action',
384
+ disableUser: 'user',
385
+ }
386
+
387
+ const settingDescriptions = {
388
+ isSecondaryNavigation: 'When the navbar is used as a secondary navigation (e.g.: under Canvas main navbar), using the inverse color mode is recommended',
389
+ hasBrandSection: 'Displays brand section',
390
+ hasMenuItemsSection: 'Displays main navbar items',
391
+ hasActionItemsSection: 'Displays action items',
392
+ hasUserSection: 'Displays user menu',
393
+ hideActionsUserSeparator: 'Hides the separator between the action items and the user menu',
394
+ useAlternativeTitle: 'Displays other data (e.g.: page title) instead of the Brand logo and link',
395
+ renderName: 'The app/product/brand/company/etc. name',
396
+ renderIcon: 'Visible only in "desktop" mode',
397
+ nameBackground: 'Visible only in "desktop" mode',
398
+ iconBackground: 'Visible only in "desktop" mode',
399
+ extraMenuItems: 'In "desktop" mode, when there is not enough room to list all the menu items, they will be accessible via a dropdown menu at the end of the list',
400
+ actionItemShowChevronForSubmenu: 'Displays the open/close chevron next to the item, when it has a submenu or custom popover',
401
+ userShowChevronForSubmenu: 'Displays the open/close chevron next to the item, when it has a submenu or custom popover (only visible in "desktop" mode)',
402
+ extraActionItems: 'In "smallViewport" mode, when there is not enough room to list all the action items, they will be accessible via a dropdown menu at the end of the list',
403
+ actionItemVariant: 'In "smallViewport" mode all items are displayed as `variant="icon"` due to the lack of space',
404
+ userVariant: 'In "smallViewport" mode it will always display as text (with or without avatar)',
405
+ disableMenuItem: 'e.g.: "Settings" menu item',
406
+ disableMenuItemWithSubmenu: 'e.g.: "Admin" menu item',
407
+ disableSubmenuItem: 'e.g.: "Item Bank" menu item under "Admin"',
408
+ disableAction: 'e.g.: "Info" action',
409
+ }
410
+
411
+ return (
412
+ <View as="div" margin="medium 0 large">
413
+ <FormFieldGroup
414
+ description={(
415
+ <Heading as="p" level="h3" margin="0 0 large">
416
+ Example Settings
417
+ </Heading>
418
+ )}
419
+ colSpacing="large"
420
+ rowSpacing="large"
421
+ layout="stacked"
422
+ vAlign="top"
423
+ >
424
+ {Object.values(settings).map(({ label, checkboxes = [], radios = {} }) => {
425
+ const name = label.replace(' ', '')
426
+
427
+ const checkboxSettings = checkboxes.length ? (
428
+ <CheckboxGroup
429
+ description={label}
430
+ name={name}
431
+ key={name}
432
+ layout="stacked"
433
+ defaultValue={checkboxes.filter(setting => this.state[setting])}
434
+ >
435
+ {checkboxes.map((setting) => (
436
+ <Checkbox
437
+ key={`${setting}Setting`}
438
+ variant="toggle"
439
+ value={setting}
440
+ label={settingLabels[setting] || `"${setting}" prop`}
441
+ checked={this.state[setting]}
442
+ messages={settingDescriptions[setting]
443
+ ? [{ text: settingDescriptions[setting], type: 'hint' }]
444
+ : undefined
445
+ }
446
+ onChange={() => {
447
+ this.setState({ [setting]: !this.state[setting] })
448
+ }}
449
+ />
450
+ ))}
451
+ </CheckboxGroup>
452
+ ) : null
453
+
454
+ const radioSettings = Object.entries(radios).map(([name, values]) => {
455
+ return (
456
+ <RadioInputGroup
457
+ onChange={(_event, value) => {
458
+ this.setState({ [name]: value })
459
+ }}
460
+ value={this.state[name]}
461
+ name={`${name}Setting`}
462
+ description={settingLabels[name] || name}
463
+ messages={settingDescriptions[name]
464
+ ? [{ text: settingDescriptions[name], type: 'hint' }]
465
+ : undefined
466
+ }
467
+ >
468
+ {values.map(value =>
469
+ <RadioInput key={value} value={value} label={value} />
470
+ )}
471
+ </RadioInputGroup>
472
+ )
473
+ })
474
+
475
+ return [checkboxSettings, radioSettings]
476
+ })}
477
+ </FormFieldGroup>
478
+ </View>
479
+ )
480
+ }
481
+
482
+ renderPageContent() {
483
+ return (
484
+ <View overflowY='auto' as="div">
485
+ <View as="div" maxWidth="75rem" margin="0 auto">
486
+
487
+ <View as="div" margin="large medium small">
488
+ <Button
489
+ onClick={() => { this.setState({ isModalOpen: false }) }}
490
+ renderIcon={IconXSolid}
491
+ >
492
+ Close TopNavBar Fullscreen Example
493
+ </Button>
494
+ </View>
495
+
496
+ <View as="div" margin="large medium 0">
497
+ <Heading as="p" level="h2" margin="0 0 x-small">
498
+ {this.state.breadcrumbs[this.state.breadcrumbs.length - 1]}
499
+ </Heading>
500
+
501
+ {this.state.breadcrumbs.length > 1 && (
502
+ <Breadcrumb label="You are here:">
503
+ {this.state.breadcrumbs.map(breadcrumb => (
504
+ <Breadcrumb.Link key={breadcrumb}>
505
+ {breadcrumb}
506
+ </Breadcrumb.Link>
507
+
508
+ ))}
509
+ </Breadcrumb>
510
+ )}
511
+ </View>
512
+
513
+ <Responsive
514
+ query={{
515
+ small: { maxWidth: 719 },
516
+ large: { minWidth: 720 }
517
+ }}
518
+ props={{
519
+ small: {
520
+ flexDirection: 'column',
521
+ textWidth: "100%",
522
+ settingsWidth: "100%"
523
+ },
524
+ large: {
525
+ flexDirection: 'row-reverse',
526
+ textWidth: "60%",
527
+ settingsWidth: "40%"
528
+ }
529
+ }}
530
+ render={(props, matches) => {
531
+ return (
532
+ <Flex
533
+ alignItems="start"
534
+ wrap="wrap"
535
+ direction={props.flexDirection}
536
+ >
537
+ <Flex.Item
538
+ width={props.settingsWidth}
539
+ padding="small medium medium"
540
+ >
541
+ {this.renderExampleSettings()}
542
+ </Flex.Item>
543
+ <Flex.Item
544
+ width={props.textWidth}
545
+ padding="small medium medium"
546
+ >
547
+ {Array.from(Array(5)).map((_i, idx) => (
548
+ <View as="div" margin="medium 0" key={idx}>
549
+ {this.fillerText}
550
+ </View>
551
+ ))}
552
+ </Flex.Item>
553
+ </Flex>
554
+ )
555
+ }}
556
+ />
557
+ </View>
558
+ </View>
559
+ )
560
+ }
561
+
562
+ renderNavBar() {
563
+ const navItems = [
564
+ ...this.navItems,
565
+ ...(this.state.extraMenuItems
566
+ ? Array.from(Array(20)).map((i, idx) => (
567
+ {
568
+ id: `item${idx}`,
569
+ label: `Item ${idx + 1}`,
570
+ href: `/#Item${idx}`
571
+ }
572
+ ))
573
+ : []
574
+ )
575
+ ]
576
+
577
+ const actionItemSettings = {
578
+ variant: this.state.actionItemVariant.replace(' with icon', ''),
579
+ showSubmenuChevron: this.state.actionItemShowChevronForSubmenu,
580
+ }
581
+
582
+ return (
583
+ <TopNavBar
584
+ inverseColor={this.state.isSecondaryNavigation}
585
+ mediaQueryMatch="element"
586
+ >
587
+ {({ currentLayout, inverseColor }) => {
588
+
589
+ if (currentLayout === 'desktop' && !this.state.actionItemVariant.includes('icon')) {
590
+ actionItemSettings.renderIcon = undefined
591
+ }
592
+
593
+ return (
594
+ <TopNavBar.Layout
595
+ navLabel={this.state.isSecondaryNavigation
596
+ ? 'Secondary navigation bar'
597
+ : 'Main navigation bar'}
598
+ desktopConfig={{
599
+ hideActionsUserSeparator: this.state.hideActionsUserSeparator
600
+ }}
601
+ smallViewportConfig={{
602
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
603
+ dropdownMenuLabel: 'Main Menu',
604
+ alternativeTitle: this.state.useAlternativeTitle || inverseColor
605
+ ? this.state.breadcrumbs[this.state.breadcrumbs.length - 1]
606
+ : undefined,
607
+ renderInPlaceDialogConfig: {
608
+ open: this.state.isSearchOpen,
609
+ onClose: () => {
610
+ this.toggleSearch(false)
611
+ },
612
+ closeButtonLabel: 'Close Search and return to Navigation',
613
+ returnFocusElement: () =>
614
+ document.getElementById('Search'),
615
+ shouldCloseOnEscape: true,
616
+ shouldCloseOnDocumentClick: false,
617
+ shouldContainFocus: false,
618
+ content: ({ closeInPlaceDialog }) => this.renderSearch(currentLayout, closeInPlaceDialog)
619
+ }
620
+ }}
621
+ renderBrand={this.state.hasBrandSection ? (
622
+ <TopNavBar.Brand
623
+ screenReaderLabel="Elevate Data Sync"
624
+ href="/#TopNavBar"
625
+ {...{
626
+ ...(this.state.renderName && {
627
+ renderName: inverseColor
628
+ ? elevateLogoInverse
629
+ : elevateLogo
630
+ }),
631
+ ...(this.state.renderIcon && {
632
+ renderIcon: inverseColor
633
+ ? undefined
634
+ : elevateIcon
635
+ }),
636
+ ...(this.state.iconBackground && {
637
+ iconBackground: '#0097D3'
638
+ }),
639
+ ...(this.state.nameBackground && {
640
+ nameBackground: inverseColor
641
+ ? '#F5F5F5'
642
+ : '#2D3B45'
643
+ }),
644
+ }}
645
+ />
646
+ ) : undefined }
647
+ renderMenuItems={this.state.hasMenuItemsSection ? (
648
+ <TopNavBar.MenuItems
649
+ listLabel="Page navigation"
650
+ currentPageId={this.state.currentPageId}
651
+ renderHiddenItemsMenuTriggerLabel={(
652
+ hiddenChildrenCount
653
+ ) => `${hiddenChildrenCount} More`}
654
+ >
655
+ {navItems.map(item => (
656
+ <TopNavBar.Item
657
+ key={item.id}
658
+ id={item.id}
659
+
660
+ {...this.state.disableMenuItem && item.label === 'Settings' && {
661
+ status: 'disabled'
662
+ }}
663
+ {...this.state.disableMenuItemWithSubmenu && item.label === 'Admin' && {
664
+ status: 'disabled'
665
+ }}
666
+
667
+ {...item.submenu && {
668
+ renderSubmenu: this.generateSubmenu(item),
669
+ 'aria-label': `Open for ${item.label} menu`
670
+ }}
671
+
672
+ {...item.customPopoverConfig && {
673
+ customPopoverConfig: item.customPopoverConfig,
674
+ 'aria-label': `Open for ${item.label} menu`
675
+ }}
676
+
677
+ {...!item.submenu && !item.customPopoverConfig ? {
678
+ // Example logic:
679
+ href: '/#TopNavBar',
680
+ onClick: () => {
681
+ if (typeof item.onClick === 'function') {
682
+ item.onClick()
683
+ }
684
+
685
+ this.setState({
686
+ currentPageId: item.id,
687
+ activeIds: [item.id],
688
+ breadcrumbs: [item.label],
689
+ })
690
+ }
691
+ } : {
692
+ href: undefined,
693
+ onClick: undefined
694
+ }}
695
+ >
696
+ {item.label}
697
+ </TopNavBar.Item>
698
+ ))}
699
+ </TopNavBar.MenuItems>
700
+ ) : undefined }
701
+ renderActionItems={this.state.hasActionItemsSection ? (
702
+ <TopNavBar.ActionItems
703
+ listLabel="Actions"
704
+ renderHiddenItemsMenuTriggerLabel={(
705
+ hiddenChildrenCount
706
+ ) => `${hiddenChildrenCount} more actions`}
707
+ renderHiddenItemsMenuTriggerTooltip={(
708
+ hiddenChildrenCount
709
+ ) => `${hiddenChildrenCount} more actions`}
710
+ >
711
+ <TopNavBar.Item
712
+ id="Search1"
713
+ renderIcon={<IconSearchLine />}
714
+ aria-label="Open to search in the page"
715
+ {...actionItemSettings}
716
+ {...(currentLayout === 'desktop'
717
+ ? {
718
+ customPopoverConfig: {
719
+ children: this.renderSearch(currentLayout),
720
+ color: 'primary-inverse',
721
+ isShowingContent: this.state.isSearchOpen,
722
+ onShowContent: () => { this.toggleSearch(true) },
723
+ onHideContent: () => { this.toggleSearch(false) },
724
+ on: 'click',
725
+ shouldCloseOnDocumentClick: true,
726
+ placement: 'bottom end'
727
+ }
728
+ }
729
+ : {
730
+ onClick: () => {
731
+ this.toggleSearch(true)
732
+ }
733
+ })}
734
+ >
735
+ Search
736
+ </TopNavBar.Item>
737
+
738
+ <TopNavBar.Item
739
+ id="Info"
740
+ renderIcon={<IconQuestionLine />}
741
+ aria-label="Open for info menu"
742
+ renderSubmenu={this.generateSubmenu({
743
+ id: 'Info',
744
+ submenu: ['Contact', 'Map', 'Career'].map(item => ({
745
+ id: item.toLowerCase(),
746
+ label: item,
747
+ onClick: () => {
748
+ console.log(`"${item}" action clicked`)
749
+ }
750
+ }))
751
+ })}
752
+ {...actionItemSettings}
753
+ {...this.state.disableAction && {
754
+ status: 'disabled'
755
+ }}
756
+ >
757
+ Info
758
+ </TopNavBar.Item>
759
+
760
+ {this.state.extraActionItems &&
761
+ [
762
+ { name: 'Alerts', icon: <IconAlertsLine /> },
763
+ { name: 'Calendar', icon: <IconCalendarMonthLine /> },
764
+ { name: 'Discussion', icon: <IconDiscussionLine /> },
765
+ ].map(({ name, icon }) => {
766
+ return (
767
+ <TopNavBar.Item
768
+ id={name.toLowerCase()}
769
+ key={name}
770
+ onClick={() => {
771
+ console.log(`"${name}" action clicked`)
772
+ }}
773
+ renderIcon={icon}
774
+ {...actionItemSettings}
775
+ >
776
+ {name}
777
+ </TopNavBar.Item>
778
+ )
779
+ })}
780
+ </TopNavBar.ActionItems>
781
+ ) : undefined }
782
+ renderUser={this.state.hasUserSection ? (
783
+ <TopNavBar.User>
784
+ <TopNavBar.Item
785
+ id="User"
786
+ tooltip="User settings"
787
+ aria-label="User settings"
788
+ variant={this.state.userVariant === 'avatar'
789
+ ? 'avatar'
790
+ : this.state.userVariant.includes('button')
791
+ ? 'button'
792
+ : 'default'
793
+ }
794
+ renderAvatar={this.state.userVariant.includes('avatar')
795
+ ? {
796
+ avatarName: 'User Name',
797
+ avatarSrc: 'https://images.pexels.com/photos/220453/pexels-photo-220453.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1'
798
+ }
799
+ : undefined
800
+ }
801
+ renderSubmenu={this.state.userVariant.includes('login')
802
+ ? undefined
803
+ : this.generateSubmenu({
804
+ id: 'Info',
805
+ submenu: [
806
+ { label: 'Profile', icon: IconUserLine },
807
+ { label: 'Personal settings', icon: IconSettingsLine },
808
+ { label: 'Log out', icon: IconXLine },
809
+ ].map(item => ({
810
+ id: item.label.replace(' ', '').toLowerCase(),
811
+ label: item.label,
812
+ renderIcon: item.icon,
813
+ onClick: () => {
814
+ console.log(`"${item.label}" action clicked`)
815
+ }
816
+ }))
817
+ })
818
+ }
819
+ href={this.state.userVariant.includes('login')
820
+ ? '/#TopNavBar'
821
+ : undefined
822
+ }
823
+ showSubmenuChevron={this.state.userShowChevronForSubmenu}
824
+ {...this.state.disableUser && {
825
+ status: 'disabled'
826
+ }}
827
+ >
828
+ {this.state.userVariant.includes('login')
829
+ ? 'Log in/Register'
830
+ : 'User Name'
831
+ }
832
+ </TopNavBar.Item>
833
+ </TopNavBar.User>
834
+ ) : undefined }
835
+ themeOverride={{
836
+ // For example demo
837
+ smallViewportZIndex: 9999,
838
+ smallViewportTrayFixTopPosition: this.state.isSecondaryNavigation
839
+ ? `calc(${this.canvasNavbarHeight} + 1px + 3.5rem)`
840
+ : '3.5rem'
841
+ }}
842
+ />
843
+ )
844
+ }}
845
+ </TopNavBar>
846
+ )
847
+ }
848
+
849
+ renderModalContent() {
850
+ return (
851
+ <div
852
+ key={this.state.exampleViewport}
853
+ style={{
854
+ height: '100%',
855
+ overflow: 'hidden',
856
+ minHeight: 0,
857
+ display: 'flex',
858
+ flexDirection: 'column'
859
+ }}
860
+ >
861
+ {this.state.isSecondaryNavigation && (
862
+ <div
863
+ style={{
864
+ background: '#394B58',
865
+ color: 'white',
866
+ position: 'relative',
867
+ padding: '16px',
868
+ flex: `0 0 ${this.canvasNavbarHeight}`,
869
+ boxSizing: 'border-box',
870
+ zIndex: 10000
871
+ }}
872
+ >
873
+ Primary Navbar
874
+ </div>
875
+ )}
876
+
877
+
878
+ <InstUISettingsProvider dir={this.state.rtlMode ? 'rtl' : 'ltr'}>
879
+ {this.renderNavBar()}
880
+ </InstUISettingsProvider>
881
+
882
+ {this.renderPageContent()}
883
+ </div>
884
+ )
885
+ }
886
+
887
+ render() {
888
+ return (
889
+ <div>
890
+ <Button
891
+ color="primary"
892
+ onClick={() => { this.setState({ isModalOpen: true }) }}
893
+ >
894
+ Open TopNavBar Fullscreen Example
895
+ </Button>
896
+
897
+ <Modal
898
+ open={this.state.isModalOpen}
899
+ onDismiss={() => { this.setState({ isModalOpen: false }) }}
900
+ size={this.state.exampleViewport === 'desktop'
901
+ ? 'fullscreen'
902
+ : 'small'
903
+ }
904
+ label="TopNavBar Fullscreen Example"
905
+ shouldCloseOnDocumentClick={false}
906
+ overflow="fit"
907
+ >
908
+ <Modal.Body padding="none">
909
+ {this.renderModalContent()}
910
+ </Modal.Body>
911
+ </Modal>
912
+ </div>
913
+ )
914
+ }
915
+ }
916
+
917
+ const elevateLogo = (
918
+ <svg
919
+ width="90"
920
+ height="36"
921
+ viewBox="0 0 90 36"
922
+ fill="none"
923
+ xmlns="http://www.w3.org/2000/svg"
924
+ >
925
+ <g>
926
+ <path
927
+ d="M0.0861816 10.546V0.0927734H7.63835V2.44336H2.74183V4.0713H7.5314V6.42454H2.74183V8.20601H7.63835V10.5566L0.0861816 10.546Z"
928
+ fill="white"
929
+ />
930
+ <path
931
+ d="M10.3696 10.546V0.0927734H13.0279V8.20601H17.1679V10.5566L10.3696 10.546Z"
932
+ fill="white"
933
+ />
934
+ <path
935
+ d="M19.761 10.546V0.0927734H27.3132V2.44336H22.4166V4.0713H27.2036V6.42454H22.4166V8.20601H27.3132V10.5566L19.761 10.546Z"
936
+ fill="white"
937
+ />
938
+ <path
939
+ d="M32.8697 10.546L28.9932 0.0927734H32.0062L34.5549 7.62895L37.0879 0.0927734H40.0984L36.2219 10.546H32.8697Z"
940
+ fill="white"
941
+ />
942
+ <path
943
+ d="M48.407 10.546L47.8853 9.03983H43.8262L43.3175 10.546H40.3123L44.1888 0.0927734H47.541L51.4175 10.546H48.407ZM45.874 2.75571L44.5697 6.68925H47.1783L45.874 2.75571Z"
944
+ fill="white"
945
+ />
946
+ <path
947
+ d="M54.7514 10.546V2.44336H51.8635V0.0927734H60.2818V2.44336H57.4122V10.546H54.7514Z"
948
+ fill="white"
949
+ />
950
+ <path
951
+ d="M62.781 10.546V0.0927734H70.3462V2.44336H65.4393V4.0713H70.2262V6.42454H65.4393V8.20601H70.3358V10.5566L62.781 10.546Z"
952
+ fill="white"
953
+ />
954
+ <path
955
+ d="M0.404541 31.897V18.0767H5.77584C10.0437 18.0767 13.0045 20.8322 13.0045 24.9749C13.0045 29.1599 10.0437 31.897 5.79671 31.897H0.404541ZM10.0437 24.9749C10.0437 22.5502 8.57498 20.6655 5.79671 20.6655H3.30541V29.3055H5.77584C8.47063 29.3055 10.0437 27.3387 10.0437 24.9749Z"
956
+ fill="white"
957
+ />
958
+ <path
959
+ d="M20.7236 31.8971V30.8383C20.0479 31.6668 18.8845 32.1433 17.5932 32.1433C16.0279 32.1433 14.1836 31.0659 14.1836 28.8265C14.1836 26.4653 16.0097 25.5944 17.5932 25.5944C18.921 25.5944 20.0636 26.0286 20.7236 26.8174V25.5547C20.7236 24.5409 19.8653 23.8765 18.5584 23.8765C17.4979 23.8877 16.4821 24.3112 15.7201 25.0597L14.7001 23.2068C15.8913 22.1525 17.4268 21.5863 19.0071 21.6186C21.274 21.6186 23.3375 22.5291 23.3375 25.4091V31.8971H20.7236ZM20.7236 29.4936V28.2494C20.2932 27.6697 19.4766 27.3574 18.6366 27.3574C17.6166 27.3574 16.7792 27.9186 16.7792 28.8715C16.7792 29.8244 17.6166 30.3618 18.6366 30.3618C19.4766 30.3618 20.2932 30.0733 20.7236 29.4936Z"
960
+ fill="white"
961
+ />
962
+ <path
963
+ d="M26.2148 29.3825V24.189H24.5818V21.8887H26.2148V19.1543H28.8105V21.8887H30.8114V24.189H28.8105V28.689C28.8105 29.3322 29.1366 29.8087 29.7079 29.8087C30.0347 29.8233 30.355 29.7128 30.6053 29.499L31.1583 31.5081C30.7696 31.8602 30.0757 32.1514 28.9931 32.1514C27.1748 32.1461 26.2148 31.1931 26.2148 29.3825Z"
964
+ fill="white"
965
+ />
966
+ <path
967
+ d="M38.3036 31.8971V30.8382C37.6305 31.6668 36.4775 32.1432 35.1732 32.1432C33.6079 32.1432 31.761 31.0659 31.761 28.8265C31.761 26.4653 33.6001 25.5944 35.1732 25.5944C36.4984 25.5944 37.6436 26.0285 38.3036 26.8174V25.5547C38.3036 24.5409 37.4453 23.8765 36.1384 23.8765C35.078 23.8882 34.0624 24.3116 33.3001 25.0597L32.2801 23.2068C33.4725 22.1527 35.0086 21.5866 36.5897 21.6185C38.8566 21.6185 40.9175 22.5291 40.9175 25.4091V31.8971H38.3036ZM38.3036 29.4935V28.2494C37.8758 27.6697 37.0592 27.3574 36.2166 27.3574C35.194 27.3574 34.3566 27.9185 34.3566 28.8715C34.3566 29.8244 35.194 30.3618 36.2166 30.3618C37.0592 30.3618 37.8758 30.0732 38.3036 29.4935Z"
968
+ fill="white"
969
+ />
970
+ <path
971
+ d="M47.022 29.9489L48.6159 27.6486C49.1742 28.244 49.846 28.718 50.5904 29.042C51.3348 29.366 52.1363 29.5331 52.9463 29.5333C54.5585 29.5333 55.315 28.808 55.315 28.0006C55.3046 25.5971 47.4785 27.2647 47.4785 22.0739C47.4785 19.7736 49.4376 17.8677 52.6437 17.8677C54.8089 17.8677 56.6063 18.5321 57.9524 19.7947L56.348 21.9918C55.2592 21.004 53.8459 20.4649 52.3854 20.4803C51.162 20.4803 50.4681 21.0097 50.4681 21.8462C50.4681 24.0221 58.2941 22.5503 58.2941 27.7121C58.2941 30.24 56.4967 32.1459 52.842 32.1459C50.1889 32.1459 48.3107 31.2539 47.022 29.9489Z"
972
+ fill="white"
973
+ />
974
+ <path
975
+ d="M59.7236 33.451C59.9833 33.5569 60.2603 33.6126 60.5402 33.6151C61.2158 33.6151 61.6645 33.4298 61.9097 32.8898L62.2775 32.0216L58.2732 21.8887H61.0436L63.6158 28.8504L66.2115 21.8887H68.9871L64.3515 33.5357C63.6158 35.4231 62.3088 35.9181 60.6158 35.9604C60.1882 35.9558 59.7626 35.8998 59.348 35.7937L59.7236 33.451Z"
976
+ fill="white"
977
+ />
978
+ <path
979
+ d="M76.6122 31.8972V25.846C76.6122 24.4589 75.8974 23.993 74.7861 23.993C74.3515 24.0019 73.9244 24.1103 73.5368 24.3101C73.1492 24.51 72.8112 24.7961 72.5479 25.1472V31.8972H69.9548V21.8886H72.5479V23.1725C72.9844 22.6849 73.5175 22.2964 74.1123 22.0323C74.707 21.7681 75.35 21.6344 75.9992 21.6398C78.1853 21.6398 79.2261 22.8839 79.2261 24.8163V31.8839L76.6122 31.8972Z"
980
+ fill="white"
981
+ />
982
+ <path
983
+ d="M80.9401 26.8809C80.9401 23.8156 83.1444 21.6397 86.1574 21.6397C88.1792 21.6397 89.4053 22.5318 90.0574 23.4424L88.3618 25.0597C88.1345 24.7133 87.823 24.4322 87.4575 24.2435C87.0919 24.0548 86.6846 23.9649 86.2748 23.9824C84.7096 23.9824 83.5983 25.1418 83.5983 26.8941C83.5983 28.6465 84.7018 29.8059 86.2748 29.8059C86.6855 29.8148 87.0919 29.7189 87.4565 29.527C87.8212 29.335 88.1325 29.0532 88.3618 28.7074L90.0574 30.3247C89.4053 31.2353 88.1792 32.1485 86.1574 32.1485C83.1444 32.1459 80.9401 29.97 80.9401 26.8809Z"
984
+ fill="white"
985
+ />
986
+ </g>
987
+ </svg>
988
+ )
989
+
990
+ const elevateLogoInverse = (
991
+ <svg
992
+ width="91"
993
+ height="36"
994
+ viewBox="0 0 91 36"
995
+ fill="none"
996
+ xmlns="http://www.w3.org/2000/svg"
997
+ >
998
+ <path
999
+ d="M-0.177261 10.5509V0.10437H7.48102V2.45344H2.5157V4.08033H7.37256V6.43205H2.5157V8.21237H7.48102V10.5614L-0.177261 10.5509Z"
1000
+ fill="#0097D3"
1001
+ />
1002
+ <path
1003
+ d="M10.251 10.5509V0.10437H12.9466V8.21237H17.1447V10.5614L10.251 10.5509Z"
1004
+ fill="#0097D3"
1005
+ />
1006
+ <path
1007
+ d="M19.7739 10.5509V0.10437H27.4322V2.45344H22.4669V4.08033H27.3211V6.43205H22.4669V8.21237H27.4322V10.5614L19.7739 10.5509Z"
1008
+ fill="#0097D3"
1009
+ />
1010
+ <path
1011
+ d="M33.0667 10.5509L29.1357 0.10437H32.1911L34.7756 7.63568L37.3442 0.10437H40.397L36.466 10.5509H33.0667Z"
1012
+ fill="#0097D3"
1013
+ />
1014
+ <path
1015
+ d="M48.8223 10.5509L48.2932 9.04565H44.177L43.6612 10.5509H40.6138L44.5448 0.10437H47.944L51.875 10.5509H48.8223ZM46.2536 2.76559L44.931 6.69658H47.5763L46.2536 2.76559Z"
1016
+ fill="#0097D3"
1017
+ />
1018
+ <path
1019
+ d="M55.256 10.5509V2.45344H52.3276V0.10437H60.8642V2.45344H57.9543V10.5509H55.256Z"
1020
+ fill="#0097D3"
1021
+ />
1022
+ <path
1023
+ d="M63.3984 10.5509V0.10437H71.0699V2.45344H66.094V4.08033H70.9482V6.43205H66.094V8.21237H71.0593V10.5614L63.3984 10.5509Z"
1024
+ fill="#0097D3"
1025
+ />
1026
+ <path
1027
+ d="M0.145493 31.8879V18.0765H5.59227C9.92006 18.0765 12.9225 20.8303 12.9225 24.9703C12.9225 29.1526 9.92006 31.8879 5.61343 31.8879H0.145493ZM9.92006 24.9703C9.92006 22.5472 8.43073 20.6637 5.61343 20.6637H3.08712V29.2981H5.59227C8.32491 29.2981 9.92006 27.3326 9.92006 24.9703Z"
1028
+ fill="#143D50"
1029
+ />
1030
+ <path
1031
+ d="M20.75 31.8878V30.8297C20.0649 31.6577 18.8851 32.1338 17.5756 32.1338C15.9884 32.1338 14.1181 31.0572 14.1181 28.8192C14.1181 26.4596 15.9699 25.5892 17.5756 25.5892C18.9221 25.5892 20.0808 26.0231 20.75 26.8114V25.5496C20.75 24.5364 19.8797 23.8724 18.5544 23.8724C17.479 23.8836 16.4489 24.3068 15.6763 25.0549L14.6419 23.2031C15.8498 22.1495 17.4069 21.5837 19.0094 21.6159C21.3082 21.6159 23.4007 22.5259 23.4007 25.4041V31.8878H20.75ZM20.75 29.4858V28.2425C20.3136 27.6632 19.4856 27.351 18.6338 27.351C17.5994 27.351 16.7503 27.9119 16.7503 28.8642C16.7503 29.8165 17.5994 30.3535 18.6338 30.3535C19.4856 30.3535 20.3136 30.0652 20.75 29.4858Z"
1032
+ fill="#143D50"
1033
+ />
1034
+ <path
1035
+ d="M26.3186 29.3748V24.1847H24.6626V21.8858H26.3186V19.1532H28.9507V21.8858H30.9797V24.1847H28.9507V28.6817C28.9507 29.3246 29.2814 29.8007 29.8607 29.8007C30.1921 29.8153 30.5169 29.7049 30.7707 29.4912L31.3315 31.499C30.9373 31.8509 30.2337 32.1419 29.1359 32.1419C27.2921 32.1366 26.3186 31.1842 26.3186 29.3748Z"
1036
+ fill="#143D50"
1037
+ />
1038
+ <path
1039
+ d="M38.5769 31.8878V30.8297C37.8944 31.6576 36.7252 32.1338 35.4025 32.1338C33.8153 32.1338 31.9424 31.0572 31.9424 28.8192C31.9424 26.4595 33.8073 25.5892 35.4025 25.5892C36.7463 25.5892 37.9076 26.0231 38.5769 26.8114V25.5495C38.5769 24.5364 37.7066 23.8724 36.3813 23.8724C35.306 23.8841 34.2761 24.3073 33.5031 25.0549L32.4688 23.2031C33.6779 22.1498 35.2357 21.584 36.8389 21.6159C39.1377 21.6159 41.2275 22.5259 41.2275 25.404V31.8878H38.5769ZM38.5769 29.4858V28.2425C38.1431 27.6632 37.3151 27.351 36.4606 27.351C35.4236 27.351 34.5745 27.9118 34.5745 28.8642C34.5745 29.8165 35.4236 30.3535 36.4606 30.3535C37.3151 30.3535 38.1431 30.0651 38.5769 29.4858Z"
1040
+ fill="#143D50"
1041
+ />
1042
+ <path
1043
+ d="M47.418 29.9409L49.0343 27.6421C49.6005 28.2371 50.2817 28.7109 51.0365 29.0347C51.7914 29.3584 52.6042 29.5255 53.4255 29.5256C55.0604 29.5256 55.8275 28.8008 55.8275 27.9939C55.8169 25.592 47.8809 27.2585 47.8809 22.071C47.8809 19.7722 49.8675 17.8676 53.1187 17.8676C55.3143 17.8676 57.137 18.5315 58.502 19.7934L56.8751 21.989C55.771 21.0019 54.3378 20.4631 52.8568 20.4785C51.6161 20.4785 50.9125 21.0076 50.9125 21.8435C50.9125 24.018 58.8485 22.5472 58.8485 27.7056C58.8485 30.2319 57.0259 32.1366 53.3197 32.1366C50.6294 32.1366 48.7248 31.2451 47.418 29.9409Z"
1044
+ fill="#143D50"
1045
+ />
1046
+ <path
1047
+ d="M60.2979 33.441C60.5613 33.5468 60.8421 33.6025 61.1259 33.605C61.8111 33.605 62.2661 33.4198 62.5147 32.8802L62.8877 32.0125L58.8271 21.8861H61.6365L64.2448 28.8434L66.8769 21.8861H69.6916L64.9908 33.5256C64.2448 35.4118 62.9195 35.9065 61.2027 35.9488C60.769 35.9441 60.3375 35.8882 59.917 35.7821L60.2979 33.441Z"
1048
+ fill="#143D50"
1049
+ />
1050
+ <path
1051
+ d="M77.4242 31.888V25.8407C77.4242 24.4545 76.6994 23.989 75.5725 23.989C75.1317 23.9978 74.6987 24.1061 74.3056 24.3058C73.9126 24.5055 73.5698 24.7915 73.3028 25.1423V31.888H70.6733V21.8859H73.3028V23.1689C73.7455 22.6817 74.2861 22.2934 74.8892 22.0294C75.4923 21.7655 76.1443 21.6319 76.8026 21.6372C79.0194 21.6372 80.0749 22.8806 80.0749 24.8117V31.8747L77.4242 31.888Z"
1052
+ fill="#143D50"
1053
+ />
1054
+ <path
1055
+ d="M81.8125 26.8749C81.8125 23.8116 84.0478 21.6371 87.1032 21.6371C89.1533 21.6371 90.3966 22.5286 91.058 23.4386L89.3385 25.0549C89.108 24.7087 88.7921 24.4278 88.4214 24.2392C88.0508 24.0506 87.6377 23.9607 87.2222 23.9782C85.635 23.9782 84.5081 25.1369 84.5081 26.8881C84.5081 28.6393 85.6271 29.798 87.2222 29.798C87.6387 29.8069 88.0507 29.7111 88.4205 29.5192C88.7903 29.3274 89.1059 29.0458 89.3385 28.7002L91.058 30.3165C90.3966 31.2265 89.1533 32.1391 87.1032 32.1391C84.0478 32.1365 81.8125 29.962 81.8125 26.8749Z"
1056
+ fill="#143D50"
1057
+ />
1058
+ </svg>
1059
+ )
1060
+
1061
+ const elevateIcon = (
1062
+ <svg
1063
+ width="40"
1064
+ height="40"
1065
+ viewBox="0 0 40 40"
1066
+ fill="none"
1067
+ xmlns="http://www.w3.org/2000/svg"
1068
+ >
1069
+ <path
1070
+ d="M17.2933 31.0827C15.1594 30.574 13.2178 29.4599 11.7019 27.8743C10.1859 26.2887 9.16013 24.2991 8.7478 22.1445C8.33547 19.9899 8.55415 17.7621 9.37754 15.7288C10.2009 13.6955 11.594 11.9433 13.3893 10.6827L13.0666 13.9707L14.4 14.0987L14.912 8.8L9.59997 8.26666L9.47198 9.6L12.232 9.86666C9.9706 11.5897 8.35089 14.0199 7.63086 16.7701C6.91083 19.5204 7.1319 22.4326 8.25887 25.0426C9.38584 27.6527 11.3539 29.8105 13.8494 31.1724C16.345 32.5343 19.2245 33.0218 22.0293 32.5573L21.8106 31.2427C20.3095 31.4942 18.7729 31.4398 17.2933 31.0827Z"
1071
+ fill="white"
1072
+ />
1073
+ <path
1074
+ d="M30.8027 13.3335C29.4769 11.1761 27.5381 9.46282 25.2339 8.41261C22.9297 7.36241 20.3648 7.02291 17.8667 7.43748L18.0854 8.75215C20.6006 8.33221 23.184 8.76789 25.4223 9.98951C27.6607 11.2111 29.4247 13.1481 30.4323 15.4907C31.4398 17.8332 31.6327 20.446 30.98 22.911C30.3273 25.3761 28.8668 27.5511 26.832 29.0882L27.0987 26.3362L25.7654 26.2081L25.3094 30.9015L30.0027 31.3575L30.1307 30.0241L28.0374 29.8215C30.4138 27.872 32.0034 25.1275 32.5118 22.096C33.0202 19.0646 32.4131 15.9516 30.8027 13.3335Z"
1075
+ fill="white"
1076
+ />
1077
+ <path
1078
+ d="M26.7973 21.0347C26.7966 20.4238 26.5537 19.8382 26.1217 19.4063C25.6898 18.9743 25.1042 18.7314 24.4933 18.7307H24.376C24.3739 17.6701 23.9768 16.6484 23.2623 15.8647C22.5478 15.081 21.567 14.5915 20.5112 14.4916C19.4554 14.3917 18.4002 14.6886 17.5514 15.3244C16.7026 15.9602 16.121 16.8893 15.92 17.9307H15.808C15.0909 17.9307 14.4031 18.2155 13.896 18.7226C13.3889 19.2297 13.104 19.9175 13.104 20.6347C13.104 21.3518 13.3889 22.0396 13.896 22.5467C14.4031 23.0538 15.0909 23.3387 15.808 23.3387H24.4933C25.1044 23.3387 25.6904 23.0959 26.1225 22.6638C26.5546 22.2317 26.7973 21.6457 26.7973 21.0347ZM24.4933 22.0053H15.808C15.4445 22.0053 15.0958 21.8609 14.8388 21.6039C14.5817 21.3468 14.4373 20.9982 14.4373 20.6347C14.4373 20.2711 14.5817 19.9225 14.8388 19.6654C15.0958 19.4084 15.4445 19.264 15.808 19.264H17.1227L17.1627 18.64C17.1878 17.8599 17.5217 17.1217 18.0911 16.5879C18.6605 16.054 19.4186 15.7682 20.1987 15.7933C20.9788 15.8184 21.7169 16.1524 22.2508 16.7218C22.7846 17.2911 23.0704 18.0492 23.0453 18.8293V19.0587C23.0453 19.152 23.0453 19.2453 23.0293 19.3253L22.9627 20.0533H24.4933C24.7508 20.0533 24.9977 20.1556 25.1797 20.3376C25.3617 20.5197 25.464 20.7666 25.464 21.024C25.464 21.2814 25.3617 21.5283 25.1797 21.7104C24.9977 21.8924 24.7508 21.9947 24.4933 21.9947V22.0053Z"
1079
+ fill="white"
1080
+ />
1081
+ </svg>
1082
+ )
1083
+
1084
+ render(<PlaygroundExample />)
1085
+ ```
1086
+
1087
+ ### Responsive layout
1088
+
1089
+ TopNavBar is a responsive component, and it has 4 "sections" or "blocks".
1090
+
1091
+ The `<TopNavBar.Layout>` component has a `desktopConfig` and a `smallViewportConfig` prop that handles how the different views are set up.
1092
+
1093
+ #### Main blocks
1094
+
1095
+ ##### TopNavBar.Brand
1096
+
1097
+ `<TopNavBar.Brand>` contains the brand logo and icon.
1098
+
1099
+ Use the brand logo over the primary brand color in front of the brand's name. If there is no brand logo then use the name with darker background.
1100
+
1101
+ ```js
1102
+ ---
1103
+ example: true
1104
+ ---
1105
+ <div>
1106
+ <View as="div" margin="medium 0">
1107
+ <TopNavBar>
1108
+ {() => (
1109
+ <TopNavBar.Layout
1110
+ navLabel="Example navigation bar"
1111
+ desktopConfig={{
1112
+ hideActionsUserSeparator: false
1113
+ }}
1114
+ smallViewportConfig={{
1115
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1116
+ dropdownMenuLabel: 'Main Menu',
1117
+ }}
1118
+ renderBrand={(
1119
+ <TopNavBar.Brand
1120
+ screenReaderLabel="Brand name"
1121
+ renderName={(
1122
+ <View as="div" minWidth="7rem">
1123
+ <Text
1124
+ as="div"
1125
+ color="primary-inverse"
1126
+ transform="uppercase"
1127
+ size="small"
1128
+ weight="bold"
1129
+ lineHeight="condensed"
1130
+ >
1131
+ Brand
1132
+ </Text>
1133
+ <Text
1134
+ as="div"
1135
+ color="primary-inverse"
1136
+ size="large"
1137
+ weight="normal"
1138
+ lineHeight="condensed"
1139
+ >
1140
+ Sub-brand
1141
+ </Text>
1142
+ </View>
1143
+ )}
1144
+ renderIcon={(
1145
+ <IconBoldLine
1146
+ size="small"
1147
+ color="primary-inverse"
1148
+ height="2.5rem"
1149
+ width="2.5rem"
1150
+ />
1151
+ )}
1152
+ iconBackground="#0097D3"
1153
+ href="/#TopNavBar"
1154
+ />
1155
+ )}
1156
+ />
1157
+ )}
1158
+ </TopNavBar>
1159
+ </View>
1160
+
1161
+ <View as="div" margin="medium 0">
1162
+ <TopNavBar>
1163
+ {() => (
1164
+ <TopNavBar.Layout
1165
+ navLabel="Example navigation bar"
1166
+ desktopConfig={{
1167
+ hideActionsUserSeparator: false
1168
+ }}
1169
+ smallViewportConfig={{
1170
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1171
+ dropdownMenuLabel: 'Main Menu',
1172
+ }}
1173
+ renderBrand={(
1174
+ <TopNavBar.Brand
1175
+ screenReaderLabel="Brand name"
1176
+ renderName={(
1177
+ <View as="div" minWidth="7rem">
1178
+ <Text
1179
+ as="div"
1180
+ color="primary-inverse"
1181
+ transform="uppercase"
1182
+ size="small"
1183
+ weight="bold"
1184
+ lineHeight="condensed"
1185
+ >
1186
+ Brand
1187
+ </Text>
1188
+ <Text
1189
+ as="div"
1190
+ color="primary-inverse"
1191
+ size="large"
1192
+ weight="normal"
1193
+ lineHeight="condensed"
1194
+ >
1195
+ Sub-brand
1196
+ </Text>
1197
+ </View>
1198
+ )}
1199
+ nameBackground="#2D3B45"
1200
+ href="/#TopNavBar"
1201
+ />
1202
+ )}
1203
+ />
1204
+ )}
1205
+ </TopNavBar>
1206
+ </View>
1207
+ </div>
1208
+ ```
1209
+
1210
+ ##### TopNavBar.MenuItems
1211
+
1212
+ `<TopNavBar.MenuItems>` contains the main menu items, subpage links.
1213
+
1214
+ If there is not enough space to display all items, the list is truncated, and the hidden items are available under a dropdown menu.
1215
+
1216
+ When a menu item has multiple levels, a submenu can be rendered by passing a [Drilldown](#Drilldown) navigation via it's `renderSubmenu` prop. If a more specialized dropdown is needed, it can be configured by the `customPopoverConfig` prop (see the [Dropdowns](/#TopNavBar/#items-dropdowns) section).
1217
+
1218
+ The current page is highlighted, if it's id is passed via the `currentPageId` prop. (Note that it doesn't highlight items in submenus, but it highlights items hidden in truncated lists.)
1219
+
1220
+ ```js
1221
+ ---
1222
+ example: true
1223
+ ---
1224
+ <div>
1225
+ <View as="div" margin="medium 0">
1226
+ <TopNavBar breakpoint="10rem">
1227
+ {() => (
1228
+ <TopNavBar.Layout
1229
+ navLabel="Example navigation bar"
1230
+ desktopConfig={{
1231
+ hideActionsUserSeparator: false
1232
+ }}
1233
+ smallViewportConfig={{
1234
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1235
+ dropdownMenuLabel: 'Main Menu',
1236
+ }}
1237
+ renderMenuItems={(
1238
+ <TopNavBar.MenuItems
1239
+ listLabel="Page navigation"
1240
+ currentPageId="menuItems1Page2"
1241
+ renderHiddenItemsMenuTriggerLabel={(
1242
+ hiddenChildrenCount
1243
+ ) => `${hiddenChildrenCount} More`}
1244
+ >
1245
+ {Array.from(Array(4)).map((_item, idx) => (
1246
+ <TopNavBar.Item
1247
+ id={`menuItems1Page${idx + 1}`}
1248
+ key={`menuItems1Page${idx + 1}`}
1249
+ href={idx === 2 ? undefined : "/#TopNavBar"}
1250
+ renderSubmenu={idx === 2 ? (
1251
+ <Drilldown rootPageId="root">
1252
+ <Drilldown.Page id="root">
1253
+ {Array.from(Array(4)).map((_item, idx) => (
1254
+ <Drilldown.Option
1255
+ id={`option${idx + 1}`}
1256
+ key={`option${idx + 1}`}
1257
+ href="/#TopNavBar"
1258
+ >
1259
+ Option {idx + 1}
1260
+ </Drilldown.Option>
1261
+ ))}
1262
+ </Drilldown.Page>
1263
+ </Drilldown>
1264
+ ) : undefined}
1265
+ >
1266
+ Page {idx + 1}
1267
+ </TopNavBar.Item>
1268
+ ))}
1269
+ </TopNavBar.MenuItems>
1270
+ )}
1271
+ />
1272
+ )}
1273
+ </TopNavBar>
1274
+ </View>
1275
+
1276
+ <View as="div" margin="medium 0">
1277
+ <TopNavBar breakpoint="10rem">
1278
+ {() => (
1279
+ <TopNavBar.Layout
1280
+ navLabel="Example navigation bar"
1281
+ desktopConfig={{
1282
+ hideActionsUserSeparator: false
1283
+ }}
1284
+ smallViewportConfig={{
1285
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1286
+ dropdownMenuLabel: 'Main Menu',
1287
+ }}
1288
+ renderMenuItems={(
1289
+ <TopNavBar.MenuItems
1290
+ listLabel="Page navigation"
1291
+ currentPageId="menuItems2Page11"
1292
+ renderHiddenItemsMenuTriggerLabel={(
1293
+ hiddenChildrenCount
1294
+ ) => `${hiddenChildrenCount} More`}
1295
+ >
1296
+ {Array.from(Array(14)).map((_item, idx) => (
1297
+ <TopNavBar.Item
1298
+ id={`menuItems2Page${idx + 1}`}
1299
+ key={`menuItems2Page${idx + 1}`}
1300
+ href={idx === 2 || idx === 6 ? undefined : "/#TopNavBar"}
1301
+ renderSubmenu={idx === 2 ? (
1302
+ <Drilldown rootPageId="root">
1303
+ <Drilldown.Page id="root">
1304
+ {Array.from(Array(4)).map((_item, idx) => (
1305
+ <Drilldown.Option
1306
+ id={`option${idx + 1}`}
1307
+ key={`option${idx + 1}`}
1308
+ href="/#TopNavBar"
1309
+ >
1310
+ Option {idx + 1}
1311
+ </Drilldown.Option>
1312
+ ))}
1313
+ </Drilldown.Page>
1314
+ </Drilldown>
1315
+ ) : undefined}
1316
+ customPopoverConfig={idx === 6 ? {
1317
+ children: (
1318
+ <View padding="medium" as="div">
1319
+ Example Custom Popover
1320
+ </View>
1321
+ ),
1322
+ on: 'click'
1323
+ }: undefined}
1324
+ >
1325
+ Page {idx + 1}
1326
+ </TopNavBar.Item>
1327
+ ))}
1328
+ </TopNavBar.MenuItems>
1329
+ )}
1330
+ />
1331
+ )}
1332
+ </TopNavBar>
1333
+ </View>
1334
+ </div>
1335
+ ```
1336
+
1337
+ ##### TopNavBar.ActionItems
1338
+
1339
+ `<TopNavBar.ActionItems>` contains items that do some action or have special function.
1340
+
1341
+ Action items can have submenus and popovers too. It is also recommended to add helpful tooltips to items that are "icon" variants.
1342
+
1343
+ **Special case:** The "Search" action should open in a flyout on desktop. On the mobile/tablet view it should fill the header (see the [Playground](/#TopNavBar/#playground) example).
1344
+
1345
+ If the last action is shown as text and the user is shown as text, use the separator between the 2 blocks, otherwise it is optional (`desktopConfig.hideActionsUserSeparator` prop on the `<TopNavBar.Layout>`).
1346
+
1347
+ ```js
1348
+ ---
1349
+ example: true
1350
+ ---
1351
+ <div>
1352
+ <View as="div" margin="medium 0">
1353
+ <TopNavBar>
1354
+ {() => (
1355
+ <TopNavBar.Layout
1356
+ navLabel="Example navigation bar"
1357
+ desktopConfig={{
1358
+ hideActionsUserSeparator: true
1359
+ }}
1360
+ smallViewportConfig={{
1361
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1362
+ dropdownMenuLabel: 'Main Menu',
1363
+ }}
1364
+ renderActionItems={(
1365
+ <TopNavBar.ActionItems
1366
+ listLabel="Actions"
1367
+ renderHiddenItemsMenuTriggerLabel={(
1368
+ hiddenChildrenCount
1369
+ ) => `${hiddenChildrenCount} more actions`}
1370
+ >
1371
+ <TopNavBar.Item
1372
+ id="AlertsAction1"
1373
+ variant="icon"
1374
+ tooltip="Alerts"
1375
+ renderIcon={<IconAlertsLine />}
1376
+ onClick={() => {
1377
+ console.log('Alerts')
1378
+ }}
1379
+ >
1380
+ Alerts
1381
+ </TopNavBar.Item>
1382
+ <TopNavBar.Item
1383
+ id="SearchAction"
1384
+ variant="icon"
1385
+ tooltip="Search"
1386
+ renderIcon={<IconSearchLine />}
1387
+ customPopoverConfig={{
1388
+ on: 'click',
1389
+ children: (
1390
+ <View as="div" padding="x-small">
1391
+ <TextInput
1392
+ id="searchInput"
1393
+ width="100%"
1394
+ display="block"
1395
+ renderLabel={<ScreenReaderContent>Search</ScreenReaderContent>}
1396
+ renderBeforeInput={() => <IconSearchLine inline={false} />}
1397
+ placeholder="Search..."
1398
+ onChange={(_event, value) => {
1399
+ console.log(value)
1400
+ }}
1401
+ onKeyDown={(event) => {
1402
+ if (event.key === 'Enter') {
1403
+ event.preventDefault()
1404
+ event.stopPropagation()
1405
+
1406
+ console.log(`Search input submitted.`)
1407
+ }
1408
+ }}
1409
+ />
1410
+ </View>
1411
+ )
1412
+ }}
1413
+ >
1414
+ Search
1415
+ </TopNavBar.Item>
1416
+ <TopNavBar.Item
1417
+ id="ForumAction1"
1418
+ renderIcon={<IconDiscussionLine />}
1419
+ onClick={() => {
1420
+ console.log('Forum')
1421
+ }}
1422
+ >
1423
+ Forum
1424
+ </TopNavBar.Item>
1425
+ <TopNavBar.Item
1426
+ id="InfoAction1"
1427
+ variant="icon"
1428
+ tooltip="Info"
1429
+ renderIcon={<IconQuestionLine />}
1430
+ href="/#TopNavBar"
1431
+ >
1432
+ Info
1433
+ </TopNavBar.Item>
1434
+ </TopNavBar.ActionItems>
1435
+ )}
1436
+ renderUser={(
1437
+ <TopNavBar.User>
1438
+ <TopNavBar.Item
1439
+ id="LogInRegisterButton1"
1440
+ href="/#TopNavBar"
1441
+ variant="button"
1442
+ >
1443
+ Log In/Register
1444
+ </TopNavBar.Item>
1445
+ </TopNavBar.User>
1446
+ )}
1447
+ />
1448
+ )}
1449
+ </TopNavBar>
1450
+ </View>
1451
+
1452
+ <View as="div" margin="medium 0">
1453
+ <TopNavBar>
1454
+ {() => (
1455
+ <TopNavBar.Layout
1456
+ navLabel="Example navigation bar"
1457
+ desktopConfig={{
1458
+ hideActionsUserSeparator: false
1459
+ }}
1460
+ smallViewportConfig={{
1461
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1462
+ dropdownMenuLabel: 'Main Menu',
1463
+ }}
1464
+ renderActionItems={(
1465
+ <TopNavBar.ActionItems
1466
+ listLabel="Actions"
1467
+ renderHiddenItemsMenuTriggerLabel={(
1468
+ hiddenChildrenCount
1469
+ ) => `${hiddenChildrenCount} more actions`}
1470
+ >
1471
+ <TopNavBar.Item
1472
+ id="AlertsAction2"
1473
+ renderIcon={<IconAlertsLine />}
1474
+ onClick={() => {
1475
+ console.log('Alerts')
1476
+ }}
1477
+ >
1478
+ Alerts
1479
+ </TopNavBar.Item>
1480
+ <TopNavBar.Item
1481
+ id="ForumAction2"
1482
+ renderIcon={<IconDiscussionLine />}
1483
+ onClick={() => {
1484
+ console.log('Forum')
1485
+ }}
1486
+ >
1487
+ Forum
1488
+ </TopNavBar.Item>
1489
+ <TopNavBar.Item
1490
+ id="InfoAction2"
1491
+ renderIcon={<IconQuestionLine />}
1492
+ onClick={() => {
1493
+ console.log('Info')
1494
+ }}
1495
+ >
1496
+ Info
1497
+ </TopNavBar.Item>
1498
+ </TopNavBar.ActionItems>
1499
+ )}
1500
+ renderUser={(
1501
+ <TopNavBar.User>
1502
+ <TopNavBar.Item
1503
+ id="LogInRegisterButton2"
1504
+ href="/#TopNavBar"
1505
+ >
1506
+ Log In/Register
1507
+ </TopNavBar.Item>
1508
+ </TopNavBar.User>
1509
+ )}
1510
+ />
1511
+ )}
1512
+ </TopNavBar>
1513
+ </View>
1514
+ </div>
1515
+ ```
1516
+
1517
+ ##### TopNavBar.User
1518
+
1519
+ `<TopNavBar.User>` contains the login/register button and user menu.
1520
+
1521
+ If the last action is shown as text and the user is shown as text, use the separator between the 2 blocks, otherwise it is optional (`desktopConfig.hideActionsUserSeparator` prop on the `<TopNavBar.Layout>`).
1522
+
1523
+ ```js
1524
+ ---
1525
+ example: true
1526
+ ---
1527
+ <div>
1528
+ <View as="div" margin="medium 0">
1529
+ <TopNavBar breakpoint="10rem">
1530
+ {() => (
1531
+ <TopNavBar.Layout
1532
+ navLabel="Example navigation bar"
1533
+ desktopConfig={{
1534
+ hideActionsUserSeparator: false
1535
+ }}
1536
+ smallViewportConfig={{
1537
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1538
+ dropdownMenuLabel: 'Main Menu',
1539
+ }}
1540
+ renderUser={(
1541
+ <TopNavBar.User>
1542
+ <TopNavBar.Item
1543
+ id="LogInRegisterButton3"
1544
+ href="/#TopNavBar"
1545
+ >
1546
+ Log In/Register
1547
+ </TopNavBar.Item>
1548
+ </TopNavBar.User>
1549
+ )}
1550
+ />
1551
+ )}
1552
+ </TopNavBar>
1553
+ </View>
1554
+
1555
+ <View as="div" margin="medium 0">
1556
+ <TopNavBar breakpoint="10rem">
1557
+ {() => (
1558
+ <TopNavBar.Layout
1559
+ navLabel="Example navigation bar"
1560
+ desktopConfig={{
1561
+ hideActionsUserSeparator: false
1562
+ }}
1563
+ smallViewportConfig={{
1564
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1565
+ dropdownMenuLabel: 'Main Menu',
1566
+ }}
1567
+ renderUser={(
1568
+ <TopNavBar.User>
1569
+ <TopNavBar.Item
1570
+ id="LogInRegisterButton4"
1571
+ href="/#TopNavBar"
1572
+ variant="button"
1573
+ >
1574
+ Log In/Register
1575
+ </TopNavBar.Item>
1576
+ </TopNavBar.User>
1577
+ )}
1578
+ />
1579
+ )}
1580
+ </TopNavBar>
1581
+ </View>
1582
+
1583
+ <View as="div" margin="medium 0">
1584
+ <TopNavBar breakpoint="10rem">
1585
+ {() => (
1586
+ <TopNavBar.Layout
1587
+ navLabel="Example navigation bar"
1588
+ desktopConfig={{
1589
+ hideActionsUserSeparator: false
1590
+ }}
1591
+ smallViewportConfig={{
1592
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1593
+ dropdownMenuLabel: 'Main Menu',
1594
+ }}
1595
+ renderUser={(
1596
+ <TopNavBar.User>
1597
+ <TopNavBar.Item
1598
+ id="UserMenu1"
1599
+ renderSubmenu={(
1600
+ <Drilldown rootPageId="root">
1601
+ <Drilldown.Page id="root">
1602
+ {Array.from(Array(4)).map((_item, idx) => (
1603
+ <Drilldown.Option
1604
+ id={`userOption${idx + 1}`}
1605
+ key={`userOption${idx + 1}`}
1606
+ href="/#TopNavBar"
1607
+ >
1608
+ User Menu Option {idx + 1}
1609
+ </Drilldown.Option>
1610
+ ))}
1611
+ </Drilldown.Page>
1612
+ </Drilldown>
1613
+ )}
1614
+ >
1615
+ User Name
1616
+ </TopNavBar.Item>
1617
+ </TopNavBar.User>
1618
+ )}
1619
+ />
1620
+ )}
1621
+ </TopNavBar>
1622
+ </View>
1623
+
1624
+ <View as="div" margin="medium 0">
1625
+ <TopNavBar breakpoint="10rem">
1626
+ {() => (
1627
+ <TopNavBar.Layout
1628
+ navLabel="Example navigation bar"
1629
+ desktopConfig={{
1630
+ hideActionsUserSeparator: false
1631
+ }}
1632
+ smallViewportConfig={{
1633
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1634
+ dropdownMenuLabel: 'Main Menu',
1635
+ }}
1636
+ renderUser={(
1637
+ <TopNavBar.User>
1638
+ <TopNavBar.Item
1639
+ id="UserMenu2"
1640
+ renderAvatar={{ avatarName: 'User Name', avatarSrc: avatarSquare }}
1641
+ renderSubmenu={(
1642
+ <Drilldown rootPageId="root">
1643
+ <Drilldown.Page id="root">
1644
+ {Array.from(Array(4)).map((_item, idx) => (
1645
+ <Drilldown.Option
1646
+ id={`userOption${idx + 1}`}
1647
+ key={`userOption${idx + 1}`}
1648
+ href="/#TopNavBar"
1649
+ >
1650
+ User Menu Option {idx + 1}
1651
+ </Drilldown.Option>
1652
+ ))}
1653
+ </Drilldown.Page>
1654
+ </Drilldown>
1655
+ )}
1656
+ >
1657
+ User Name
1658
+ </TopNavBar.Item>
1659
+ </TopNavBar.User>
1660
+ )}
1661
+ />
1662
+ )}
1663
+ </TopNavBar>
1664
+ </View>
1665
+
1666
+ <View as="div" margin="medium 0">
1667
+ <TopNavBar breakpoint="10rem">
1668
+ {() => (
1669
+ <TopNavBar.Layout
1670
+ navLabel="Example navigation bar"
1671
+ desktopConfig={{
1672
+ hideActionsUserSeparator: false
1673
+ }}
1674
+ smallViewportConfig={{
1675
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1676
+ dropdownMenuLabel: 'Main Menu',
1677
+ }}
1678
+ renderUser={(
1679
+ <TopNavBar.User>
1680
+ <TopNavBar.Item
1681
+ id="UserMenu3"
1682
+ variant="avatar"
1683
+ renderAvatar={{ avatarName: 'User Name', avatarSrc: avatarSquare }}
1684
+ onClick={() => {
1685
+ console.log('User action')
1686
+ }}
1687
+ >
1688
+ User Name
1689
+ </TopNavBar.Item>
1690
+ </TopNavBar.User>
1691
+ )}
1692
+ />
1693
+ )}
1694
+ </TopNavBar>
1695
+ </View>
1696
+ </div>
1697
+ ```
1698
+
1699
+ #### smallViewport mode
1700
+
1701
+ At the breakpoint (defined by the `breakpoint` and `mediaQueryMatch` props) it will switch between the "desktop" (fullscreen) view mode and the "smallViewport" view mode (optimized for mobile devices and smaller viewports).
1702
+
1703
+ The main difference between the two is that in "smallViewport" mode:
1704
+
1705
+ - The content of the `<TopNavBar.MenuItems>` and the `<TopNavBar.User>` blocks will be moved to a dropdown menu. The user block comes first, and there is a separator between the 2 blocks.
1706
+ - The `<TopNavBar.ActionItems>` stays in place, but its items will be converted into "icon" variant items.
1707
+ - The `<TopNavBar.Brand>` block will only display the brand logo.
1708
+
1709
+ ```js
1710
+ ---
1711
+ example: true
1712
+ render: false
1713
+ ---
1714
+ class LayoutExample extends React.Component {
1715
+ state = {
1716
+ exampleWidth: '100%',
1717
+ isSecondaryNavigation: false
1718
+ }
1719
+
1720
+ render() {
1721
+ return (
1722
+ <View as="div">
1723
+ <View as="div" maxWidth="42rem" padding="small" background="primary">
1724
+ <FormFieldGroup description="Example settings" layout="columns">
1725
+ <Checkbox
1726
+ variant="toggle"
1727
+ value="toggleSmallViewportMode"
1728
+ label="Toggle smallViewport mode"
1729
+ checked={this.state.exampleWidth === '500px'}
1730
+ onChange={() => {
1731
+ this.setState({ exampleWidth: this.state.exampleWidth === '100%'
1732
+ ? '500px'
1733
+ : '100%'
1734
+ })
1735
+ }}
1736
+ />
1737
+
1738
+ <Checkbox
1739
+ variant="toggle"
1740
+ value="toggleSecondaryNavigationtMode"
1741
+ label="Toggle secondary navigation mode"
1742
+ checked={this.state.isSecondaryNavigation}
1743
+ onChange={() => {
1744
+ this.setState({
1745
+ isSecondaryNavigation: !this.state.isSecondaryNavigation
1746
+ })
1747
+ }}
1748
+ />
1749
+ </FormFieldGroup>
1750
+ </View>
1751
+
1752
+ <View as="div" margin="medium 0 0" width={this.state.exampleWidth}>
1753
+ <div
1754
+ style={{
1755
+ height: '100%',
1756
+ position: 'relative',
1757
+ background: '#fff'
1758
+ }}
1759
+ >
1760
+ <TopNavBar
1761
+ breakpoint='650'
1762
+ mediaQueryMatch='element'
1763
+ inverseColor={this.state.isSecondaryNavigation}
1764
+ key={this.state.exampleWidth}
1765
+ >
1766
+ {({ currentLayout, inverseColor }) => {
1767
+ return (
1768
+ <TopNavBar.Layout
1769
+ navLabel={this.state.isSecondaryNavigation
1770
+ ? 'Example secondary navigation bar'
1771
+ : 'Example navigation bar'}
1772
+ desktopConfig={{
1773
+ hideActionsUserSeparator: true
1774
+ }}
1775
+ smallViewportConfig={{
1776
+ trayMountNode: () => document.getElementById('menuMountNode'),
1777
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
1778
+ dropdownMenuLabel: 'Main Menu',
1779
+ alternativeTitle: inverseColor ? 'Overview' : undefined
1780
+ }}
1781
+ renderBrand={
1782
+ <TopNavBar.Brand
1783
+ screenReaderLabel="Brand name"
1784
+ renderName={(
1785
+ <View as="div" minWidth="7rem">
1786
+ <Text
1787
+ as="div"
1788
+ color={inverseColor
1789
+ ? "brand"
1790
+ : "primary-inverse"
1791
+ }
1792
+ transform="uppercase"
1793
+ size="small"
1794
+ weight="bold"
1795
+ lineHeight="condensed"
1796
+ >
1797
+ Brand
1798
+ </Text>
1799
+ <Text
1800
+ as="div"
1801
+ color={inverseColor
1802
+ ? "primary"
1803
+ : "primary-inverse"
1804
+ }
1805
+ size="large"
1806
+ weight="normal"
1807
+ lineHeight="condensed"
1808
+ >
1809
+ Sub-brand
1810
+ </Text>
1811
+ </View>
1812
+ )}
1813
+ renderIcon={inverseColor ? undefined : (
1814
+ <IconBoldLine
1815
+ size="small"
1816
+ color="primary-inverse"
1817
+ height="2.5rem"
1818
+ width="2.5rem"
1819
+ />
1820
+ )}
1821
+ iconBackground="#0097D3"
1822
+ href="/#TopNavBar"
1823
+ />
1824
+ }
1825
+ renderMenuItems={
1826
+ <TopNavBar.MenuItems
1827
+ listLabel="Page navigation"
1828
+ currentPageId="OverviewPage"
1829
+ renderHiddenItemsMenuTriggerLabel={(
1830
+ hiddenChildrenCount
1831
+ ) => `${hiddenChildrenCount} More`}
1832
+ >
1833
+ <TopNavBar.Item
1834
+ id="OverviewPage"
1835
+ href="/#TopNavBar"
1836
+ >
1837
+ Overview
1838
+ </TopNavBar.Item>
1839
+ <TopNavBar.Item
1840
+ id="AdminPage"
1841
+ href="/#TopNavBar"
1842
+ >
1843
+ Admin
1844
+ </TopNavBar.Item>
1845
+ <TopNavBar.Item
1846
+ id="SettingsPage"
1847
+ href="/#TopNavBar"
1848
+ >
1849
+ Settings
1850
+ </TopNavBar.Item>
1851
+ <TopNavBar.Item
1852
+ id="MapsPage"
1853
+ href="/#TopNavBar"
1854
+ >
1855
+ Maps
1856
+ </TopNavBar.Item>
1857
+ <TopNavBar.Item
1858
+ id="AssessmentsPage"
1859
+ href="/#TopNavBar"
1860
+ >
1861
+ Assessments
1862
+ </TopNavBar.Item>
1863
+ <TopNavBar.Item
1864
+ id="CommunityPage"
1865
+ href="/#TopNavBar"
1866
+ >
1867
+ Community
1868
+ </TopNavBar.Item>
1869
+ </TopNavBar.MenuItems>
1870
+ }
1871
+ renderActionItems={
1872
+ <TopNavBar.ActionItems
1873
+ listLabel="Actions"
1874
+ renderHiddenItemsMenuTriggerLabel={(
1875
+ hiddenChildrenCount
1876
+ ) => `${hiddenChildrenCount} more actions`}
1877
+ >
1878
+ <TopNavBar.Item
1879
+ id="InfoAction3"
1880
+ variant="icon"
1881
+ tooltip="Info"
1882
+ renderIcon={<IconQuestionLine />}
1883
+ onClick={() => {
1884
+ console.log('Info')
1885
+ }}
1886
+ >
1887
+ Info
1888
+ </TopNavBar.Item>
1889
+ <TopNavBar.Item
1890
+ id="AlertsAction3"
1891
+ variant="icon"
1892
+ tooltip="Alerts"
1893
+ renderIcon={<IconAlertsLine />}
1894
+ onClick={() => {
1895
+ console.log('Alerts')
1896
+ }}
1897
+ >
1898
+ Alerts
1899
+ </TopNavBar.Item>
1900
+ </TopNavBar.ActionItems>
1901
+ }
1902
+ renderUser={
1903
+ <TopNavBar.User>
1904
+ <TopNavBar.Item
1905
+ id="LogInRegisterButton5"
1906
+ href="/#TopNavBar"
1907
+ variant="button"
1908
+ >
1909
+ Log In/Register
1910
+ </TopNavBar.Item>
1911
+ </TopNavBar.User>
1912
+ }
1913
+ themeOverride={{
1914
+ // For example demo
1915
+ smallViewportZIndex: 9999,
1916
+ smallViewportTrayFixTopPosition: this.state.isSecondaryNavigation
1917
+ ? `57px`
1918
+ : '56px'
1919
+ }}
1920
+ />
1921
+ )
1922
+ }}
1923
+ </TopNavBar>
1924
+
1925
+ <div
1926
+ id="menuMountNode"
1927
+ style={{
1928
+ position: 'absolute',
1929
+ insetBlockStart: this.state.isSecondaryNavigation
1930
+ ? 'calc(3.5rem + 1px)'
1931
+ : '3.5rem',
1932
+ insetInlineStart: '0px',
1933
+ width: '100%',
1934
+ height: this.state.isSecondaryNavigation
1935
+ ? 'calc(100% - 3.5rem - 1px)'
1936
+ : 'calc(100% - 3.5rem)',
1937
+ }}
1938
+ />
1939
+
1940
+ <View as="div" minHeight='10rem' padding="medium">
1941
+ <Heading as="p" level="h2" margin="medium 0">
1942
+ Page Content
1943
+ </Heading>
1944
+
1945
+ <p>
1946
+ Reprehenderit magna aliquip laboris nostrud. Culpa aliqua ex laboris pariatur quis laboris ipsum culpa quis aliquip nisi veniam consectetur amet. Cillum dolore officia irure est velit.
1947
+ </p>
1948
+ <p>
1949
+ Mollit laboris anim dolor amet mollit ut in duis quis anim. Minim sit aute laborum sunt ad veniam. Labore id in enim labore culpa. Ullamco irure magna enim excepteur nulla incididunt laboris. Dolor quis duis Lorem ad. Veniam non eu nisi labore duis est quis. Laborum aute quis velit reprehenderit consequat esse qui tempor ad in et voluptate.
1950
+ </p>
1951
+ <p>
1952
+ Irure velit duis amet pariatur anim nostrud sit magna anim non do ea exercitation. Adipisicing veniam culpa do nostrud nisi. Do aliqua cupidatat ad fugiat labore ad non fugiat. Laboris et tempor sunt velit incididunt sunt enim occaecat do aliquip nulla magna.
1953
+ </p>
1954
+ </View>
1955
+ </div>
1956
+
1957
+ </View>
1958
+ </View>
1959
+ )
1960
+ }
1961
+ }
1962
+
1963
+ render(<LayoutExample />)
1964
+ ```
1965
+
1966
+ #### Secondary navigation
1967
+
1968
+ In case TopNavBar is used as secondary navigation (e.g. LTI tools menu in Canvas), use the inverse color version. The `inverseColor` prop displays the navbar with inverted colors.
1969
+
1970
+ In the smallViewport layout of the "secodary navigation" mode, don’t show the branding, instead display the current/selected page title by passing the `smallViewportConfig.alternativeTitle` prop. See the example above (toggle secondary navigation mode).
1971
+
1972
+ ### Items
1973
+
1974
+ The main building block of TopNavBar is the `<TopNavBar.Item>`. The items have 4 variants, can have icons, avatars, submenus, tooltips, etc.
1975
+
1976
+ #### Variants
1977
+
1978
+ The items can display as text, button, icon only or avatar only. The text and button versions can have icons and avatars, and all variants can have submenus, popovers and tooltips.
1979
+
1980
+ Not all 4 variation are available in every container, e.g.: items with avatars can only be used in `<TopNavBar.User>`.
1981
+
1982
+ In small viewport mode, items in `<TopNavBar.User>` and `<TopNavBar.MenuItems>` will be converted to dropdown menu items ([Drilldown](#Drilldown) options), thus displaying differently (e.g.: all variants display as text options and icons are not rendered). The items in `<TopNavBar.ActionItems>` will be converted to `icon` variants (and are required to have `renderIcon` prop), and the list will get truncated when there is not enough space to display all actions.
1983
+
1984
+ ```js
1985
+ ---
1986
+ example: true
1987
+ ---
1988
+
1989
+ <View as="div" background="primary-inverse" padding="medium">
1990
+ <Flex wrap="wrap">
1991
+ <Flex.Item padding="small">
1992
+ <TopNavBar.Item
1993
+ id="defaultText"
1994
+ >
1995
+ Default variant
1996
+ </TopNavBar.Item>
1997
+ </Flex.Item>
1998
+ <Flex.Item padding="small">
1999
+ <TopNavBar.Item
2000
+ id="defaultIcon"
2001
+ renderIcon={<IconDiscussionLine />}
2002
+ >
2003
+ Default with icon
2004
+ </TopNavBar.Item>
2005
+ </Flex.Item>
2006
+ <Flex.Item padding="small">
2007
+ <TopNavBar.Item
2008
+ id="defaultAvatar"
2009
+ renderAvatar={{ avatarName: 'User Name', avatarSrc: avatarSquare }}
2010
+ >
2011
+ Default with avatar
2012
+ </TopNavBar.Item>
2013
+ </Flex.Item>
2014
+ </Flex>
2015
+
2016
+ <Flex wrap="wrap">
2017
+ <Flex.Item padding="small">
2018
+ <TopNavBar.Item
2019
+ id="buttonText"
2020
+ variant="button"
2021
+ >
2022
+ Button variant
2023
+ </TopNavBar.Item>
2024
+ </Flex.Item>
2025
+ <Flex.Item padding="small">
2026
+ <TopNavBar.Item
2027
+ id="buttonIcon"
2028
+ variant="button"
2029
+ renderIcon={<IconDiscussionLine />}
2030
+ >
2031
+ Button with icon
2032
+ </TopNavBar.Item>
2033
+ </Flex.Item>
2034
+ <Flex.Item padding="small">
2035
+ <TopNavBar.Item
2036
+ id="buttonAvatar"
2037
+ variant="button"
2038
+ renderAvatar={{ avatarName: 'User Name', avatarSrc: avatarSquare }}
2039
+ >
2040
+ Button with avatar
2041
+ </TopNavBar.Item>
2042
+ </Flex.Item>
2043
+ </Flex>
2044
+
2045
+ <Flex wrap="wrap">
2046
+ <Flex.Item padding="small">
2047
+ <TopNavBar.Item
2048
+ id="iconItem"
2049
+ variant="icon"
2050
+ renderIcon={<IconDiscussionLine />}
2051
+ tooltip="Icon variant"
2052
+ >
2053
+ Icon variant
2054
+ </TopNavBar.Item>
2055
+ </Flex.Item>
2056
+ </Flex>
2057
+
2058
+ <Flex wrap="wrap">
2059
+ <Flex.Item padding="small">
2060
+ <TopNavBar.Item
2061
+ id="avatarItem"
2062
+ variant="avatar"
2063
+ renderAvatar={{ avatarName: 'User Name', avatarSrc: avatarSquare }}
2064
+ tooltip="Avatar variant"
2065
+ >
2066
+ Avatar variant
2067
+ </TopNavBar.Item>
2068
+ </Flex.Item>
2069
+ </Flex>
2070
+ </View>
2071
+ ```
2072
+
2073
+ #### Dropdowns
2074
+
2075
+ `<TopNavBar.Item>` can display 3 type of dropdowns.
2076
+
2077
+ ##### Submenu
2078
+
2079
+ The most common use case is when we want to open a submenu by clicking on the item. The `renderSubmenu` prop accepts a [Drilldown](#Drilldown) component, and the toggle logic is handled by `TopNavBar.Item`. The submenu can have multiple levels.
2080
+
2081
+ ##### Custom Popover
2082
+
2083
+ If custom content needs to be displayed in the dropdown (e.g. search feature), use the `customPopoverConfig` prop. It accepts a config object of [Popover](#Popover) component props (except `renderTrigger`, since the item itself is the trigger).
2084
+
2085
+ **Note**: in "smallViewport" mode items in `TopNavBar.ActionItems` can display custom popovers, but since the items in `TopNavBar.MenuItems` are converted to Drilldown options, custom popovers are not recommended to use in menu items.
2086
+
2087
+ ##### Tooltip
2088
+
2089
+ The `tooltip` prop can display extra information on hover/focus. Tooltips can be useful for `variant="icon"` or `variant="avatar"` type menu items where there is no visible text.
2090
+
2091
+ It accepts either a string or a config object containing a subset of props from [Tooltip](#Tooltip).
2092
+
2093
+ **Note**: items rendered as Drilldown options don't render tooltips.
2094
+
2095
+ ```js
2096
+ ---
2097
+ example: true
2098
+ ---
2099
+
2100
+ <div>
2101
+ <View as="div" margin="medium 0">
2102
+ <TopNavBar breakpoint="10rem">
2103
+ {() => (
2104
+ <TopNavBar.Layout
2105
+ navLabel="Example navigation bar"
2106
+ desktopConfig={{
2107
+ hideActionsUserSeparator: false
2108
+ }}
2109
+ smallViewportConfig={{
2110
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
2111
+ dropdownMenuLabel: 'Main Menu',
2112
+ }}
2113
+ renderMenuItems={(
2114
+ <TopNavBar.MenuItems
2115
+ listLabel="Page navigation"
2116
+ renderHiddenItemsMenuTriggerLabel={(
2117
+ hiddenChildrenCount
2118
+ ) => `${hiddenChildrenCount} More`}
2119
+ >
2120
+ <TopNavBar.Item
2121
+ id="itemSubmenuExample"
2122
+ renderSubmenu={(
2123
+ <Drilldown rootPageId="root">
2124
+ <Drilldown.Page id="root">
2125
+ <Drilldown.Option id="rootOption1" subPageId="secondPage">
2126
+ Link One
2127
+ </Drilldown.Option>
2128
+ <Drilldown.Option id="rootOption2" href="/#TopNavBar">
2129
+ Link Two
2130
+ </Drilldown.Option>
2131
+ <Drilldown.Option id="rootOption3" href="/#TopNavBar">
2132
+ Link Three
2133
+ </Drilldown.Option>
2134
+ </Drilldown.Page>
2135
+ <Drilldown.Page id="secondPage">
2136
+ <Drilldown.Option id="secondPageOption1">
2137
+ Level 2 Option One
2138
+ </Drilldown.Option>
2139
+ <Drilldown.Option id="secondPageOption2" href="/#TopNavBar">
2140
+ Level 2 Option Two
2141
+ </Drilldown.Option>
2142
+ </Drilldown.Page>
2143
+ </Drilldown>
2144
+ )}
2145
+ >
2146
+ Menu Item with submenu
2147
+ </TopNavBar.Item>
2148
+ </TopNavBar.MenuItems>
2149
+ )}
2150
+ renderActionItems={(
2151
+ <TopNavBar.ActionItems
2152
+ listLabel="Actions"
2153
+ renderHiddenItemsMenuTriggerLabel={(
2154
+ hiddenChildrenCount
2155
+ ) => `${hiddenChildrenCount} More`}
2156
+ >
2157
+ <TopNavBar.Item
2158
+ id="itemTooltipExample"
2159
+ variant="icon"
2160
+ tooltip={{
2161
+ renderTip: "Settings action",
2162
+ placement: 'bottom end',
2163
+ }}
2164
+ renderIcon={<IconSettingsLine />}
2165
+ >
2166
+ Action Item with tooltip
2167
+ </TopNavBar.Item>
2168
+ <TopNavBar.Item
2169
+ id="itemPopoverExample"
2170
+ variant="icon"
2171
+ showSubmenuChevron={false}
2172
+ tooltip="Open for Content info"
2173
+ renderIcon={<IconQuestionLine />}
2174
+ customPopoverConfig={{
2175
+ on: 'click',
2176
+ placement: 'bottom end',
2177
+ shouldContainFocus: true,
2178
+ children: (
2179
+ <View
2180
+ as="div"
2181
+ padding="medium"
2182
+ width="25rem"
2183
+ role="dialog"
2184
+ tabIndex={0}
2185
+ aria-label="Contact information"
2186
+ position="relative"
2187
+ borderRadius="small"
2188
+ >
2189
+ <Heading level="h3">Contact information</Heading>
2190
+ <p>{lorem.sentence()}</p>
2191
+ <Button color="primary" margin="x-small 0 small">Help Center</Button>
2192
+ <hr aria-hidden="true" />
2193
+ <View as="div" margin="medium 0 0">
2194
+ <Text weight="bold">
2195
+ <div>Contact person</div>
2196
+ <Link href="/#TopNavBar" isWithinText={false}>
2197
+ contact.person@example.com
2198
+ </Link>
2199
+ <div>(801) 123-4567</div>
2200
+ </Text>
2201
+ </View>
2202
+ </View>
2203
+ )
2204
+ }}
2205
+ >
2206
+ Action Item with popover
2207
+ </TopNavBar.Item>
2208
+ </TopNavBar.ActionItems>
2209
+ )}
2210
+ />
2211
+ )}
2212
+ </TopNavBar>
2213
+ </View>
2214
+ </div>
2215
+ ```
2216
+
2217
+ ##### Full width dialog on small viewports
2218
+
2219
+ In "smallViewport" mode, due to the lack of space, some features might be rendered in a special dialog that covers the whole navbar (e.g.: search feature).
2220
+
2221
+ This feature is settable via the `smallViewportConfig.renderInPlaceDialogConfig` prop of `TopNavBar.Layout`, and accepts a config object. It can also trap focus.
2222
+
2223
+ **Note**: please make sure to set an element to return the focus to upon closing the dialog via the `returnFocusElement` prop.
2224
+
2225
+ ```js
2226
+ ---
2227
+ example: true
2228
+ render: false
2229
+ ---
2230
+
2231
+ class InPlaceDialogExample extends React.Component {
2232
+ state = {
2233
+ isSearchOpen: false,
2234
+ searchInputValue: ''
2235
+ }
2236
+
2237
+ toggleSearch(isOpen) {
2238
+ this.setState({ isSearchOpen: isOpen })
2239
+ }
2240
+
2241
+ render() {
2242
+ return (
2243
+ <View as="div" margin="medium 0" maxWidth="29rem">
2244
+ <TopNavBar breakpoint="30rem" mediaQueryMatch="element">
2245
+ {({ currentLayout }) => (
2246
+ <TopNavBar.Layout
2247
+ navLabel="Example navigation bar"
2248
+ desktopConfig={{
2249
+ hideActionsUserSeparator: false
2250
+ }}
2251
+ smallViewportConfig={{
2252
+ dropdownMenuToggleButtonLabel: 'Toggle Menu',
2253
+ dropdownMenuLabel: 'Main Menu',
2254
+ renderInPlaceDialogConfig: {
2255
+ open: this.state.isSearchOpen,
2256
+ onClose: () => {
2257
+ this.toggleSearch(false)
2258
+ },
2259
+ closeButtonLabel: 'Close Search and return to Navigation',
2260
+ returnFocusElement: () =>
2261
+ document.getElementById('Search'),
2262
+ shouldCloseOnEscape: true,
2263
+ shouldCloseOnDocumentClick: false,
2264
+ shouldContainFocus: false,
2265
+ content: ({ closeInPlaceDialog }) => (
2266
+ <View as="div" padding="x-small">
2267
+ <TextInput
2268
+ id="searchInput"
2269
+ width="100%"
2270
+ display="block"
2271
+ renderLabel={<ScreenReaderContent>Search</ScreenReaderContent>}
2272
+ renderBeforeInput={() => <IconSearchLine inline={false} />}
2273
+ placeholder="Search..."
2274
+ onChange={(_event, value) => {
2275
+ this.setState({ searchInputValue: value })
2276
+ }}
2277
+ value={this.state.searchInputValue}
2278
+ onKeyDown={(event) => {
2279
+ if (event.key === 'Enter') {
2280
+ event.preventDefault()
2281
+ event.stopPropagation()
2282
+
2283
+ console.log(`Search input submitted value "${this.state.searchInputValue}".`)
2284
+
2285
+ this.setState({ searchInputValue: '' })
2286
+
2287
+ if (currentLayout === 'smallViewport' && typeof closeInPlaceDialog === 'function') {
2288
+ closeInPlaceDialog()
2289
+ }
2290
+ }
2291
+ }}
2292
+ themeOverride={(_theme, globalTheme) => ({
2293
+ focusOutlineColor: globalTheme.colors.borderLightest
2294
+ })}
2295
+ />
2296
+ </View>
2297
+ )
2298
+ }
2299
+ }}
2300
+ renderActionItems={(
2301
+ <TopNavBar.ActionItems
2302
+ listLabel="Actions"
2303
+ renderHiddenItemsMenuTriggerLabel={(
2304
+ hiddenChildrenCount
2305
+ ) => `${hiddenChildrenCount} More`}
2306
+ >
2307
+ <TopNavBar.Item
2308
+ id="Search2"
2309
+ renderIcon={<IconSearchLine />}
2310
+ tooltip="Opens search dialog"
2311
+ onClick={() => {
2312
+ this.toggleSearch(true)
2313
+ }}
2314
+ >
2315
+ Search
2316
+ </TopNavBar.Item>
2317
+ </TopNavBar.ActionItems>
2318
+ )}
2319
+ />
2320
+ )}
2321
+ </TopNavBar>
2322
+ </View>
2323
+ )
2324
+ }
2325
+ }
2326
+
2327
+ render(<InPlaceDialogExample />)
2328
+
2329
+ ```