@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.
- package/CHANGELOG.md +57 -0
- package/README.md +30 -0
- package/es/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.js +47 -0
- package/es/TopNavBar/TopNavBarActionItems/index.js +215 -0
- package/es/TopNavBar/TopNavBarActionItems/props.js +36 -0
- package/es/TopNavBar/TopNavBarActionItems/styles.js +76 -0
- package/es/TopNavBar/TopNavBarActionItems/theme.js +46 -0
- package/es/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.js +57 -0
- package/es/TopNavBar/TopNavBarBrand/index.js +117 -0
- package/es/TopNavBar/TopNavBarBrand/props.js +37 -0
- package/es/TopNavBar/TopNavBarBrand/styles.js +91 -0
- package/es/TopNavBar/TopNavBarBrand/theme.js +42 -0
- package/es/TopNavBar/TopNavBarContext.js +37 -0
- package/es/TopNavBar/TopNavBarItem/TopNavBarItemLocator.js +114 -0
- package/es/TopNavBar/TopNavBarItem/index.js +634 -0
- package/es/TopNavBar/TopNavBarItem/props.js +64 -0
- package/es/TopNavBar/TopNavBarItem/styles.js +124 -0
- package/es/TopNavBar/TopNavBarItem/theme.js +54 -0
- package/es/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.js +86 -0
- package/es/TopNavBar/TopNavBarLayout/DesktopLayout/index.js +119 -0
- package/es/TopNavBar/TopNavBarLayout/DesktopLayout/props.js +31 -0
- package/es/TopNavBar/TopNavBarLayout/DesktopLayout/styles.js +115 -0
- package/es/TopNavBar/TopNavBarLayout/DesktopLayout/theme.js +61 -0
- package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.js +126 -0
- package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.js +454 -0
- package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.js +31 -0
- package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.js +158 -0
- package/es/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.js +61 -0
- package/es/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.js +36 -0
- package/es/TopNavBar/TopNavBarLayout/index.js +118 -0
- package/es/TopNavBar/TopNavBarLayout/props.js +69 -0
- package/es/TopNavBar/TopNavBarLayout/theme.js +40 -0
- package/es/TopNavBar/TopNavBarLocator.js +29 -0
- package/es/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.js +54 -0
- package/es/TopNavBar/TopNavBarMenuItems/index.js +210 -0
- package/es/TopNavBar/TopNavBarMenuItems/props.js +35 -0
- package/es/TopNavBar/TopNavBarMenuItems/styles.js +65 -0
- package/es/TopNavBar/TopNavBarMenuItems/theme.js +45 -0
- package/es/TopNavBar/TopNavBarUser/TopNavBarUserLocator.js +29 -0
- package/es/TopNavBar/TopNavBarUser/index.js +109 -0
- package/es/TopNavBar/TopNavBarUser/props.js +32 -0
- package/es/TopNavBar/TopNavBarUser/styles.js +45 -0
- package/es/TopNavBar/index.js +110 -0
- package/es/TopNavBar/props.js +33 -0
- package/es/TopNavBar/utils/exampleHelpers.js +211 -0
- package/es/TopNavBar/utils/exampleSvgFiles.js +86 -0
- package/es/TopNavBar/utils/mapItemsForDrilldown.js +142 -0
- package/es/index.js +24 -0
- package/lib/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.js +59 -0
- package/lib/TopNavBar/TopNavBarActionItems/index.js +222 -0
- package/lib/TopNavBar/TopNavBarActionItems/props.js +50 -0
- package/lib/TopNavBar/TopNavBarActionItems/styles.js +84 -0
- package/lib/TopNavBar/TopNavBarActionItems/theme.js +54 -0
- package/lib/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.js +68 -0
- package/lib/TopNavBar/TopNavBarBrand/index.js +115 -0
- package/lib/TopNavBar/TopNavBarBrand/props.js +48 -0
- package/lib/TopNavBar/TopNavBarBrand/styles.js +99 -0
- package/lib/TopNavBar/TopNavBarBrand/theme.js +50 -0
- package/lib/TopNavBar/TopNavBarContext.js +46 -0
- package/lib/TopNavBar/TopNavBarItem/TopNavBarItemLocator.js +131 -0
- package/lib/TopNavBar/TopNavBarItem/index.js +650 -0
- package/lib/TopNavBar/TopNavBarItem/props.js +79 -0
- package/lib/TopNavBar/TopNavBarItem/styles.js +132 -0
- package/lib/TopNavBar/TopNavBarItem/theme.js +62 -0
- package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.js +102 -0
- package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/index.js +113 -0
- package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/props.js +40 -0
- package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/styles.js +123 -0
- package/lib/TopNavBar/TopNavBarLayout/DesktopLayout/theme.js +69 -0
- package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.js +143 -0
- package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.js +472 -0
- package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.js +40 -0
- package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.js +166 -0
- package/lib/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.js +69 -0
- package/lib/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.js +48 -0
- package/lib/TopNavBar/TopNavBarLayout/index.js +113 -0
- package/lib/TopNavBar/TopNavBarLayout/props.js +94 -0
- package/lib/TopNavBar/TopNavBarLayout/theme.js +52 -0
- package/lib/TopNavBar/TopNavBarLocator.js +39 -0
- package/lib/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.js +66 -0
- package/lib/TopNavBar/TopNavBarMenuItems/index.js +213 -0
- package/lib/TopNavBar/TopNavBarMenuItems/props.js +48 -0
- package/lib/TopNavBar/TopNavBarMenuItems/styles.js +73 -0
- package/lib/TopNavBar/TopNavBarMenuItems/theme.js +53 -0
- package/lib/TopNavBar/TopNavBarUser/TopNavBarUserLocator.js +39 -0
- package/lib/TopNavBar/TopNavBarUser/index.js +104 -0
- package/lib/TopNavBar/TopNavBarUser/props.js +45 -0
- package/lib/TopNavBar/TopNavBarUser/styles.js +53 -0
- package/lib/TopNavBar/index.js +110 -0
- package/lib/TopNavBar/props.js +44 -0
- package/lib/TopNavBar/utils/exampleHelpers.js +255 -0
- package/lib/TopNavBar/utils/exampleSvgFiles.js +75 -0
- package/lib/TopNavBar/utils/mapItemsForDrilldown.js +165 -0
- package/lib/index.js +13 -0
- package/lib/package.json +1 -0
- package/package.json +64 -0
- package/src/TopNavBar/README.md +2329 -0
- package/src/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.ts +53 -0
- package/src/TopNavBar/TopNavBarActionItems/index.tsx +299 -0
- package/src/TopNavBar/TopNavBarActionItems/props.ts +152 -0
- package/src/TopNavBar/TopNavBarActionItems/styles.ts +92 -0
- package/src/TopNavBar/TopNavBarActionItems/theme.ts +51 -0
- package/src/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.ts +44 -0
- package/src/TopNavBar/TopNavBarBrand/index.tsx +139 -0
- package/src/TopNavBar/TopNavBarBrand/props.ts +146 -0
- package/src/TopNavBar/TopNavBarBrand/styles.ts +102 -0
- package/src/TopNavBar/TopNavBarBrand/theme.ts +48 -0
- package/src/TopNavBar/TopNavBarContext.ts +47 -0
- package/src/TopNavBar/TopNavBarItem/TopNavBarItemLocator.ts +111 -0
- package/src/TopNavBar/TopNavBarItem/index.tsx +752 -0
- package/src/TopNavBar/TopNavBarItem/props.ts +331 -0
- package/src/TopNavBar/TopNavBarItem/styles.ts +142 -0
- package/src/TopNavBar/TopNavBarItem/theme.ts +60 -0
- package/src/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.ts +84 -0
- package/src/TopNavBar/TopNavBarLayout/DesktopLayout/index.tsx +148 -0
- package/src/TopNavBar/TopNavBarLayout/DesktopLayout/props.ts +104 -0
- package/src/TopNavBar/TopNavBarLayout/DesktopLayout/styles.ts +136 -0
- package/src/TopNavBar/TopNavBarLayout/DesktopLayout/theme.ts +66 -0
- package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.ts +125 -0
- package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.tsx +600 -0
- package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.ts +187 -0
- package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.ts +184 -0
- package/src/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.ts +69 -0
- package/src/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.ts +46 -0
- package/src/TopNavBar/TopNavBarLayout/index.tsx +149 -0
- package/src/TopNavBar/TopNavBarLayout/props.ts +209 -0
- package/src/TopNavBar/TopNavBarLayout/theme.ts +47 -0
- package/src/TopNavBar/TopNavBarLocator.ts +31 -0
- package/src/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.ts +56 -0
- package/src/TopNavBar/TopNavBarMenuItems/index.tsx +275 -0
- package/src/TopNavBar/TopNavBarMenuItems/props.ts +133 -0
- package/src/TopNavBar/TopNavBarMenuItems/styles.ts +72 -0
- package/src/TopNavBar/TopNavBarMenuItems/theme.ts +51 -0
- package/src/TopNavBar/TopNavBarUser/TopNavBarUserLocator.ts +32 -0
- package/src/TopNavBar/TopNavBarUser/index.tsx +133 -0
- package/src/TopNavBar/TopNavBarUser/props.ts +83 -0
- package/src/TopNavBar/TopNavBarUser/styles.ts +47 -0
- package/src/TopNavBar/index.tsx +142 -0
- package/src/TopNavBar/props.ts +108 -0
- package/src/TopNavBar/utils/exampleHelpers.tsx +342 -0
- package/src/TopNavBar/utils/exampleSvgFiles.tsx +76 -0
- package/src/TopNavBar/utils/mapItemsForDrilldown.tsx +228 -0
- package/src/index.ts +62 -0
- package/tsconfig.build.json +37 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +4 -0
- package/types/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.d.ts +2116 -0
- package/types/TopNavBar/TopNavBarActionItems/TopNavBarActionItemsLocator.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarActionItems/index.d.ts +40 -0
- package/types/TopNavBar/TopNavBarActionItems/index.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarActionItems/props.d.ts +59 -0
- package/types/TopNavBar/TopNavBarActionItems/props.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarActionItems/styles.d.ts +15 -0
- package/types/TopNavBar/TopNavBarActionItems/styles.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarActionItems/theme.d.ts +10 -0
- package/types/TopNavBar/TopNavBarActionItems/theme.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.d.ts +592 -0
- package/types/TopNavBar/TopNavBarBrand/TopNavBarBrandLocator.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarBrand/index.d.ts +30 -0
- package/types/TopNavBar/TopNavBarBrand/index.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarBrand/props.d.ts +60 -0
- package/types/TopNavBar/TopNavBarBrand/props.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarBrand/styles.d.ts +15 -0
- package/types/TopNavBar/TopNavBarBrand/styles.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarBrand/theme.d.ts +10 -0
- package/types/TopNavBar/TopNavBarBrand/theme.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarContext.d.ts +17 -0
- package/types/TopNavBar/TopNavBarContext.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarItem/TopNavBarItemLocator.d.ts +642 -0
- package/types/TopNavBar/TopNavBarItem/TopNavBarItemLocator.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarItem/index.d.ts +64 -0
- package/types/TopNavBar/TopNavBarItem/index.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarItem/props.d.ts +188 -0
- package/types/TopNavBar/TopNavBarItem/props.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarItem/styles.d.ts +15 -0
- package/types/TopNavBar/TopNavBarItem/styles.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarItem/theme.d.ts +10 -0
- package/types/TopNavBar/TopNavBarItem/theme.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.d.ts +5737 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/TopNavBarDesktopLayoutLocator.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/index.d.ts +31 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/index.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/props.d.ts +29 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/props.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/styles.d.ts +15 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/styles.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/theme.d.ts +10 -0
- package/types/TopNavBar/TopNavBarLayout/DesktopLayout/theme.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.d.ts +4357 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/TopNavBarSmallViewportLayoutLocator.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.d.ts +58 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/index.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.d.ts +89 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/props.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.d.ts +15 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/styles.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.d.ts +10 -0
- package/types/TopNavBar/TopNavBarLayout/SmallViewportLayout/theme.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.d.ts +7 -0
- package/types/TopNavBar/TopNavBarLayout/TopNavBarLayoutLocator.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/index.d.ts +34 -0
- package/types/TopNavBar/TopNavBarLayout/index.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/props.d.ts +83 -0
- package/types/TopNavBar/TopNavBarLayout/props.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLayout/theme.d.ts +10 -0
- package/types/TopNavBar/TopNavBarLayout/theme.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarLocator.d.ts +566 -0
- package/types/TopNavBar/TopNavBarLocator.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.d.ts +1351 -0
- package/types/TopNavBar/TopNavBarMenuItems/TopNavBarMenuItemsLocator.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarMenuItems/index.d.ts +38 -0
- package/types/TopNavBar/TopNavBarMenuItems/index.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarMenuItems/props.d.ts +53 -0
- package/types/TopNavBar/TopNavBarMenuItems/props.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarMenuItems/styles.d.ts +15 -0
- package/types/TopNavBar/TopNavBarMenuItems/styles.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarMenuItems/theme.d.ts +10 -0
- package/types/TopNavBar/TopNavBarMenuItems/theme.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarUser/TopNavBarUserLocator.d.ts +566 -0
- package/types/TopNavBar/TopNavBarUser/TopNavBarUserLocator.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarUser/index.d.ts +31 -0
- package/types/TopNavBar/TopNavBarUser/index.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarUser/props.d.ts +29 -0
- package/types/TopNavBar/TopNavBarUser/props.d.ts.map +1 -0
- package/types/TopNavBar/TopNavBarUser/styles.d.ts +14 -0
- package/types/TopNavBar/TopNavBarUser/styles.d.ts.map +1 -0
- package/types/TopNavBar/index.d.ts +38 -0
- package/types/TopNavBar/index.d.ts.map +1 -0
- package/types/TopNavBar/props.d.ts +43 -0
- package/types/TopNavBar/props.d.ts.map +1 -0
- package/types/TopNavBar/utils/exampleHelpers.d.ts +70 -0
- package/types/TopNavBar/utils/exampleHelpers.d.ts.map +1 -0
- package/types/TopNavBar/utils/exampleSvgFiles.d.ts +7 -0
- package/types/TopNavBar/utils/exampleSvgFiles.d.ts.map +1 -0
- package/types/TopNavBar/utils/mapItemsForDrilldown.d.ts +19 -0
- package/types/TopNavBar/utils/mapItemsForDrilldown.d.ts.map +1 -0
- package/types/index.d.ts +11 -0
- package/types/index.d.ts.map +1 -0
|
@@ -0,0 +1,752 @@
|
|
|
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
|
+
callRenderProp,
|
|
30
|
+
matchComponentTypes,
|
|
31
|
+
omitProps,
|
|
32
|
+
passthroughProps,
|
|
33
|
+
safeCloneElement,
|
|
34
|
+
withDeterministicId
|
|
35
|
+
} from '@instructure/ui-react-utils'
|
|
36
|
+
import { createChainedFunction } from '@instructure/ui-utils'
|
|
37
|
+
import { testable } from '@instructure/ui-testable'
|
|
38
|
+
import { warn, error } from '@instructure/console'
|
|
39
|
+
|
|
40
|
+
import { withStyle, jsx, InstUISettingsProvider } from '@instructure/emotion'
|
|
41
|
+
|
|
42
|
+
import {
|
|
43
|
+
IconArrowOpenDownSolid,
|
|
44
|
+
IconArrowOpenUpSolid
|
|
45
|
+
} from '@instructure/ui-icons'
|
|
46
|
+
import { Avatar } from '@instructure/ui-avatar'
|
|
47
|
+
import { BaseButton } from '@instructure/ui-buttons'
|
|
48
|
+
import type { BaseButtonProps } from '@instructure/ui-buttons'
|
|
49
|
+
import { Tooltip } from '@instructure/ui-tooltip'
|
|
50
|
+
import type { TooltipProps } from '@instructure/ui-tooltip'
|
|
51
|
+
import { Popover } from '@instructure/ui-popover'
|
|
52
|
+
import type { PopoverProps } from '@instructure/ui-popover'
|
|
53
|
+
import { Drilldown } from '@instructure/ui-drilldown'
|
|
54
|
+
import type { DrilldownProps } from '@instructure/ui-drilldown'
|
|
55
|
+
import { ScreenReaderContent } from '@instructure/ui-a11y-content'
|
|
56
|
+
|
|
57
|
+
import { TopNavBarContext } from '../TopNavBarContext'
|
|
58
|
+
|
|
59
|
+
import generateStyle from './styles'
|
|
60
|
+
import generateComponentTheme from './theme'
|
|
61
|
+
|
|
62
|
+
import { propTypes, allowedProps } from './props'
|
|
63
|
+
import type {
|
|
64
|
+
TopNavBarItemProps,
|
|
65
|
+
TopNavBarItemState,
|
|
66
|
+
TopNavBarItemStyleProps
|
|
67
|
+
} from './props'
|
|
68
|
+
|
|
69
|
+
type BaseButtonElement = React.ComponentElement<BaseButtonProps, BaseButton>
|
|
70
|
+
|
|
71
|
+
const navbarStackingDefault = 10000
|
|
72
|
+
const submenuStacking = navbarStackingDefault + 1
|
|
73
|
+
const tooltipStacking = navbarStackingDefault + 2
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
---
|
|
77
|
+
parent: TopNavBar
|
|
78
|
+
id: TopNavBar.Item
|
|
79
|
+
---
|
|
80
|
+
@module TopNavBarItem
|
|
81
|
+
@tsProps
|
|
82
|
+
**/
|
|
83
|
+
@withDeterministicId()
|
|
84
|
+
@withStyle(generateStyle, generateComponentTheme)
|
|
85
|
+
@testable()
|
|
86
|
+
class TopNavBarItem extends Component<TopNavBarItemProps, TopNavBarItemState> {
|
|
87
|
+
static readonly componentId = 'TopNavBar.Item'
|
|
88
|
+
|
|
89
|
+
static propTypes = propTypes
|
|
90
|
+
static allowedProps = allowedProps
|
|
91
|
+
static defaultProps = {
|
|
92
|
+
status: 'default',
|
|
93
|
+
variant: 'default',
|
|
94
|
+
showSubmenuChevron: true
|
|
95
|
+
} as const
|
|
96
|
+
|
|
97
|
+
declare context: React.ContextType<typeof TopNavBarContext>
|
|
98
|
+
static contextType = TopNavBarContext
|
|
99
|
+
|
|
100
|
+
ref: HTMLDivElement | null = null
|
|
101
|
+
private _itemRef: HTMLButtonElement | HTMLLinkElement | null = null
|
|
102
|
+
|
|
103
|
+
private readonly _tooltipContentId: string
|
|
104
|
+
|
|
105
|
+
handleRef = (el: HTMLDivElement | null) => {
|
|
106
|
+
const { elementRef } = this.props
|
|
107
|
+
|
|
108
|
+
this.ref = el
|
|
109
|
+
|
|
110
|
+
if (typeof elementRef === 'function') {
|
|
111
|
+
elementRef(el)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
handleItemRef = (el: HTMLButtonElement | HTMLLinkElement | null) => {
|
|
116
|
+
const { itemRef } = this.props
|
|
117
|
+
|
|
118
|
+
this._itemRef = el
|
|
119
|
+
|
|
120
|
+
if (typeof itemRef === 'function') {
|
|
121
|
+
itemRef(el)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
constructor(props: TopNavBarItemProps) {
|
|
126
|
+
super(props)
|
|
127
|
+
|
|
128
|
+
this._tooltipContentId = props.deterministicId!('TopNavBarItem-tooltip')
|
|
129
|
+
|
|
130
|
+
this.state = {
|
|
131
|
+
isSubmenuOpen: false,
|
|
132
|
+
isPopoverOpen: false
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
componentDidMount() {
|
|
137
|
+
const { makeStyles, customPopoverConfig } = this.props
|
|
138
|
+
|
|
139
|
+
makeStyles?.(this.makeStylesVariables)
|
|
140
|
+
|
|
141
|
+
if (customPopoverConfig && this.isCustomPopoverControlled) {
|
|
142
|
+
this.setState({
|
|
143
|
+
isPopoverOpen: !!customPopoverConfig.isShowingContent
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
componentDidUpdate() {
|
|
149
|
+
const { makeStyles, customPopoverConfig } = this.props
|
|
150
|
+
|
|
151
|
+
makeStyles?.(this.makeStylesVariables)
|
|
152
|
+
|
|
153
|
+
if (
|
|
154
|
+
customPopoverConfig &&
|
|
155
|
+
this.isCustomPopoverControlled &&
|
|
156
|
+
customPopoverConfig.isShowingContent !== this.state.isPopoverOpen
|
|
157
|
+
) {
|
|
158
|
+
this.setState({
|
|
159
|
+
isPopoverOpen: !!customPopoverConfig.isShowingContent
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
get makeStylesVariables(): TopNavBarItemStyleProps {
|
|
165
|
+
const { layout, inverseColor } = this.context
|
|
166
|
+
return { layout, inverseColor }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
get shouldRenderSubmenu() {
|
|
170
|
+
const { renderSubmenu } = this.props
|
|
171
|
+
|
|
172
|
+
return !!renderSubmenu && matchComponentTypes(renderSubmenu, [Drilldown])
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
get shouldRenderPopover() {
|
|
176
|
+
const { id, renderSubmenu, customPopoverConfig } = this.props
|
|
177
|
+
|
|
178
|
+
if (!customPopoverConfig) {
|
|
179
|
+
return false
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!customPopoverConfig.children) {
|
|
183
|
+
warn(
|
|
184
|
+
false,
|
|
185
|
+
`Pass the content of the custom Popover as "customPopoverConfig.children" for the item with id: "${id}".`
|
|
186
|
+
)
|
|
187
|
+
return false
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (customPopoverConfig && renderSubmenu) {
|
|
191
|
+
warn(
|
|
192
|
+
false,
|
|
193
|
+
`TopNavBar.Items are not allowed to have both the "renderSubmenu" and "customPopoverConfig" props. For submenus, pass a Drilldown component via the "renderSubmenu" prop, and only use "customPopoverConfig" for custom features. Item with id: "${id}" will ignore the "customPopoverConfig" prop.`
|
|
194
|
+
)
|
|
195
|
+
return false
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return true
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
get isCustomPopoverControlled() {
|
|
202
|
+
const { customPopoverConfig } = this.props
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
customPopoverConfig &&
|
|
206
|
+
typeof customPopoverConfig.isShowingContent !== 'undefined'
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
get hasOpenPopover() {
|
|
211
|
+
return this.state.isSubmenuOpen || this.state.isPopoverOpen
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
get isDefaultVariant() {
|
|
215
|
+
return this.props.variant === 'default'
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
get isButtonVariant() {
|
|
219
|
+
return this.props.variant === 'button'
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
get isIconVariant() {
|
|
223
|
+
return this.props.variant === 'icon'
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
get isAvatarOnlyVariant() {
|
|
227
|
+
return this.props.variant === 'avatar'
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
get hasAvatar() {
|
|
231
|
+
const { id, renderIcon, renderAvatar, variant } = this.props
|
|
232
|
+
const hasAvatar = !!renderAvatar
|
|
233
|
+
|
|
234
|
+
if (this.isAvatarOnlyVariant && !hasAvatar) {
|
|
235
|
+
warn(
|
|
236
|
+
false,
|
|
237
|
+
`The "renderAvatar" config is required for the 'variant="avatar"' type <TopNavBar.Item> components, but received none for the item with id "${id}".`
|
|
238
|
+
)
|
|
239
|
+
return false
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (hasAvatar && (renderIcon || variant === 'icon')) {
|
|
243
|
+
warn(
|
|
244
|
+
false,
|
|
245
|
+
`<TopNavBar.Item> components with icons cannot display avatars, so the "renderAvatar" config prop will be ignored for item with id "${id}".`
|
|
246
|
+
)
|
|
247
|
+
return false
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return hasAvatar
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
get submenuIcon() {
|
|
254
|
+
if (
|
|
255
|
+
!(this.shouldRenderSubmenu || this.shouldRenderPopover) ||
|
|
256
|
+
!this.props.showSubmenuChevron
|
|
257
|
+
) {
|
|
258
|
+
return null
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return (
|
|
262
|
+
<span css={this.props.styles?.submenuIcon}>
|
|
263
|
+
{(this.shouldRenderSubmenu && this.state.isSubmenuOpen) ||
|
|
264
|
+
(this.shouldRenderPopover && this.state.isPopoverOpen) ? (
|
|
265
|
+
<IconArrowOpenUpSolid />
|
|
266
|
+
) : (
|
|
267
|
+
<IconArrowOpenDownSolid />
|
|
268
|
+
)}
|
|
269
|
+
</span>
|
|
270
|
+
)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
get buttonThemeOverride() {
|
|
274
|
+
const { styles } = this.props
|
|
275
|
+
|
|
276
|
+
const themeOverride: BaseButtonProps['themeOverride'] = {}
|
|
277
|
+
|
|
278
|
+
if (this.isDefaultVariant || this.hasAvatar) {
|
|
279
|
+
themeOverride.mediumPaddingHorizontal = styles?.itemInlinePadding
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (this.hasAvatar) {
|
|
283
|
+
themeOverride.mediumPaddingTop = '0.125rem'
|
|
284
|
+
themeOverride.mediumPaddingBottom = '0.125rem'
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (this.isAvatarOnlyVariant && !this.submenuIcon) {
|
|
288
|
+
themeOverride.mediumPaddingHorizontal = '0'
|
|
289
|
+
themeOverride.mediumPaddingTop = '0'
|
|
290
|
+
themeOverride.mediumPaddingBottom = '0'
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (this.size === 'large') {
|
|
294
|
+
// we need a custom 42x42 px icon here,
|
|
295
|
+
// so that the focus ring won't be cut off
|
|
296
|
+
themeOverride.largeHeight = '2.625rem'
|
|
297
|
+
themeOverride.iconSizeLarge = '1.5rem'
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return Object.keys(themeOverride).length > 0 ? themeOverride : undefined
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
get colorProps(): Pick<BaseButtonProps, 'color' | 'focusColor'> {
|
|
304
|
+
let color: BaseButtonProps['color'] = 'primary-inverse'
|
|
305
|
+
let focusColor: BaseButtonProps['focusColor'] = 'inverse'
|
|
306
|
+
|
|
307
|
+
if (this.context.inverseColor) {
|
|
308
|
+
color = 'secondary'
|
|
309
|
+
focusColor = 'info'
|
|
310
|
+
|
|
311
|
+
if (this.isButtonVariant) {
|
|
312
|
+
color = 'primary'
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return { color, focusColor }
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
get size(): BaseButtonProps['size'] {
|
|
320
|
+
return this.isIconVariant && this.context.layout === 'smallViewport'
|
|
321
|
+
? 'large'
|
|
322
|
+
: 'medium'
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
get ariaProps(): Pick<
|
|
326
|
+
React.AriaAttributes,
|
|
327
|
+
'aria-haspopup' | 'aria-expanded'
|
|
328
|
+
> {
|
|
329
|
+
let hasPopup: React.AriaAttributes['aria-haspopup']
|
|
330
|
+
let expanded: React.AriaAttributes['aria-expanded']
|
|
331
|
+
|
|
332
|
+
if (this.shouldRenderSubmenu) {
|
|
333
|
+
hasPopup = 'menu'
|
|
334
|
+
expanded = this.state.isSubmenuOpen
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (this.shouldRenderPopover) {
|
|
338
|
+
hasPopup = 'true'
|
|
339
|
+
expanded = this.state.isPopoverOpen
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return { 'aria-haspopup': hasPopup, 'aria-expanded': expanded }
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
get itemProps(): BaseButtonProps | null {
|
|
346
|
+
const {
|
|
347
|
+
id,
|
|
348
|
+
variant,
|
|
349
|
+
href: hrefOriginal,
|
|
350
|
+
onClick: onClickOriginal,
|
|
351
|
+
onMouseOver,
|
|
352
|
+
onMouseOut,
|
|
353
|
+
onFocus,
|
|
354
|
+
onBlur,
|
|
355
|
+
onKeyDown,
|
|
356
|
+
onKeyUp,
|
|
357
|
+
renderSubmenu,
|
|
358
|
+
status: statusOriginal,
|
|
359
|
+
renderAvatar,
|
|
360
|
+
renderIcon
|
|
361
|
+
} = this.props
|
|
362
|
+
|
|
363
|
+
let href = hrefOriginal
|
|
364
|
+
let onClick = onClickOriginal
|
|
365
|
+
let status = statusOriginal
|
|
366
|
+
|
|
367
|
+
if (renderSubmenu) {
|
|
368
|
+
if (href) {
|
|
369
|
+
warn(
|
|
370
|
+
false,
|
|
371
|
+
`TopNavBar.Items with submenus are not allowed to have 'href' property, but received href "${href}" for item with the id: "${id}".`
|
|
372
|
+
)
|
|
373
|
+
href = undefined
|
|
374
|
+
}
|
|
375
|
+
if (onClick) {
|
|
376
|
+
warn(
|
|
377
|
+
false,
|
|
378
|
+
`TopNavBar.Items with submenus are not allowed to have 'onClick' property, but received onClick for item with the id: "${id}".Use the \`onSubmenuToggle\` prop instead. OnClick: ${onClick}`
|
|
379
|
+
)
|
|
380
|
+
onClick = undefined
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (status === 'active' && !this.isDefaultVariant) {
|
|
385
|
+
warn(
|
|
386
|
+
false,
|
|
387
|
+
`Only \`variant="default"\` <TopNavBar.Item> components can be set to active, but item with id "${id}" has variant: "${variant}".`
|
|
388
|
+
)
|
|
389
|
+
status = 'default'
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (this.hasAvatar) {
|
|
393
|
+
if (!renderAvatar?.avatarName) {
|
|
394
|
+
error(
|
|
395
|
+
false,
|
|
396
|
+
`The "avatarName" prop is required for for <TopNavBar.Item> components with avatar, but the item with id "${id}" is missing it.`
|
|
397
|
+
)
|
|
398
|
+
return null
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (status === 'active') {
|
|
402
|
+
warn(
|
|
403
|
+
false,
|
|
404
|
+
`<TopNavBar.Item> components with avatar cannot have "active" status, so the "active" status on the item with id "${id}" will be ignored.`
|
|
405
|
+
)
|
|
406
|
+
status = 'default'
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (this.isIconVariant) {
|
|
411
|
+
if (!renderIcon) {
|
|
412
|
+
error(
|
|
413
|
+
false,
|
|
414
|
+
`The "renderIcon" prop is required for the \`variant="icon"\` type <TopNavBar.Item> components, but the item with id "${id}" is missing it.`
|
|
415
|
+
)
|
|
416
|
+
return null
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return {
|
|
421
|
+
id,
|
|
422
|
+
...this.colorProps,
|
|
423
|
+
...this.ariaProps,
|
|
424
|
+
size: this.size,
|
|
425
|
+
withBorder: this.isButtonVariant,
|
|
426
|
+
withBackground: this.isButtonVariant,
|
|
427
|
+
interaction: status === 'disabled' ? 'disabled' : undefined,
|
|
428
|
+
'aria-disabled': status === 'disabled' ? 'true' : undefined,
|
|
429
|
+
shape:
|
|
430
|
+
this.isAvatarOnlyVariant && !this.submenuIcon ? 'circle' : 'rectangle',
|
|
431
|
+
href,
|
|
432
|
+
onClick,
|
|
433
|
+
onMouseOver,
|
|
434
|
+
onMouseOut,
|
|
435
|
+
onFocus,
|
|
436
|
+
onBlur,
|
|
437
|
+
onKeyDown: createChainedFunction(onKeyDown, this.handleKeyDown),
|
|
438
|
+
onKeyUp,
|
|
439
|
+
renderIcon,
|
|
440
|
+
themeOverride: this.buttonThemeOverride,
|
|
441
|
+
elementRef: (e) => {
|
|
442
|
+
this.handleItemRef(e as HTMLButtonElement | HTMLLinkElement)
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
handleKeyDown: TopNavBarItemProps['onKeyDown'] = (e) => {
|
|
448
|
+
if (e.key === 'ArrowDown') {
|
|
449
|
+
if (
|
|
450
|
+
(this.shouldRenderSubmenu && !this.state.isSubmenuOpen) ||
|
|
451
|
+
(this.shouldRenderPopover && !this.state.isPopoverOpen)
|
|
452
|
+
) {
|
|
453
|
+
e.preventDefault()
|
|
454
|
+
this._itemRef?.click()
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (e.key === 'Tab') {
|
|
459
|
+
if (this.state.isPopoverOpen && !this.isCustomPopoverControlled) {
|
|
460
|
+
this.setState({ isPopoverOpen: false })
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
handleMenuToggle: NonNullable<DrilldownProps['onToggle']> = (event, args) => {
|
|
466
|
+
this.setState({ isSubmenuOpen: args.shown })
|
|
467
|
+
|
|
468
|
+
if (typeof this.props.onSubmenuToggle === 'function') {
|
|
469
|
+
this.props.onSubmenuToggle(event, args)
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
renderContent() {
|
|
474
|
+
const { children, styles } = this.props
|
|
475
|
+
const { itemProps } = this
|
|
476
|
+
|
|
477
|
+
if (!itemProps) {
|
|
478
|
+
return null
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
let content = children
|
|
482
|
+
|
|
483
|
+
if (this.isAvatarOnlyVariant) {
|
|
484
|
+
content = this.renderAvatar()
|
|
485
|
+
} else if (this.isIconVariant) {
|
|
486
|
+
content = <ScreenReaderContent>{content}</ScreenReaderContent>
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const button: BaseButtonElement = (
|
|
490
|
+
<BaseButton
|
|
491
|
+
{...itemProps}
|
|
492
|
+
// rest of the props should go to the Button
|
|
493
|
+
{...passthroughProps(omitProps(this.props, allowedProps))}
|
|
494
|
+
>
|
|
495
|
+
{this.isIconVariant && !this.submenuIcon ? (
|
|
496
|
+
content
|
|
497
|
+
) : (
|
|
498
|
+
<div css={styles?.content}>
|
|
499
|
+
{this.hasAvatar && !this.isAvatarOnlyVariant && (
|
|
500
|
+
<span css={this.props.styles?.avatarContainer}>
|
|
501
|
+
{this.renderAvatar()}
|
|
502
|
+
</span>
|
|
503
|
+
)}
|
|
504
|
+
{content}
|
|
505
|
+
{this.submenuIcon}
|
|
506
|
+
</div>
|
|
507
|
+
)}
|
|
508
|
+
</BaseButton>
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
return (
|
|
512
|
+
<div css={styles?.container}>
|
|
513
|
+
{this.props.tooltip
|
|
514
|
+
? this.wrapButtonInTooltip(button, children)
|
|
515
|
+
: button}
|
|
516
|
+
</div>
|
|
517
|
+
)
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
wrapButtonInTooltip(button: BaseButtonElement, content: React.ReactNode) {
|
|
521
|
+
const { tooltip, styles } = this.props
|
|
522
|
+
|
|
523
|
+
if (!tooltip) {
|
|
524
|
+
return button
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
let tooltipProps: Partial<TooltipProps> = {
|
|
528
|
+
placement: 'bottom',
|
|
529
|
+
color: this.context.inverseColor ? 'primary' : 'primary-inverse'
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (typeof tooltip === 'string') {
|
|
533
|
+
tooltipProps.renderTip = tooltip
|
|
534
|
+
} else {
|
|
535
|
+
tooltipProps = { ...tooltipProps, ...tooltip }
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const tipContent = callRenderProp(tooltipProps.renderTip)
|
|
539
|
+
|
|
540
|
+
if (!tipContent) {
|
|
541
|
+
return button
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
const contentAndTooltipIdentical = tipContent === content
|
|
545
|
+
|
|
546
|
+
return (
|
|
547
|
+
<InstUISettingsProvider
|
|
548
|
+
theme={{
|
|
549
|
+
componentOverrides: {
|
|
550
|
+
View: {
|
|
551
|
+
// moves tooltips above submenus/popovers
|
|
552
|
+
stackingTopmost: tooltipStacking
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}}
|
|
556
|
+
>
|
|
557
|
+
<Tooltip
|
|
558
|
+
{...tooltipProps}
|
|
559
|
+
renderTip={
|
|
560
|
+
contentAndTooltipIdentical ? (
|
|
561
|
+
tipContent
|
|
562
|
+
) : (
|
|
563
|
+
<div id={this._tooltipContentId}>{tipContent}</div>
|
|
564
|
+
)
|
|
565
|
+
}
|
|
566
|
+
positionContainerDisplay="block"
|
|
567
|
+
>
|
|
568
|
+
<div css={styles?.submenuTriggerContainer}>
|
|
569
|
+
{contentAndTooltipIdentical
|
|
570
|
+
? button
|
|
571
|
+
: safeCloneElement(button, {
|
|
572
|
+
'aria-describedby': this._tooltipContentId
|
|
573
|
+
})}
|
|
574
|
+
</div>
|
|
575
|
+
</Tooltip>
|
|
576
|
+
</InstUISettingsProvider>
|
|
577
|
+
)
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
renderAvatar() {
|
|
581
|
+
if (!this.hasAvatar) {
|
|
582
|
+
return null
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
const { id, children, renderAvatar } = this.props
|
|
586
|
+
const { avatarName, avatarSrc, avatarAlt } = renderAvatar!
|
|
587
|
+
|
|
588
|
+
const label =
|
|
589
|
+
avatarAlt ||
|
|
590
|
+
(typeof children === 'string' ? (children as string) : undefined)
|
|
591
|
+
|
|
592
|
+
if (!label) {
|
|
593
|
+
warn(
|
|
594
|
+
false,
|
|
595
|
+
`Please supply a label for the avatar with either the "renderAvatar.avatarAlt" or the "children" (as string) prop. It is needed for screen reader support, but missing on the item with the id: "${id}".`
|
|
596
|
+
)
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
return avatarName ? (
|
|
600
|
+
<Avatar name={avatarName} src={avatarSrc} alt={label} size="small" />
|
|
601
|
+
) : null
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
renderDropdownMenu() {
|
|
605
|
+
const { id, renderSubmenu, status, styles } = this.props
|
|
606
|
+
|
|
607
|
+
if (!renderSubmenu || !this.shouldRenderSubmenu) {
|
|
608
|
+
return null
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
if (typeof renderSubmenu.props.show !== 'undefined') {
|
|
612
|
+
warn(
|
|
613
|
+
false,
|
|
614
|
+
`TopNavBar.Item Drilldown submenus are controlled by the component. The "show" prop will be ignored on the submenu of the item with id: "${id}".`
|
|
615
|
+
)
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
if (renderSubmenu.props.trigger) {
|
|
619
|
+
warn(
|
|
620
|
+
false,
|
|
621
|
+
`TopNavBar.Item submenus have the item itself as their trigger. The "trigger" prop will be ignored on the Drilldown submenu of item with id: "${id}".`
|
|
622
|
+
)
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
return safeCloneElement(renderSubmenu, {
|
|
626
|
+
trigger: (
|
|
627
|
+
<div css={styles?.submenuTriggerContainer}>{this.renderContent()}</div>
|
|
628
|
+
),
|
|
629
|
+
show: this.state.isSubmenuOpen,
|
|
630
|
+
onToggle: createChainedFunction(
|
|
631
|
+
renderSubmenu.props?.onToggle,
|
|
632
|
+
this.handleMenuToggle
|
|
633
|
+
),
|
|
634
|
+
positionContainerDisplay: 'block',
|
|
635
|
+
placement: 'bottom start',
|
|
636
|
+
withArrow: false,
|
|
637
|
+
minWidth: renderSubmenu.props?.minWidth || '18.5rem',
|
|
638
|
+
maxHeight: renderSubmenu.props?.maxHeight || `calc(100vh - 10rem)`,
|
|
639
|
+
|
|
640
|
+
...(status === 'disabled' && {
|
|
641
|
+
disabled: true,
|
|
642
|
+
show: false,
|
|
643
|
+
onToggle: undefined
|
|
644
|
+
})
|
|
645
|
+
})
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
renderPopover() {
|
|
649
|
+
const { id, customPopoverConfig, styles } = this.props
|
|
650
|
+
|
|
651
|
+
if (!customPopoverConfig || !this.shouldRenderPopover) {
|
|
652
|
+
return null
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// @ts-expect-error throw a warning just in case they pass trigger
|
|
656
|
+
if (customPopoverConfig.renderTrigger) {
|
|
657
|
+
warn(
|
|
658
|
+
false,
|
|
659
|
+
`TopNavBar.Item popovers have the item itself as their trigger. The "renderTrigger" prop will be ignored on the popover of item with id: "${id}".`
|
|
660
|
+
)
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const popoverProps: PopoverProps = {
|
|
664
|
+
// defaults:
|
|
665
|
+
placement: 'bottom start',
|
|
666
|
+
withArrow: true,
|
|
667
|
+
shouldReturnFocus: true,
|
|
668
|
+
shouldContainFocus: false,
|
|
669
|
+
|
|
670
|
+
// user input:
|
|
671
|
+
...customPopoverConfig,
|
|
672
|
+
|
|
673
|
+
// fix overrides:
|
|
674
|
+
positionContainerDisplay: 'block',
|
|
675
|
+
renderTrigger: (
|
|
676
|
+
<div css={styles?.submenuTriggerContainer}>{this.renderContent()}</div>
|
|
677
|
+
),
|
|
678
|
+
onShowContent: createChainedFunction(
|
|
679
|
+
customPopoverConfig.onShowContent,
|
|
680
|
+
() => {
|
|
681
|
+
if (!this.isCustomPopoverControlled) {
|
|
682
|
+
this.setState({ isPopoverOpen: true })
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
),
|
|
686
|
+
onHideContent: createChainedFunction(
|
|
687
|
+
customPopoverConfig.onHideContent,
|
|
688
|
+
() => {
|
|
689
|
+
if (!this.isCustomPopoverControlled) {
|
|
690
|
+
this.setState({ isPopoverOpen: false })
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
),
|
|
694
|
+
isShowingContent: this.state.isPopoverOpen,
|
|
695
|
+
// @ts-expect-error This is a force override for Popover, because it puts
|
|
696
|
+
// aria-expanded on the trigger when shouldContainFocus="true",
|
|
697
|
+
// even when it should be on the item's <button>
|
|
698
|
+
'aria-expanded': undefined
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
return <Popover {...popoverProps}>{customPopoverConfig.children}</Popover>
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
render() {
|
|
705
|
+
const { styles } = this.props
|
|
706
|
+
|
|
707
|
+
let content
|
|
708
|
+
|
|
709
|
+
if (this.shouldRenderPopover) {
|
|
710
|
+
content = (
|
|
711
|
+
<InstUISettingsProvider
|
|
712
|
+
theme={{
|
|
713
|
+
componentOverrides: {
|
|
714
|
+
View: {
|
|
715
|
+
// moves popovers above navbar, below tooltips
|
|
716
|
+
stackingTopmost: submenuStacking
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}}
|
|
720
|
+
>
|
|
721
|
+
{this.renderPopover()}
|
|
722
|
+
</InstUISettingsProvider>
|
|
723
|
+
)
|
|
724
|
+
} else if (this.shouldRenderSubmenu) {
|
|
725
|
+
content = (
|
|
726
|
+
<InstUISettingsProvider
|
|
727
|
+
theme={{
|
|
728
|
+
componentOverrides: {
|
|
729
|
+
View: {
|
|
730
|
+
// moves submenus above navbar, below tooltips
|
|
731
|
+
stackingTopmost: submenuStacking
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}}
|
|
735
|
+
>
|
|
736
|
+
{this.renderDropdownMenu()}
|
|
737
|
+
</InstUISettingsProvider>
|
|
738
|
+
)
|
|
739
|
+
} else {
|
|
740
|
+
content = this.renderContent()
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
return (
|
|
744
|
+
<div ref={this.handleRef} css={styles?.topNavBarItem}>
|
|
745
|
+
{content}
|
|
746
|
+
</div>
|
|
747
|
+
)
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
export { TopNavBarItem }
|
|
752
|
+
export default TopNavBarItem
|