@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,600 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ /** @jsx jsx */
26
+ import React, { Component } from 'react'
27
+
28
+ import {
29
+ omitProps,
30
+ withDeterministicId,
31
+ callRenderProp
32
+ } from '@instructure/ui-react-utils'
33
+ import { px } from '@instructure/ui-utils'
34
+ import { warn } from '@instructure/console'
35
+ import { testable } from '@instructure/ui-testable'
36
+ import {
37
+ getBoundingClientRect,
38
+ requestAnimationFrame
39
+ } from '@instructure/ui-dom-utils'
40
+ import type { RequestAnimationFrameType } from '@instructure/ui-dom-utils'
41
+
42
+ import { withStyle, jsx, Global } from '@instructure/emotion'
43
+
44
+ import { Tray } from '@instructure/ui-tray'
45
+ import {
46
+ IconXLine,
47
+ IconHamburgerLine,
48
+ IconArrowOpenDownSolid,
49
+ IconArrowOpenUpSolid
50
+ } from '@instructure/ui-icons'
51
+ import { Avatar } from '@instructure/ui-avatar'
52
+ import { Dialog } from '@instructure/ui-dialog'
53
+ import { Drilldown } from '@instructure/ui-drilldown'
54
+ import type { DrilldownPageChildren } from '@instructure/ui-drilldown'
55
+
56
+ import { TopNavBarItem } from '../../TopNavBarItem'
57
+ import type { ItemChild, TopNavBarItemProps } from '../../TopNavBarItem/props'
58
+ import {
59
+ mapItemsForDrilldown,
60
+ renderMappedItemDrilldownSubpages,
61
+ renderMappedItemsAsDrilldownOptions
62
+ } from '../../utils/mapItemsForDrilldown'
63
+ import type { RenderOptionContent } from '../../utils/mapItemsForDrilldown'
64
+
65
+ import { TopNavBarContext } from '../../TopNavBarContext'
66
+
67
+ import generateStyle from './styles'
68
+ import generateComponentTheme from './theme'
69
+
70
+ import { propTypes, allowedProps } from './props'
71
+ import type {
72
+ TopNavBarSmallViewportLayoutProps,
73
+ TopNavBarSmallViewportLayoutState,
74
+ TopNavBarSmallViewportLayoutStyleProps
75
+ } from './props'
76
+
77
+ /**
78
+ ---
79
+ private: true
80
+ ---
81
+ @tsProps
82
+ **/
83
+ @withDeterministicId()
84
+ @withStyle(generateStyle, generateComponentTheme)
85
+ @testable()
86
+ class TopNavBarSmallViewportLayout extends Component<
87
+ TopNavBarSmallViewportLayoutProps,
88
+ TopNavBarSmallViewportLayoutState
89
+ > {
90
+ static readonly componentId = 'TopNavBar.SmallViewportLayout'
91
+
92
+ static propTypes = propTypes
93
+ static allowedProps = allowedProps
94
+ static defaultProps = {}
95
+
96
+ declare context: React.ContextType<typeof TopNavBarContext>
97
+ static contextType = TopNavBarContext
98
+
99
+ ref: HTMLElement | null = null
100
+
101
+ private readonly _trayContainerId: string
102
+ private readonly _trayId: string
103
+ private readonly _drilldownId: string
104
+ private readonly _menuTriggerId: string
105
+ private readonly _menuId: string
106
+ private readonly _inPlaceDialogId: string
107
+ private readonly _inPlaceDialogCloseButtonId: string
108
+ private readonly _separatorId: string
109
+
110
+ private _raf: RequestAnimationFrameType[] = []
111
+
112
+ handleRef = (el: HTMLElement | null) => {
113
+ const { elementRef } = this.props
114
+
115
+ this.ref = el
116
+
117
+ if (typeof elementRef === 'function') {
118
+ elementRef(el)
119
+ }
120
+ }
121
+
122
+ constructor(props: TopNavBarSmallViewportLayoutProps) {
123
+ super(props)
124
+
125
+ this._trayContainerId = props.deterministicId!(
126
+ 'TopNavBarSmallViewportLayout-trayContainer'
127
+ )
128
+ this._trayId = props.deterministicId!('TopNavBarSmallViewportLayout-tray')
129
+ this._menuId = props.deterministicId!('TopNavBarSmallViewportLayout-menu')
130
+ this._menuTriggerId = props.deterministicId!(
131
+ 'TopNavBarSmallViewportLayout-menuTrigger'
132
+ )
133
+ this._drilldownId = props.deterministicId!(
134
+ 'TopNavBarSmallViewportLayout-drilldown'
135
+ )
136
+ this._inPlaceDialogId = props.deterministicId!(
137
+ 'TopNavBarSmallViewportLayout-inPlaceDialog'
138
+ )
139
+ this._inPlaceDialogCloseButtonId = props.deterministicId!(
140
+ 'TopNavBarSmallViewportLayout-inPlaceDialogCloseButton'
141
+ )
142
+ this._separatorId = props.deterministicId!(
143
+ 'TopNavBarSmallViewportLayout-separator'
144
+ )
145
+
146
+ this.state = {
147
+ isDropdownMenuOpen: false,
148
+ isDropdownMenuVisible: false,
149
+ menuBottomPosition: px(props.styles?.navbarHeight || 0)
150
+ }
151
+ }
152
+
153
+ componentDidMount() {
154
+ this.props.makeStyles?.(this.makeStylesVariables)
155
+ this.updateMenuBottomPosition()
156
+ }
157
+
158
+ componentDidUpdate() {
159
+ this.props.makeStyles?.(this.makeStylesVariables)
160
+ }
161
+
162
+ componentWillUnmount() {
163
+ this._raf.forEach((request) => request.cancel())
164
+ }
165
+
166
+ get makeStylesVariables(): TopNavBarSmallViewportLayoutStyleProps {
167
+ return {
168
+ isDropdownMenuVisible: this.state.isDropdownMenuVisible,
169
+ drilldownId: this._drilldownId,
170
+ trayId: this._trayId,
171
+ menuBottomPosition: this.state.menuBottomPosition,
172
+ inverseColor: this.context.inverseColor
173
+ }
174
+ }
175
+
176
+ hasBrandBlock(
177
+ renderBrand: TopNavBarSmallViewportLayoutProps['renderBrand']
178
+ ): renderBrand is NonNullable<
179
+ TopNavBarSmallViewportLayoutProps['renderBrand']
180
+ > {
181
+ return (
182
+ !!renderBrand &&
183
+ (!!renderBrand.props.renderName || !!renderBrand.props.renderIcon)
184
+ )
185
+ }
186
+
187
+ hasMenuItemsBlock(
188
+ renderMenuItems: TopNavBarSmallViewportLayoutProps['renderMenuItems']
189
+ ): renderMenuItems is NonNullable<
190
+ TopNavBarSmallViewportLayoutProps['renderMenuItems']
191
+ > {
192
+ return (
193
+ !!renderMenuItems &&
194
+ React.Children.count(renderMenuItems.props.children) > 0
195
+ )
196
+ }
197
+
198
+ hasActionItemsBlock(
199
+ renderActionItems: TopNavBarSmallViewportLayoutProps['renderActionItems']
200
+ ): renderActionItems is NonNullable<
201
+ TopNavBarSmallViewportLayoutProps['renderActionItems']
202
+ > {
203
+ return (
204
+ !!renderActionItems &&
205
+ React.Children.count(renderActionItems.props.children) > 0
206
+ )
207
+ }
208
+
209
+ hasUserBlock(
210
+ renderUser: TopNavBarSmallViewportLayoutProps['renderUser']
211
+ ): renderUser is NonNullable<
212
+ TopNavBarSmallViewportLayoutProps['renderUser']
213
+ > {
214
+ return !!renderUser && React.Children.count(renderUser.props.children) > 0
215
+ }
216
+
217
+ get hasSubmenu() {
218
+ return (this.dropdownMenuContent || []).length > 0
219
+ }
220
+
221
+ get isInPlaceDialogOpen() {
222
+ return this.props.renderInPlaceDialogConfig?.open
223
+ }
224
+
225
+ get mappedUserOptions() {
226
+ const { renderUser } = this.props
227
+
228
+ if (!this.hasUserBlock(renderUser)) {
229
+ return []
230
+ }
231
+
232
+ const userChildren = React.Children.toArray(
233
+ renderUser.props.children
234
+ ) as ItemChild[]
235
+
236
+ return mapItemsForDrilldown(userChildren, {
237
+ renderOptionContent: this.renderOptionContent
238
+ })
239
+ }
240
+
241
+ get mappedMenuItemsOptions() {
242
+ const { renderMenuItems } = this.props
243
+
244
+ if (!this.hasMenuItemsBlock(renderMenuItems)) {
245
+ return []
246
+ }
247
+
248
+ const menuItemsChildren = React.Children.toArray(
249
+ renderMenuItems.props.children
250
+ ) as ItemChild[]
251
+
252
+ return mapItemsForDrilldown(menuItemsChildren, {
253
+ renderOptionContent: this.renderOptionContent,
254
+ currentPageId: renderMenuItems.props.currentPageId
255
+ })
256
+ }
257
+
258
+ get extractDrilldownSubpages() {
259
+ return renderMappedItemDrilldownSubpages([
260
+ ...this.mappedUserOptions,
261
+ ...this.mappedMenuItemsOptions
262
+ ])
263
+ }
264
+
265
+ updateMenuBottomPosition() {
266
+ const boundingRect = getBoundingClientRect(this.ref)
267
+ this.setState({
268
+ menuBottomPosition: boundingRect.top + boundingRect.height
269
+ })
270
+ }
271
+
272
+ toggleDropdownMenu() {
273
+ const { onDropdownMenuToggle } = this.props
274
+ const { isDropdownMenuOpen } = this.state
275
+
276
+ if (!isDropdownMenuOpen) {
277
+ this.updateMenuBottomPosition()
278
+ }
279
+
280
+ if (typeof onDropdownMenuToggle === 'function') {
281
+ onDropdownMenuToggle(!isDropdownMenuOpen)
282
+ }
283
+
284
+ this.setState({ isDropdownMenuOpen: !isDropdownMenuOpen })
285
+ }
286
+
287
+ renderOptionContent: RenderOptionContent = (children, itemProps) => {
288
+ const { styles } = this.props
289
+ const { status, renderAvatar } = itemProps
290
+
291
+ let content = children
292
+ let optionStyle =
293
+ status === 'active'
294
+ ? styles?.dropdownMenuOptionActive
295
+ : styles?.dropdownMenuOption
296
+
297
+ if (renderAvatar) {
298
+ const { avatarName, avatarSrc, avatarAlt } = renderAvatar
299
+
300
+ const label =
301
+ avatarAlt ||
302
+ (typeof children === 'string' ? (children as string) : undefined)
303
+
304
+ optionStyle = styles?.dropdownMenuOptionWithAvatar
305
+
306
+ content = (
307
+ <React.Fragment>
308
+ <Avatar
309
+ name={avatarName}
310
+ src={avatarSrc}
311
+ alt={label}
312
+ size="small"
313
+ margin="0 small 0 0"
314
+ role="presentation"
315
+ aria-hidden="true"
316
+ />
317
+ {children}
318
+ </React.Fragment>
319
+ )
320
+ }
321
+
322
+ return <span css={optionStyle}>{content}</span>
323
+ }
324
+
325
+ renderMenuTrigger() {
326
+ const {
327
+ dropdownMenuToggleButtonLabel,
328
+ dropdownMenuToggleButtonTooltip,
329
+ renderBrand,
330
+ alternativeTitle,
331
+ styles
332
+ } = this.props
333
+ const { isDropdownMenuOpen } = this.state
334
+
335
+ let menuTrigger: React.ReactNode
336
+
337
+ const menuTriggerStyle = [
338
+ styles?.menuTrigger,
339
+ ...(alternativeTitle ? [styles?.alternativeTitleContainer] : [])
340
+ ]
341
+
342
+ if (!this.hasSubmenu) {
343
+ menuTrigger = null
344
+
345
+ if (alternativeTitle) {
346
+ warn(
347
+ false,
348
+ 'There are no menu items or user menu to display in the <TopNavBar> dropdown menu! The menu trigger and the alternative title will not display.'
349
+ )
350
+ }
351
+ } else {
352
+ const itemProps: Omit<TopNavBarItemProps, 'children'> = {
353
+ id: this._menuTriggerId,
354
+ onClick: () => {
355
+ this.toggleDropdownMenu()
356
+ },
357
+ tooltip: dropdownMenuToggleButtonTooltip,
358
+ themeOverride: { itemSpacing: '0.375rem' },
359
+ 'aria-haspopup': 'menu',
360
+ 'aria-expanded': isDropdownMenuOpen
361
+ }
362
+
363
+ const alternativeTitleIconProps = {
364
+ size: 'x-small' as const,
365
+ style: { marginInlineEnd: '0.5em' }
366
+ }
367
+
368
+ menuTrigger = (
369
+ <div css={menuTriggerStyle}>
370
+ {alternativeTitle ? (
371
+ <TopNavBarItem
372
+ {...itemProps}
373
+ aria-label={dropdownMenuToggleButtonLabel}
374
+ >
375
+ {isDropdownMenuOpen ? (
376
+ <IconArrowOpenUpSolid {...alternativeTitleIconProps} />
377
+ ) : (
378
+ <IconArrowOpenDownSolid {...alternativeTitleIconProps} />
379
+ )}
380
+ {alternativeTitle}
381
+ </TopNavBarItem>
382
+ ) : (
383
+ <TopNavBarItem
384
+ {...itemProps}
385
+ variant="icon"
386
+ renderIcon={
387
+ isDropdownMenuOpen ? <IconXLine /> : <IconHamburgerLine />
388
+ }
389
+ >
390
+ {dropdownMenuToggleButtonLabel}
391
+ </TopNavBarItem>
392
+ )}
393
+ </div>
394
+ )
395
+ }
396
+
397
+ return (
398
+ <div css={styles?.menuTriggerContainer}>
399
+ {menuTrigger}
400
+
401
+ {this.hasBrandBlock(renderBrand) && !alternativeTitle && (
402
+ <div css={styles?.brandContainer}>{renderBrand}</div>
403
+ )}
404
+ </div>
405
+ )
406
+ }
407
+
408
+ get dropdownMenuContent() {
409
+ const { renderUser, renderMenuItems } = this.props
410
+ const hasMenuItems = this.hasMenuItemsBlock(renderMenuItems)
411
+ const hasUser = this.hasUserBlock(renderUser)
412
+
413
+ let pageChildren: DrilldownPageChildren[] = []
414
+
415
+ if (hasUser) {
416
+ pageChildren = renderMappedItemsAsDrilldownOptions(this.mappedUserOptions)
417
+
418
+ if (hasMenuItems) {
419
+ pageChildren.push(
420
+ <Drilldown.Separator id={this._separatorId} key={this._separatorId} />
421
+ )
422
+ }
423
+ }
424
+
425
+ if (hasMenuItems) {
426
+ pageChildren = [
427
+ ...pageChildren,
428
+ ...renderMappedItemsAsDrilldownOptions(this.mappedMenuItemsOptions)
429
+ ]
430
+ }
431
+
432
+ return pageChildren.length ? pageChildren : undefined
433
+ }
434
+
435
+ renderDropdownMenu() {
436
+ const { dropdownMenuLabel, onDropdownMenuSelect } = this.props
437
+
438
+ return (
439
+ <Drilldown
440
+ id={this._drilldownId}
441
+ rootPageId={this._menuId}
442
+ label={dropdownMenuLabel}
443
+ height="100%"
444
+ width="100%"
445
+ onSelect={(e, args) => {
446
+ if (typeof onDropdownMenuSelect === 'function') {
447
+ onDropdownMenuSelect(e, args)
448
+ }
449
+
450
+ if (args.selectedOption.props.href) {
451
+ this.toggleDropdownMenu()
452
+ }
453
+ }}
454
+ >
455
+ {[
456
+ <Drilldown.Page id={this._menuId} key={this._menuId}>
457
+ {this.dropdownMenuContent}
458
+ </Drilldown.Page>,
459
+ ...this.extractDrilldownSubpages
460
+ ]}
461
+ </Drilldown>
462
+ )
463
+ }
464
+
465
+ renderDropdownMenuTray() {
466
+ const { trayMountNode } = this.props
467
+
468
+ if (!this.hasSubmenu) {
469
+ return null
470
+ }
471
+
472
+ return (
473
+ <Tray
474
+ id={this._trayId}
475
+ label={''}
476
+ role="none"
477
+ open={this.state.isDropdownMenuOpen}
478
+ transitionExit={false}
479
+ onDismiss={() => {
480
+ this.toggleDropdownMenu()
481
+ }}
482
+ onKeyUp={(e) => {
483
+ if (e.key === 'Escape') {
484
+ this.toggleDropdownMenu()
485
+ }
486
+ }}
487
+ onEnter={() => {
488
+ this.setState({ isDropdownMenuVisible: true })
489
+ }}
490
+ onExited={() => {
491
+ this.setState({ isDropdownMenuVisible: false })
492
+ }}
493
+ shouldCloseOnDocumentClick
494
+ placement="top"
495
+ shadow={false}
496
+ mountNode={
497
+ trayMountNode || document.getElementById(this._trayContainerId)
498
+ }
499
+ defaultFocusElement={() => document.getElementById(this._drilldownId)}
500
+ themeOverride={{ position: 'absolute' }}
501
+ >
502
+ {this.renderDropdownMenu()}
503
+ </Tray>
504
+ )
505
+ }
506
+
507
+ renderInPlaceDialog() {
508
+ const { renderInPlaceDialogConfig, styles } = this.props
509
+
510
+ if (!renderInPlaceDialogConfig) {
511
+ return null
512
+ }
513
+
514
+ const {
515
+ content,
516
+ open,
517
+ onClose,
518
+ closeButtonLabel,
519
+ shouldContainFocus,
520
+ shouldCloseOnEscape,
521
+ shouldCloseOnDocumentClick,
522
+ returnFocusElement
523
+ } = renderInPlaceDialogConfig
524
+
525
+ const handleClose = () => {
526
+ if (typeof onClose === 'function') {
527
+ onClose()
528
+ }
529
+
530
+ if (returnFocusElement) {
531
+ this._raf.push(
532
+ requestAnimationFrame(() => {
533
+ returnFocusElement()?.focus()
534
+ })
535
+ )
536
+ }
537
+ }
538
+
539
+ const dialog = (
540
+ <Dialog
541
+ display="block"
542
+ open={open}
543
+ shouldContainFocus={shouldContainFocus}
544
+ shouldCloseOnEscape={shouldCloseOnEscape}
545
+ shouldCloseOnDocumentClick={shouldCloseOnDocumentClick}
546
+ onDismiss={handleClose}
547
+ >
548
+ <div id={this._inPlaceDialogId} css={styles?.inPlaceDialogContainer}>
549
+ <div css={styles?.inPlaceDialogContainerContent}>
550
+ {callRenderProp(content, { closeInPlaceDialog: handleClose })}
551
+ </div>
552
+ <div css={styles?.inPlaceDialogContainerButton}>
553
+ <TopNavBarItem
554
+ id={this._inPlaceDialogCloseButtonId}
555
+ renderIcon={IconXLine}
556
+ variant="icon"
557
+ onClick={handleClose}
558
+ >
559
+ {closeButtonLabel}
560
+ </TopNavBarItem>
561
+ </div>
562
+ </div>
563
+ </Dialog>
564
+ )
565
+
566
+ return dialog
567
+ }
568
+
569
+ render() {
570
+ const { trayMountNode, navLabel, renderActionItems, styles } = this.props
571
+
572
+ return (
573
+ <nav
574
+ {...omitProps(this.props, allowedProps)}
575
+ ref={this.handleRef}
576
+ aria-label={navLabel}
577
+ >
578
+ <Global styles={styles?.globalStyles} />
579
+
580
+ {!this.isInPlaceDialogOpen && (
581
+ <div css={styles?.navbar}>
582
+ {this.renderMenuTrigger()}
583
+ {this.hasActionItemsBlock(renderActionItems) && renderActionItems}
584
+ </div>
585
+ )}
586
+
587
+ {this.renderInPlaceDialog()}
588
+
589
+ {!trayMountNode && (
590
+ <div css={styles?.trayContainer} id={this._trayContainerId} />
591
+ )}
592
+
593
+ {this.renderDropdownMenuTray()}
594
+ </nav>
595
+ )
596
+ }
597
+ }
598
+
599
+ export { TopNavBarSmallViewportLayout }
600
+ export default TopNavBarSmallViewportLayout