@instructure/ui-popover 11.6.0 → 11.6.1-snapshot-129
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 +38 -288
- package/es/Popover/{index.js → v1/index.js} +3 -3
- package/es/Popover/v2/index.js +499 -0
- package/es/Popover/v2/props.js +26 -0
- package/es/Popover/v2/styles.js +39 -0
- package/es/{index.js → exports/a.js} +1 -1
- package/{src/index.ts → es/exports/b.js} +1 -2
- package/lib/Popover/{index.js → v1/index.js} +5 -6
- package/lib/Popover/v2/index.js +514 -0
- package/lib/Popover/v2/props.js +31 -0
- package/lib/Popover/v2/styles.js +45 -0
- package/lib/{index.js → exports/a.js} +2 -2
- package/lib/exports/b.js +12 -0
- package/package.json +46 -24
- package/src/Popover/{index.tsx → v1/index.tsx} +5 -5
- package/src/Popover/v2/README.md +455 -0
- package/src/Popover/v2/index.tsx +645 -0
- package/src/Popover/v2/props.ts +354 -0
- package/src/Popover/v2/styles.ts +45 -0
- package/src/exports/a.ts +25 -0
- package/src/exports/b.ts +25 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Popover/v1/index.d.ts +83 -0
- package/types/Popover/v1/index.d.ts.map +1 -0
- package/types/Popover/v1/props.d.ts.map +1 -0
- package/types/Popover/v1/styles.d.ts.map +1 -0
- package/types/Popover/v1/theme.d.ts.map +1 -0
- package/types/Popover/v2/index.d.ts.map +1 -0
- package/types/Popover/v2/props.d.ts +225 -0
- package/types/Popover/v2/props.d.ts.map +1 -0
- package/types/Popover/v2/styles.d.ts +13 -0
- package/types/Popover/v2/styles.d.ts.map +1 -0
- package/types/exports/a.d.ts +3 -0
- package/types/exports/a.d.ts.map +1 -0
- package/types/exports/b.d.ts +3 -0
- package/types/exports/b.d.ts.map +1 -0
- package/types/Popover/index.d.ts.map +0 -1
- package/types/Popover/props.d.ts.map +0 -1
- package/types/Popover/styles.d.ts.map +0 -1
- package/types/Popover/theme.d.ts.map +0 -1
- package/types/index.d.ts +0 -3
- package/types/index.d.ts.map +0 -1
- /package/es/Popover/{props.js → v1/props.js} +0 -0
- /package/es/Popover/{styles.js → v1/styles.js} +0 -0
- /package/es/Popover/{theme.js → v1/theme.js} +0 -0
- /package/lib/Popover/{props.js → v1/props.js} +0 -0
- /package/lib/Popover/{styles.js → v1/styles.js} +0 -0
- /package/lib/Popover/{theme.js → v1/theme.js} +0 -0
- /package/src/Popover/{README.md → v1/README.md} +0 -0
- /package/src/Popover/{props.ts → v1/props.ts} +0 -0
- /package/src/Popover/{styles.ts → v1/styles.ts} +0 -0
- /package/src/Popover/{theme.ts → v1/theme.ts} +0 -0
- /package/types/Popover/{props.d.ts → v1/props.d.ts} +0 -0
- /package/types/Popover/{styles.d.ts → v1/styles.d.ts} +0 -0
- /package/types/Popover/{theme.d.ts → v1/theme.d.ts} +0 -0
- /package/types/Popover/{index.d.ts → v2/index.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-popover",
|
|
3
|
-
"version": "11.6.
|
|
3
|
+
"version": "11.6.1-snapshot-129",
|
|
4
4
|
"description": "A component for hiding or showing content based on user interaction.",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -16,28 +16,28 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@babel/runtime": "^7.27.6",
|
|
18
18
|
"keycode": "^2.2.1",
|
|
19
|
-
"@instructure/console": "11.6.
|
|
20
|
-
"@instructure/emotion": "11.6.
|
|
21
|
-
"@instructure/ui-a11y-utils": "11.6.
|
|
22
|
-
"@instructure/ui-dialog": "11.6.
|
|
23
|
-
"@instructure/shared-types": "11.6.
|
|
24
|
-
"@instructure/ui-dom-utils": "11.6.
|
|
25
|
-
"@instructure/ui-i18n": "11.6.
|
|
26
|
-
"@instructure/ui-position": "11.6.
|
|
27
|
-
"@instructure/ui-utils": "11.6.
|
|
28
|
-
"@instructure/ui-
|
|
29
|
-
"@instructure/
|
|
30
|
-
"@instructure/
|
|
19
|
+
"@instructure/console": "11.6.1-snapshot-129",
|
|
20
|
+
"@instructure/emotion": "11.6.1-snapshot-129",
|
|
21
|
+
"@instructure/ui-a11y-utils": "11.6.1-snapshot-129",
|
|
22
|
+
"@instructure/ui-dialog": "11.6.1-snapshot-129",
|
|
23
|
+
"@instructure/shared-types": "11.6.1-snapshot-129",
|
|
24
|
+
"@instructure/ui-dom-utils": "11.6.1-snapshot-129",
|
|
25
|
+
"@instructure/ui-i18n": "11.6.1-snapshot-129",
|
|
26
|
+
"@instructure/ui-position": "11.6.1-snapshot-129",
|
|
27
|
+
"@instructure/ui-react-utils": "11.6.1-snapshot-129",
|
|
28
|
+
"@instructure/ui-utils": "11.6.1-snapshot-129",
|
|
29
|
+
"@instructure/ui-view": "11.6.1-snapshot-129",
|
|
30
|
+
"@instructure/uid": "11.6.1-snapshot-129"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@testing-library/jest-dom": "^6.6.3",
|
|
34
34
|
"@testing-library/react": "15.0.7",
|
|
35
35
|
"@testing-library/user-event": "^14.6.1",
|
|
36
36
|
"vitest": "^3.2.2",
|
|
37
|
-
"@instructure/ui-axe-check": "11.6.
|
|
38
|
-
"@instructure/ui-babel-preset": "11.6.
|
|
39
|
-
"@instructure/ui-color-utils": "11.6.
|
|
40
|
-
"@instructure/ui-themes": "11.6.
|
|
37
|
+
"@instructure/ui-axe-check": "11.6.1-snapshot-129",
|
|
38
|
+
"@instructure/ui-babel-preset": "11.6.1-snapshot-129",
|
|
39
|
+
"@instructure/ui-color-utils": "11.6.1-snapshot-129",
|
|
40
|
+
"@instructure/ui-themes": "11.6.1-snapshot-129"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"react": ">=18 <=19"
|
|
@@ -47,17 +47,39 @@
|
|
|
47
47
|
},
|
|
48
48
|
"sideEffects": false,
|
|
49
49
|
"exports": {
|
|
50
|
-
".": {
|
|
51
|
-
"types": "./types/index.d.ts",
|
|
52
|
-
"import": "./es/index.js",
|
|
53
|
-
"require": "./lib/index.js",
|
|
54
|
-
"default": "./es/index.js"
|
|
55
|
-
},
|
|
56
50
|
"./lib/*": "./lib/*",
|
|
57
51
|
"./es/*": "./es/*",
|
|
58
52
|
"./types/*": "./types/*",
|
|
59
53
|
"./package.json": "./package.json",
|
|
60
|
-
"./src/*": "./src/*"
|
|
54
|
+
"./src/*": "./src/*",
|
|
55
|
+
".": {
|
|
56
|
+
"src": "./src/exports/a.ts",
|
|
57
|
+
"types": "./types/exports/a.d.ts",
|
|
58
|
+
"import": "./es/exports/a.js",
|
|
59
|
+
"require": "./lib/exports/a.js",
|
|
60
|
+
"default": "./es/exports/a.js"
|
|
61
|
+
},
|
|
62
|
+
"./v11_6": {
|
|
63
|
+
"src": "./src/exports/a.ts",
|
|
64
|
+
"types": "./types/exports/a.d.ts",
|
|
65
|
+
"import": "./es/exports/a.js",
|
|
66
|
+
"require": "./lib/exports/a.js",
|
|
67
|
+
"default": "./es/exports/a.js"
|
|
68
|
+
},
|
|
69
|
+
"./v11_7": {
|
|
70
|
+
"src": "./src/exports/b.ts",
|
|
71
|
+
"types": "./types/exports/b.d.ts",
|
|
72
|
+
"import": "./es/exports/b.js",
|
|
73
|
+
"require": "./lib/exports/b.js",
|
|
74
|
+
"default": "./es/exports/b.js"
|
|
75
|
+
},
|
|
76
|
+
"./latest": {
|
|
77
|
+
"src": "./src/exports/b.ts",
|
|
78
|
+
"types": "./types/exports/b.d.ts",
|
|
79
|
+
"import": "./es/exports/b.js",
|
|
80
|
+
"require": "./lib/exports/b.js",
|
|
81
|
+
"default": "./es/exports/b.js"
|
|
82
|
+
}
|
|
61
83
|
},
|
|
62
84
|
"scripts": {
|
|
63
85
|
"lint": "ui-scripts lint",
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
parsePlacement,
|
|
31
31
|
mirrorHorizontalPlacement
|
|
32
32
|
} from '@instructure/ui-position'
|
|
33
|
-
import { ContextView, View } from '@instructure/ui-view'
|
|
33
|
+
import { ContextView, View } from '@instructure/ui-view/v11_6'
|
|
34
34
|
import { Dialog } from '@instructure/ui-dialog'
|
|
35
35
|
import { textDirectionContextConsumer } from '@instructure/ui-i18n'
|
|
36
36
|
import {
|
|
@@ -55,17 +55,17 @@ import { logError as error } from '@instructure/console'
|
|
|
55
55
|
import { FocusRegion } from '@instructure/ui-a11y-utils'
|
|
56
56
|
|
|
57
57
|
import type { RequestAnimationFrameType } from '@instructure/ui-dom-utils'
|
|
58
|
-
import type { ViewProps, ContextViewProps } from '@instructure/ui-view'
|
|
58
|
+
import type { ViewProps, ContextViewProps } from '@instructure/ui-view/v11_6'
|
|
59
59
|
import type { PositionProps } from '@instructure/ui-position'
|
|
60
60
|
import type { DialogProps } from '@instructure/ui-dialog'
|
|
61
61
|
|
|
62
|
-
import { withStyle } from '@instructure/emotion'
|
|
62
|
+
import { withStyleLegacy as withStyle } from '@instructure/emotion'
|
|
63
63
|
|
|
64
64
|
import generateStyle from './styles'
|
|
65
65
|
import generateComponentTheme from './theme'
|
|
66
66
|
|
|
67
|
-
import type { PopoverProps, PopoverState } from '
|
|
68
|
-
import { allowedProps } from '
|
|
67
|
+
import type { PopoverProps, PopoverState } from '../v1/props'
|
|
68
|
+
import { allowedProps } from '../v1/props'
|
|
69
69
|
import type { Renderable } from '@instructure/shared-types'
|
|
70
70
|
/**
|
|
71
71
|
---
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
---
|
|
2
|
+
describes: Popover
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Popovers hide or show content as a result of user interaction, such as clicking, hovering, or focusing. When opened, the content remains connected to the element that triggered it. If you only need to display a small amount of text-only content, you might consider using a [Tooltip](Tooltip). If you need to display a larger amount of content, a [Tray](Tray) could be a better choice.
|
|
6
|
+
|
|
7
|
+
#### Uncontrolled Popover
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
---
|
|
11
|
+
type: example
|
|
12
|
+
---
|
|
13
|
+
const Example = () => {
|
|
14
|
+
const [withArrow, setWithArrow] = useState(true)
|
|
15
|
+
const [shouldAlignArrow, setShouldAlignArrow] = useState(true)
|
|
16
|
+
const [color, setColor] = useState('primary')
|
|
17
|
+
|
|
18
|
+
const toggleWithArrow = () => {
|
|
19
|
+
setWithArrow((withArrow) => !withArrow)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const toggleAlignArrow = () => {
|
|
23
|
+
setShouldAlignArrow((shouldAlignArrow) => !shouldAlignArrow)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const changeColor = (event, color) => {
|
|
27
|
+
setColor(color)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<>
|
|
32
|
+
<FormFieldGroup description="Uncontrolled Popover Example">
|
|
33
|
+
<Checkbox
|
|
34
|
+
checked={withArrow}
|
|
35
|
+
label="With Arrow"
|
|
36
|
+
onChange={toggleWithArrow}
|
|
37
|
+
/>
|
|
38
|
+
<Checkbox
|
|
39
|
+
checked={shouldAlignArrow}
|
|
40
|
+
label="Align Arrow"
|
|
41
|
+
onChange={toggleAlignArrow}
|
|
42
|
+
/>
|
|
43
|
+
</FormFieldGroup>
|
|
44
|
+
<View display="block" margin="small none">
|
|
45
|
+
<RadioInputGroup
|
|
46
|
+
name="color"
|
|
47
|
+
defaultValue="primary"
|
|
48
|
+
description="Color:"
|
|
49
|
+
variant="toggle"
|
|
50
|
+
size="small"
|
|
51
|
+
onChange={changeColor}
|
|
52
|
+
>
|
|
53
|
+
<RadioInput label="Primary" value="primary" />
|
|
54
|
+
<RadioInput label="Primary inverse" value="primary-inverse" />
|
|
55
|
+
</RadioInputGroup>
|
|
56
|
+
</View>
|
|
57
|
+
<View display="block" as="div" margin="small">
|
|
58
|
+
<Popover
|
|
59
|
+
renderTrigger={
|
|
60
|
+
<Link aria-describedby="tip">Hover or focus me</Link>
|
|
61
|
+
}
|
|
62
|
+
shouldRenderOffscreen
|
|
63
|
+
shouldReturnFocus={false}
|
|
64
|
+
withArrow={withArrow}
|
|
65
|
+
shouldAlignArrow={shouldAlignArrow}
|
|
66
|
+
color={color}
|
|
67
|
+
placement="top end"
|
|
68
|
+
onPositioned={() => console.log('positioned')}
|
|
69
|
+
onShowContent={() => console.log('showing')}
|
|
70
|
+
onHideContent={() => console.log('hidden')}
|
|
71
|
+
>
|
|
72
|
+
<View padding="x-small" display="block" as="div" id="tip">
|
|
73
|
+
Hello World
|
|
74
|
+
</View>
|
|
75
|
+
</Popover>
|
|
76
|
+
</View>
|
|
77
|
+
</>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
render(<Example />)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Controlled Popover
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
---
|
|
87
|
+
type: example
|
|
88
|
+
---
|
|
89
|
+
const Example = () => {
|
|
90
|
+
const [isShowingContent, setIsShowingContent] = useState(false)
|
|
91
|
+
|
|
92
|
+
const usernameRef = useRef(null)
|
|
93
|
+
|
|
94
|
+
const renderCloseButton = () => (
|
|
95
|
+
<CloseButton
|
|
96
|
+
placement="end"
|
|
97
|
+
offset="small"
|
|
98
|
+
onClick={() => setIsShowingContent(false)}
|
|
99
|
+
screenReaderLabel="Close"
|
|
100
|
+
/>
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<View>
|
|
105
|
+
<Popover
|
|
106
|
+
renderTrigger={<Button>Sign In</Button>}
|
|
107
|
+
isShowingContent={isShowingContent}
|
|
108
|
+
onShowContent={() => {
|
|
109
|
+
setIsShowingContent(true)
|
|
110
|
+
}}
|
|
111
|
+
onHideContent={() => {
|
|
112
|
+
setIsShowingContent(false)
|
|
113
|
+
}}
|
|
114
|
+
on="click"
|
|
115
|
+
screenReaderLabel="Popover Dialog Example"
|
|
116
|
+
shouldContainFocus
|
|
117
|
+
shouldReturnFocus
|
|
118
|
+
shouldCloseOnDocumentClick
|
|
119
|
+
offsetY="16px"
|
|
120
|
+
>
|
|
121
|
+
<View padding="medium" display="block" as="form">
|
|
122
|
+
{renderCloseButton()}
|
|
123
|
+
<FormFieldGroup description="Log In">
|
|
124
|
+
<TextInput renderLabel="Username" ref={usernameRef} />
|
|
125
|
+
<TextInput renderLabel="Password" type="password" />
|
|
126
|
+
</FormFieldGroup>
|
|
127
|
+
</View>
|
|
128
|
+
</Popover>
|
|
129
|
+
</View>
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
render(<Example />)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
> Note: Popover can act as a dialog with a close button. With the `shouldContainFocus` property set, it will trap focus inside the Popover.
|
|
137
|
+
|
|
138
|
+
The `shouldAlignArrow` prop will offset the popover content to adjust for the offset of the arrow. This will override offsetX for start/end placements, and will override offsetY for top/bottom placements.
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
---
|
|
142
|
+
type: example
|
|
143
|
+
---
|
|
144
|
+
const Example = () => {
|
|
145
|
+
const [shouldAlignArrow, setShouldAlignArrow] = useState(true)
|
|
146
|
+
|
|
147
|
+
const toggleAlignArrow = () => {
|
|
148
|
+
setShouldAlignArrow((shouldAlignArrow) => !shouldAlignArrow)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return (
|
|
152
|
+
<>
|
|
153
|
+
<FormFieldGroup description="Align Arrow Example">
|
|
154
|
+
<Checkbox
|
|
155
|
+
checked={shouldAlignArrow}
|
|
156
|
+
label="Align Arrow"
|
|
157
|
+
onChange={toggleAlignArrow}
|
|
158
|
+
/>
|
|
159
|
+
</FormFieldGroup>
|
|
160
|
+
<div
|
|
161
|
+
style={{
|
|
162
|
+
paddingBottom: 25,
|
|
163
|
+
display: 'flex',
|
|
164
|
+
justifyContent: 'center'
|
|
165
|
+
}}
|
|
166
|
+
>
|
|
167
|
+
<Popover
|
|
168
|
+
renderTrigger={
|
|
169
|
+
<div
|
|
170
|
+
style={{
|
|
171
|
+
display: 'inline-block',
|
|
172
|
+
height: '3px',
|
|
173
|
+
width: '3px',
|
|
174
|
+
background: 'blue'
|
|
175
|
+
}}
|
|
176
|
+
/>
|
|
177
|
+
}
|
|
178
|
+
isShowingContent={true}
|
|
179
|
+
placement="end top"
|
|
180
|
+
shouldAlignArrow={shouldAlignArrow}
|
|
181
|
+
>
|
|
182
|
+
<Heading>
|
|
183
|
+
Small
|
|
184
|
+
<br />
|
|
185
|
+
Target
|
|
186
|
+
</Heading>
|
|
187
|
+
</Popover>
|
|
188
|
+
</div>
|
|
189
|
+
</>
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
render(<Example />)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
If the `Popover` contains focusable content and should be rendered in the focus order immediately after the trigger, it can be configured using the `shouldFocusContentOnTriggerBlur` prop. Note that the content must be rendered in the correct order in the document (using the `mountNode` prop).
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
---
|
|
200
|
+
type: example
|
|
201
|
+
---
|
|
202
|
+
const Example = () => {
|
|
203
|
+
const [isShowingContent, setIsShowingContent] = useState(false)
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
<div
|
|
207
|
+
style={{ paddingBottom: 50, display: 'flex', justifyContent: 'center' }}
|
|
208
|
+
>
|
|
209
|
+
<Popover
|
|
210
|
+
renderTrigger={<Button margin="small">Focus Me</Button>}
|
|
211
|
+
isShowingContent={isShowingContent}
|
|
212
|
+
onShowContent={() => {
|
|
213
|
+
setIsShowingContent(true)
|
|
214
|
+
}}
|
|
215
|
+
onHideContent={() => {
|
|
216
|
+
setIsShowingContent(false)
|
|
217
|
+
}}
|
|
218
|
+
on={['hover', 'focus']}
|
|
219
|
+
shouldContainFocus={false}
|
|
220
|
+
shouldFocusContentOnTriggerBlur={false}
|
|
221
|
+
>
|
|
222
|
+
<Button margin="small">Focus Me When Trigger Blurs</Button>
|
|
223
|
+
</Popover>
|
|
224
|
+
<div id="container" />
|
|
225
|
+
<Button id="next" margin="small">
|
|
226
|
+
Focus Me Next
|
|
227
|
+
</Button>
|
|
228
|
+
</div>
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
render(<Example />)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
#### Custom elements as renderTrigger
|
|
236
|
+
|
|
237
|
+
Popover and Tooltip attach mouse and focus event listeners to their `renderTrigger` components via props. These need to be propagated to the component for the listeners to work:
|
|
238
|
+
|
|
239
|
+
```js
|
|
240
|
+
---
|
|
241
|
+
type: example
|
|
242
|
+
---
|
|
243
|
+
const MyComponent = React.forwardRef((props, ref) => {
|
|
244
|
+
return (
|
|
245
|
+
<div {...props} ref={ref} style={{ width: '10rem' }}>
|
|
246
|
+
My custom component
|
|
247
|
+
</div>
|
|
248
|
+
)
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
render(<MyComponent />)
|
|
252
|
+
;<Popover renderTrigger={<MyComponent />}>
|
|
253
|
+
This text is wrapped by a Popover
|
|
254
|
+
</Popover>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### Popover playground
|
|
258
|
+
|
|
259
|
+
```js
|
|
260
|
+
---
|
|
261
|
+
type: example
|
|
262
|
+
---
|
|
263
|
+
const placementsValues = [
|
|
264
|
+
'top',
|
|
265
|
+
'end',
|
|
266
|
+
'bottom',
|
|
267
|
+
'start',
|
|
268
|
+
'top start',
|
|
269
|
+
'start top',
|
|
270
|
+
'start center',
|
|
271
|
+
'start bottom',
|
|
272
|
+
'bottom start',
|
|
273
|
+
'bottom center',
|
|
274
|
+
'bottom end',
|
|
275
|
+
'end bottom',
|
|
276
|
+
'end center',
|
|
277
|
+
'end top',
|
|
278
|
+
'top end',
|
|
279
|
+
'top center',
|
|
280
|
+
'center end',
|
|
281
|
+
'center start'
|
|
282
|
+
]
|
|
283
|
+
|
|
284
|
+
const shadowValues = ['none', 'resting', 'above', 'topmost']
|
|
285
|
+
|
|
286
|
+
const Example = () => {
|
|
287
|
+
const [shouldAlignArrow, setShouldAlignArrow] = useState(true)
|
|
288
|
+
const [isShowingContent, setIsShowingContent] = useState(true)
|
|
289
|
+
const [withArrow, setWithArrow] = useState(true)
|
|
290
|
+
const [placement, setPlacement] = useState('top')
|
|
291
|
+
const [shadow, setShadow] = useState('topmost')
|
|
292
|
+
const [color, setColor] = useState('primary')
|
|
293
|
+
|
|
294
|
+
const changePlacement = (e, { value }) => {
|
|
295
|
+
setPlacement(value)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const changeShadow = (e, { value }) => {
|
|
299
|
+
setShadow(value)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const toggleWithArrow = () => {
|
|
303
|
+
setWithArrow((withArrow) => !withArrow)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const toggleAlignArrow = () => {
|
|
307
|
+
setShouldAlignArrow((shouldAlignArrow) => !shouldAlignArrow)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const toggleShowContent = () =>
|
|
311
|
+
setIsShowingContent((isShowingContent) => !isShowingContent)
|
|
312
|
+
|
|
313
|
+
const changeColor = (event, value) => {
|
|
314
|
+
setColor(value)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return (
|
|
318
|
+
<View as="div" background="primary" padding="small">
|
|
319
|
+
<Flex margin="small small large" justifyItems="space-around">
|
|
320
|
+
<Flex.Item align="start">
|
|
321
|
+
<FormFieldGroup description="Popover Example">
|
|
322
|
+
<Checkbox
|
|
323
|
+
checked={isShowingContent}
|
|
324
|
+
label="Show Content"
|
|
325
|
+
onChange={toggleShowContent}
|
|
326
|
+
/>
|
|
327
|
+
<Checkbox
|
|
328
|
+
checked={withArrow}
|
|
329
|
+
label="With Arrow"
|
|
330
|
+
onChange={toggleWithArrow}
|
|
331
|
+
/>
|
|
332
|
+
<Checkbox
|
|
333
|
+
checked={shouldAlignArrow}
|
|
334
|
+
label="Align Arrow"
|
|
335
|
+
onChange={toggleAlignArrow}
|
|
336
|
+
/>
|
|
337
|
+
</FormFieldGroup>
|
|
338
|
+
</Flex.Item>
|
|
339
|
+
<Flex.Item>
|
|
340
|
+
<View as="div" margin="none" maxWidth="15rem">
|
|
341
|
+
<SimpleSelect
|
|
342
|
+
renderLabel="Placement"
|
|
343
|
+
value={placement}
|
|
344
|
+
onChange={changePlacement}
|
|
345
|
+
>
|
|
346
|
+
{placementsValues.map((placement, index) => (
|
|
347
|
+
<SimpleSelect.Option
|
|
348
|
+
key={index}
|
|
349
|
+
id={`${index}`}
|
|
350
|
+
value={placement}
|
|
351
|
+
>
|
|
352
|
+
{placement}
|
|
353
|
+
</SimpleSelect.Option>
|
|
354
|
+
))}
|
|
355
|
+
</SimpleSelect>
|
|
356
|
+
</View>
|
|
357
|
+
<View as="div" margin="medium none" maxWidth="15rem">
|
|
358
|
+
<SimpleSelect
|
|
359
|
+
value={shadow}
|
|
360
|
+
onChange={changeShadow}
|
|
361
|
+
renderLabel="Shadow"
|
|
362
|
+
>
|
|
363
|
+
{shadowValues.map((shadow, index) => (
|
|
364
|
+
<SimpleSelect.Option
|
|
365
|
+
key={index}
|
|
366
|
+
id={`${index}`}
|
|
367
|
+
value={shadow}
|
|
368
|
+
>
|
|
369
|
+
{shadow}
|
|
370
|
+
</SimpleSelect.Option>
|
|
371
|
+
))}
|
|
372
|
+
</SimpleSelect>
|
|
373
|
+
</View>
|
|
374
|
+
</Flex.Item>
|
|
375
|
+
<Flex.Item align="start">
|
|
376
|
+
<View as="div" margin="none">
|
|
377
|
+
<RadioInputGroup
|
|
378
|
+
name="changeColor"
|
|
379
|
+
defaultValue="primary"
|
|
380
|
+
description="Color:"
|
|
381
|
+
variant="toggle"
|
|
382
|
+
size="small"
|
|
383
|
+
onChange={changeColor}
|
|
384
|
+
>
|
|
385
|
+
<RadioInput label="Primary" value="primary" />
|
|
386
|
+
<RadioInput label="Primary inverse" value="primary-inverse" />
|
|
387
|
+
</RadioInputGroup>
|
|
388
|
+
</View>
|
|
389
|
+
</Flex.Item>
|
|
390
|
+
</Flex>
|
|
391
|
+
<View as="div" display="block" padding="large" textAlign="center">
|
|
392
|
+
<Popover
|
|
393
|
+
renderTrigger={
|
|
394
|
+
<div
|
|
395
|
+
style={{
|
|
396
|
+
display: 'inline-block',
|
|
397
|
+
height: '3px',
|
|
398
|
+
width: '3px',
|
|
399
|
+
background: 'blue'
|
|
400
|
+
}}
|
|
401
|
+
/>
|
|
402
|
+
}
|
|
403
|
+
isShowingContent={isShowingContent}
|
|
404
|
+
placement={placement}
|
|
405
|
+
withArrow={withArrow}
|
|
406
|
+
shouldAlignArrow={shouldAlignArrow}
|
|
407
|
+
shadow={shadow}
|
|
408
|
+
color={color}
|
|
409
|
+
>
|
|
410
|
+
<Heading>
|
|
411
|
+
Small
|
|
412
|
+
<br />
|
|
413
|
+
Target
|
|
414
|
+
</Heading>
|
|
415
|
+
</Popover>
|
|
416
|
+
</View>
|
|
417
|
+
</View>
|
|
418
|
+
)
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
render(<Example />)
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Guidelines
|
|
425
|
+
|
|
426
|
+
```js
|
|
427
|
+
---
|
|
428
|
+
type: embed
|
|
429
|
+
---
|
|
430
|
+
<Guidelines>
|
|
431
|
+
<Figure recommendation="yes" title="Do">
|
|
432
|
+
<Figure.Item>Consider using a <Link href="/#Tray">Tray</Link> if the content is beyond a mobile screen size</Figure.Item>
|
|
433
|
+
</Figure>
|
|
434
|
+
<Figure recommendation="no" title="Don't">
|
|
435
|
+
<Figure.Item>Put content on the same row as the close "x"</Figure.Item>
|
|
436
|
+
<Figure.Item>Use with an <Link href="#Overlay">Overlay</Link></Figure.Item>
|
|
437
|
+
<Figure.Item>Have multiple Popovers open at the same time</Figure.Item>
|
|
438
|
+
<Figure.Item>Use in place of a <Link href="/#Tooltip">Tooltip</Link> or <Link href="/#Menu">Menu</Link></Figure.Item>
|
|
439
|
+
</Figure>
|
|
440
|
+
</Guidelines>
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
```js
|
|
444
|
+
---
|
|
445
|
+
type: embed
|
|
446
|
+
---
|
|
447
|
+
<Guidelines>
|
|
448
|
+
<Figure recommendation="a11y" title="Accessibility">
|
|
449
|
+
<Figure.Item>Keyboard focus must be set in the popover when it appears; usually on the first interactive element</Figure.Item>
|
|
450
|
+
<Figure.Item>Popovers must contain keyboard focus until they’re closed. This is to ensure that keyboard or screen reader users won't mistakenly interact with background content that is meant to be hidden or inaccessible</Figure.Item>
|
|
451
|
+
<Figure.Item>When a user closes the Popover, focus must return to a logical place within the page. This is usually the element that triggered opening the popover</Figure.Item>
|
|
452
|
+
<Figure.Item>Popovers should be able to be closed by clicking away, esc key and/or a close button</Figure.Item>
|
|
453
|
+
</Figure>
|
|
454
|
+
</Guidelines>
|
|
455
|
+
```
|