@instructure/ui-popover 10.2.3-snapshot-2 → 10.2.3-snapshot-5
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 +1 -1
- package/package.json +20 -20
- package/src/Popover/README.md +599 -204
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
## [10.2.3-snapshot-
|
|
6
|
+
## [10.2.3-snapshot-5](https://github.com/instructure/instructure-ui/compare/v10.2.2...v10.2.3-snapshot-5) (2024-09-24)
|
|
7
7
|
|
|
8
8
|
**Note:** Version bump only for package @instructure/ui-popover
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-popover",
|
|
3
|
-
"version": "10.2.3-snapshot-
|
|
3
|
+
"version": "10.2.3-snapshot-5",
|
|
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",
|
|
@@ -24,29 +24,29 @@
|
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@babel/runtime": "^7.24.5",
|
|
27
|
-
"@instructure/console": "10.2.3-snapshot-
|
|
28
|
-
"@instructure/emotion": "10.2.3-snapshot-
|
|
29
|
-
"@instructure/shared-types": "10.2.3-snapshot-
|
|
30
|
-
"@instructure/ui-a11y-utils": "10.2.3-snapshot-
|
|
31
|
-
"@instructure/ui-dialog": "10.2.3-snapshot-
|
|
32
|
-
"@instructure/ui-dom-utils": "10.2.3-snapshot-
|
|
33
|
-
"@instructure/ui-i18n": "10.2.3-snapshot-
|
|
34
|
-
"@instructure/ui-position": "10.2.3-snapshot-
|
|
35
|
-
"@instructure/ui-prop-types": "10.2.3-snapshot-
|
|
36
|
-
"@instructure/ui-react-utils": "10.2.3-snapshot-
|
|
37
|
-
"@instructure/ui-testable": "10.2.3-snapshot-
|
|
38
|
-
"@instructure/ui-utils": "10.2.3-snapshot-
|
|
39
|
-
"@instructure/ui-view": "10.2.3-snapshot-
|
|
40
|
-
"@instructure/uid": "10.2.3-snapshot-
|
|
27
|
+
"@instructure/console": "10.2.3-snapshot-5",
|
|
28
|
+
"@instructure/emotion": "10.2.3-snapshot-5",
|
|
29
|
+
"@instructure/shared-types": "10.2.3-snapshot-5",
|
|
30
|
+
"@instructure/ui-a11y-utils": "10.2.3-snapshot-5",
|
|
31
|
+
"@instructure/ui-dialog": "10.2.3-snapshot-5",
|
|
32
|
+
"@instructure/ui-dom-utils": "10.2.3-snapshot-5",
|
|
33
|
+
"@instructure/ui-i18n": "10.2.3-snapshot-5",
|
|
34
|
+
"@instructure/ui-position": "10.2.3-snapshot-5",
|
|
35
|
+
"@instructure/ui-prop-types": "10.2.3-snapshot-5",
|
|
36
|
+
"@instructure/ui-react-utils": "10.2.3-snapshot-5",
|
|
37
|
+
"@instructure/ui-testable": "10.2.3-snapshot-5",
|
|
38
|
+
"@instructure/ui-utils": "10.2.3-snapshot-5",
|
|
39
|
+
"@instructure/ui-view": "10.2.3-snapshot-5",
|
|
40
|
+
"@instructure/uid": "10.2.3-snapshot-5",
|
|
41
41
|
"keycode": "^2.2.1",
|
|
42
42
|
"prop-types": "^15.8.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@instructure/ui-babel-preset": "10.2.3-snapshot-
|
|
46
|
-
"@instructure/ui-color-utils": "10.2.3-snapshot-
|
|
47
|
-
"@instructure/ui-test-locator": "10.2.3-snapshot-
|
|
48
|
-
"@instructure/ui-test-queries": "10.2.3-snapshot-
|
|
49
|
-
"@instructure/ui-test-utils": "10.2.3-snapshot-
|
|
45
|
+
"@instructure/ui-babel-preset": "10.2.3-snapshot-5",
|
|
46
|
+
"@instructure/ui-color-utils": "10.2.3-snapshot-5",
|
|
47
|
+
"@instructure/ui-test-locator": "10.2.3-snapshot-5",
|
|
48
|
+
"@instructure/ui-test-queries": "10.2.3-snapshot-5",
|
|
49
|
+
"@instructure/ui-test-utils": "10.2.3-snapshot-5",
|
|
50
50
|
"@testing-library/jest-dom": "^6.4.6",
|
|
51
51
|
"@testing-library/react": "^15.0.7",
|
|
52
52
|
"@testing-library/user-event": "^14.5.2",
|
package/src/Popover/README.md
CHANGED
|
@@ -6,32 +6,105 @@ Popovers hide or show content as a result of user interaction, such as clicking,
|
|
|
6
6
|
|
|
7
7
|
#### Uncontrolled Popover
|
|
8
8
|
|
|
9
|
-
```js
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
- ```js
|
|
10
|
+
class Example extends React.Component {
|
|
11
|
+
state = {
|
|
12
|
+
withArrow: true,
|
|
13
|
+
shouldAlignArrow: true,
|
|
14
|
+
color: 'primary'
|
|
15
|
+
}
|
|
16
|
+
toggleWithArrow = (event) =>
|
|
17
|
+
this.setState({ withArrow: !this.state.withArrow })
|
|
18
|
+
toggleAlignArrow = (event) =>
|
|
19
|
+
this.setState({ shouldAlignArrow: !this.state.shouldAlignArrow })
|
|
20
|
+
changeColor = (event, color) => {
|
|
21
|
+
this.setState({ color })
|
|
22
|
+
}
|
|
23
|
+
render() {
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
<FormFieldGroup description="Uncontrolled Popover Example">
|
|
27
|
+
<Checkbox
|
|
28
|
+
checked={this.state.withArrow}
|
|
29
|
+
label="With Arrow"
|
|
30
|
+
onChange={this.toggleWithArrow}
|
|
31
|
+
/>
|
|
32
|
+
<Checkbox
|
|
33
|
+
checked={this.state.shouldAlignArrow}
|
|
34
|
+
label="Align Arrow"
|
|
35
|
+
onChange={this.toggleAlignArrow}
|
|
36
|
+
/>
|
|
37
|
+
</FormFieldGroup>
|
|
38
|
+
<View display="block" margin="small none">
|
|
39
|
+
<RadioInputGroup
|
|
40
|
+
name="color"
|
|
41
|
+
defaultValue="primary"
|
|
42
|
+
description="Color:"
|
|
43
|
+
variant="toggle"
|
|
44
|
+
size="small"
|
|
45
|
+
onChange={this.changeColor}
|
|
46
|
+
>
|
|
47
|
+
<RadioInput label="Primary" value="primary" />
|
|
48
|
+
<RadioInput label="Primary inverse" value="primary-inverse" />
|
|
49
|
+
</RadioInputGroup>
|
|
50
|
+
</View>
|
|
51
|
+
<View display="block" as="div" margin="small">
|
|
52
|
+
<Popover
|
|
53
|
+
renderTrigger={
|
|
54
|
+
<Link aria-describedby="tip">Hover or focus me</Link>
|
|
55
|
+
}
|
|
56
|
+
shouldRenderOffscreen
|
|
57
|
+
shouldReturnFocus={false}
|
|
58
|
+
withArrow={this.state.withArrow}
|
|
59
|
+
shouldAlignArrow={this.state.shouldAlignArrow}
|
|
60
|
+
color={this.state.color}
|
|
61
|
+
placement="top end"
|
|
62
|
+
onPositioned={() => console.log('positioned')}
|
|
63
|
+
onShowContent={() => console.log('showing')}
|
|
64
|
+
onHideContent={() => console.log('hidden')}
|
|
65
|
+
>
|
|
66
|
+
<View padding="x-small" display="block" as="div" id="tip">
|
|
67
|
+
Hello World
|
|
68
|
+
</View>
|
|
69
|
+
</Popover>
|
|
70
|
+
</View>
|
|
71
|
+
</>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
18
74
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
75
|
+
render(<Example />)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- ```js
|
|
79
|
+
const Example = () => {
|
|
80
|
+
const [withArrow, setWithArrow] = useState(true)
|
|
81
|
+
const [shouldAlignArrow, setShouldAlignArrow] = useState(true)
|
|
82
|
+
const [color, setColor] = useState('primary')
|
|
83
|
+
|
|
84
|
+
const toggleWithArrow = () => {
|
|
85
|
+
setWithArrow((withArrow) => !withArrow)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const toggleAlignArrow = () => {
|
|
89
|
+
setShouldAlignArrow((shouldAlignArrow) => !shouldAlignArrow)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const changeColor = (event, color) => {
|
|
93
|
+
setColor(color)
|
|
94
|
+
}
|
|
95
|
+
|
|
23
96
|
return (
|
|
24
97
|
<>
|
|
25
98
|
<FormFieldGroup description="Uncontrolled Popover Example">
|
|
26
99
|
<Checkbox
|
|
27
|
-
checked={
|
|
100
|
+
checked={withArrow}
|
|
28
101
|
label="With Arrow"
|
|
29
|
-
onChange={
|
|
102
|
+
onChange={toggleWithArrow}
|
|
30
103
|
/>
|
|
31
104
|
<Checkbox
|
|
32
|
-
checked={
|
|
105
|
+
checked={shouldAlignArrow}
|
|
33
106
|
label="Align Arrow"
|
|
34
|
-
onChange={
|
|
107
|
+
onChange={toggleAlignArrow}
|
|
35
108
|
/>
|
|
36
109
|
</FormFieldGroup>
|
|
37
110
|
<View display="block" margin="small none">
|
|
@@ -41,25 +114,23 @@ class Example extends React.Component {
|
|
|
41
114
|
description="Color:"
|
|
42
115
|
variant="toggle"
|
|
43
116
|
size="small"
|
|
44
|
-
onChange={
|
|
45
|
-
|
|
117
|
+
onChange={changeColor}
|
|
118
|
+
>
|
|
119
|
+
<RadioInput label="Primary" value="primary" />
|
|
46
120
|
<RadioInput label="Primary inverse" value="primary-inverse" />
|
|
47
121
|
</RadioInputGroup>
|
|
48
122
|
</View>
|
|
49
123
|
<View display="block" as="div" margin="small">
|
|
50
124
|
<Popover
|
|
51
125
|
renderTrigger={
|
|
52
|
-
<Link aria-describedby="tip">
|
|
53
|
-
Hover or focus me
|
|
54
|
-
</Link>
|
|
126
|
+
<Link aria-describedby="tip">Hover or focus me</Link>
|
|
55
127
|
}
|
|
56
128
|
shouldRenderOffscreen
|
|
57
129
|
shouldReturnFocus={false}
|
|
58
|
-
withArrow={
|
|
59
|
-
shouldAlignArrow={
|
|
60
|
-
color
|
|
61
|
-
placement
|
|
62
|
-
mountNode={() => document.getElementById('main')}
|
|
130
|
+
withArrow={withArrow}
|
|
131
|
+
shouldAlignArrow={shouldAlignArrow}
|
|
132
|
+
color={color}
|
|
133
|
+
placement="top end"
|
|
63
134
|
onPositioned={() => console.log('positioned')}
|
|
64
135
|
onShowContent={() => console.log('showing')}
|
|
65
136
|
onHideContent={() => console.log('hidden')}
|
|
@@ -72,46 +143,95 @@ class Example extends React.Component {
|
|
|
72
143
|
</>
|
|
73
144
|
)
|
|
74
145
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
```
|
|
146
|
+
render(<Example />)
|
|
147
|
+
```
|
|
79
148
|
|
|
80
149
|
#### Controlled Popover
|
|
81
150
|
|
|
82
|
-
```js
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
151
|
+
- ```js
|
|
152
|
+
class Example extends React.Component {
|
|
153
|
+
state = {
|
|
154
|
+
isShowingContent: false
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
renderCloseButton() {
|
|
158
|
+
return (
|
|
159
|
+
<CloseButton
|
|
160
|
+
placement="end"
|
|
161
|
+
offset="small"
|
|
162
|
+
onClick={() => this.setState({ isShowingContent: false })}
|
|
163
|
+
screenReaderLabel="Close"
|
|
164
|
+
/>
|
|
165
|
+
)
|
|
166
|
+
}
|
|
87
167
|
|
|
88
|
-
|
|
89
|
-
|
|
168
|
+
render() {
|
|
169
|
+
return (
|
|
170
|
+
<View>
|
|
171
|
+
<Popover
|
|
172
|
+
renderTrigger={<Button>Sign In</Button>}
|
|
173
|
+
isShowingContent={this.state.isShowingContent}
|
|
174
|
+
onShowContent={(e) => {
|
|
175
|
+
this.setState({ isShowingContent: true })
|
|
176
|
+
}}
|
|
177
|
+
onHideContent={(e, { documentClick }) => {
|
|
178
|
+
this.setState({ isShowingContent: false })
|
|
179
|
+
}}
|
|
180
|
+
on="click"
|
|
181
|
+
screenReaderLabel="Popover Dialog Example"
|
|
182
|
+
shouldContainFocus
|
|
183
|
+
shouldReturnFocus
|
|
184
|
+
shouldCloseOnDocumentClick
|
|
185
|
+
offsetY="16px"
|
|
186
|
+
>
|
|
187
|
+
<View padding="medium" display="block" as="form">
|
|
188
|
+
{this.renderCloseButton()}
|
|
189
|
+
<FormFieldGroup description="Log In">
|
|
190
|
+
<TextInput
|
|
191
|
+
renderLabel="Username"
|
|
192
|
+
inputRef={(el) => {
|
|
193
|
+
if (el) {
|
|
194
|
+
this._username = el
|
|
195
|
+
}
|
|
196
|
+
}}
|
|
197
|
+
/>
|
|
198
|
+
<TextInput renderLabel="Password" type="password" />
|
|
199
|
+
</FormFieldGroup>
|
|
200
|
+
</View>
|
|
201
|
+
</Popover>
|
|
202
|
+
</View>
|
|
203
|
+
)
|
|
204
|
+
}
|
|
90
205
|
}
|
|
91
206
|
|
|
207
|
+
render(<Example />)
|
|
208
|
+
```
|
|
92
209
|
|
|
93
|
-
|
|
94
|
-
|
|
210
|
+
- ```js
|
|
211
|
+
const Example = () => {
|
|
212
|
+
const [isShowingContent, setIsShowingContent] = useState(false)
|
|
213
|
+
|
|
214
|
+
const usernameRef = useRef(null)
|
|
215
|
+
|
|
216
|
+
const renderCloseButton = () => (
|
|
95
217
|
<CloseButton
|
|
96
218
|
placement="end"
|
|
97
219
|
offset="small"
|
|
98
|
-
onClick={() =>
|
|
220
|
+
onClick={() => setIsShowingContent(false)}
|
|
99
221
|
screenReaderLabel="Close"
|
|
100
222
|
/>
|
|
101
223
|
)
|
|
102
|
-
}
|
|
103
224
|
|
|
104
|
-
render () {
|
|
105
225
|
return (
|
|
106
226
|
<View>
|
|
107
227
|
<Popover
|
|
108
228
|
renderTrigger={<Button>Sign In</Button>}
|
|
109
|
-
isShowingContent={
|
|
110
|
-
onShowContent={(
|
|
111
|
-
|
|
229
|
+
isShowingContent={isShowingContent}
|
|
230
|
+
onShowContent={() => {
|
|
231
|
+
setIsShowingContent(true)
|
|
112
232
|
}}
|
|
113
|
-
onHideContent={(
|
|
114
|
-
|
|
233
|
+
onHideContent={() => {
|
|
234
|
+
setIsShowingContent(false)
|
|
115
235
|
}}
|
|
116
236
|
on="click"
|
|
117
237
|
screenReaderLabel="Popover Dialog Example"
|
|
@@ -119,12 +239,11 @@ class Example extends React.Component {
|
|
|
119
239
|
shouldReturnFocus
|
|
120
240
|
shouldCloseOnDocumentClick
|
|
121
241
|
offsetY="16px"
|
|
122
|
-
mountNode={() => document.getElementById('main')}
|
|
123
242
|
>
|
|
124
243
|
<View padding="medium" display="block" as="form">
|
|
125
|
-
{
|
|
244
|
+
{renderCloseButton()}
|
|
126
245
|
<FormFieldGroup description="Log In">
|
|
127
|
-
<TextInput renderLabel="Username"
|
|
246
|
+
<TextInput renderLabel="Username" ref={usernameRef} />
|
|
128
247
|
<TextInput renderLabel="Password" type="password" />
|
|
129
248
|
</FormFieldGroup>
|
|
130
249
|
</View>
|
|
@@ -132,136 +251,252 @@ class Example extends React.Component {
|
|
|
132
251
|
</View>
|
|
133
252
|
)
|
|
134
253
|
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
render(<Example />)
|
|
138
254
|
|
|
139
|
-
|
|
255
|
+
render(<Example />)
|
|
256
|
+
```
|
|
140
257
|
|
|
141
258
|
> Note: Popover can act as a dialog with a close button. With the `shouldContainFocus` property set, it will trap focus inside the Popover.
|
|
142
259
|
|
|
143
260
|
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.
|
|
144
261
|
|
|
145
|
-
```js
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
262
|
+
- ```js
|
|
263
|
+
class Example extends React.Component {
|
|
264
|
+
state = {
|
|
265
|
+
shouldAlignArrow: true
|
|
266
|
+
}
|
|
267
|
+
toggleAlignArrow = (event) =>
|
|
268
|
+
this.setState({ shouldAlignArrow: !this.state.shouldAlignArrow })
|
|
269
|
+
|
|
270
|
+
render() {
|
|
271
|
+
return (
|
|
272
|
+
<>
|
|
273
|
+
<FormFieldGroup description="Align Arrow Example">
|
|
274
|
+
<Checkbox
|
|
275
|
+
checked={this.state.shouldAlignArrow}
|
|
276
|
+
label="Align Arrow"
|
|
277
|
+
onChange={this.toggleAlignArrow}
|
|
278
|
+
/>
|
|
279
|
+
</FormFieldGroup>
|
|
280
|
+
<div
|
|
281
|
+
style={{
|
|
282
|
+
paddingBottom: 25,
|
|
283
|
+
display: 'flex',
|
|
284
|
+
justifyContent: 'center'
|
|
285
|
+
}}
|
|
286
|
+
>
|
|
287
|
+
<Popover
|
|
288
|
+
renderTrigger={
|
|
289
|
+
<div
|
|
290
|
+
style={{
|
|
291
|
+
display: 'inline-block',
|
|
292
|
+
height: '3px',
|
|
293
|
+
width: '3px',
|
|
294
|
+
background: 'blue'
|
|
295
|
+
}}
|
|
296
|
+
/>
|
|
297
|
+
}
|
|
298
|
+
isShowingContent={true}
|
|
299
|
+
placement="end top"
|
|
300
|
+
shouldAlignArrow={this.state.shouldAlignArrow}
|
|
301
|
+
>
|
|
302
|
+
<Heading>
|
|
303
|
+
Small
|
|
304
|
+
<br />
|
|
305
|
+
Target
|
|
306
|
+
</Heading>
|
|
307
|
+
</Popover>
|
|
308
|
+
</div>
|
|
309
|
+
</>
|
|
310
|
+
)
|
|
311
|
+
}
|
|
152
312
|
}
|
|
153
|
-
toggleAlignArrow = (event) => this.setState({ shouldAlignArrow: !this.state.shouldAlignArrow })
|
|
154
313
|
|
|
155
|
-
render
|
|
314
|
+
render(<Example />)
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
- ```js
|
|
318
|
+
const Example = () => {
|
|
319
|
+
const [shouldAlignArrow, setShouldAlignArrow] = useState(true)
|
|
320
|
+
|
|
321
|
+
const toggleAlignArrow = () => {
|
|
322
|
+
setShouldAlignArrow((shouldAlignArrow) => !shouldAlignArrow)
|
|
323
|
+
}
|
|
324
|
+
|
|
156
325
|
return (
|
|
157
326
|
<>
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
mountNode={() => document.getElementById('main')}
|
|
327
|
+
<FormFieldGroup description="Align Arrow Example">
|
|
328
|
+
<Checkbox
|
|
329
|
+
checked={shouldAlignArrow}
|
|
330
|
+
label="Align Arrow"
|
|
331
|
+
onChange={toggleAlignArrow}
|
|
332
|
+
/>
|
|
333
|
+
</FormFieldGroup>
|
|
334
|
+
<div
|
|
335
|
+
style={{
|
|
336
|
+
paddingBottom: 25,
|
|
337
|
+
display: 'flex',
|
|
338
|
+
justifyContent: 'center'
|
|
339
|
+
}}
|
|
172
340
|
>
|
|
173
|
-
<
|
|
174
|
-
|
|
175
|
-
|
|
341
|
+
<Popover
|
|
342
|
+
renderTrigger={
|
|
343
|
+
<div
|
|
344
|
+
style={{
|
|
345
|
+
display: 'inline-block',
|
|
346
|
+
height: '3px',
|
|
347
|
+
width: '3px',
|
|
348
|
+
background: 'blue'
|
|
349
|
+
}}
|
|
350
|
+
/>
|
|
351
|
+
}
|
|
352
|
+
isShowingContent={true}
|
|
353
|
+
placement="end top"
|
|
354
|
+
shouldAlignArrow={shouldAlignArrow}
|
|
355
|
+
>
|
|
356
|
+
<Heading>
|
|
357
|
+
Small
|
|
358
|
+
<br />
|
|
359
|
+
Target
|
|
360
|
+
</Heading>
|
|
361
|
+
</Popover>
|
|
362
|
+
</div>
|
|
176
363
|
</>
|
|
177
364
|
)
|
|
178
365
|
}
|
|
179
|
-
}
|
|
180
366
|
|
|
181
|
-
render(<Example />)
|
|
182
|
-
```
|
|
367
|
+
render(<Example />)
|
|
368
|
+
```
|
|
183
369
|
|
|
184
370
|
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).
|
|
185
371
|
|
|
186
|
-
```js
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
372
|
+
- ```js
|
|
373
|
+
class Example extends React.Component {
|
|
374
|
+
state = {
|
|
375
|
+
isShowingContent: false
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
render() {
|
|
379
|
+
return (
|
|
380
|
+
<div
|
|
381
|
+
style={{
|
|
382
|
+
paddingBottom: 50,
|
|
383
|
+
display: 'flex',
|
|
384
|
+
justifyContent: 'center'
|
|
385
|
+
}}
|
|
386
|
+
>
|
|
387
|
+
<Popover
|
|
388
|
+
renderTrigger={<Button margin="small">Focus Me</Button>}
|
|
389
|
+
isShowingContent={this.state.isShowingContent}
|
|
390
|
+
onShowContent={(e) => {
|
|
391
|
+
this.setState({ isShowingContent: true })
|
|
392
|
+
}}
|
|
393
|
+
onHideContent={(e) => {
|
|
394
|
+
this.setState({ isShowingContent: false })
|
|
395
|
+
}}
|
|
396
|
+
on={['hover', 'focus']}
|
|
397
|
+
shouldContainFocus={false}
|
|
398
|
+
shouldFocusContentOnTriggerBlur={false}
|
|
399
|
+
>
|
|
400
|
+
<Button margin="small">Focus Me When Trigger Blurs</Button>
|
|
401
|
+
</Popover>
|
|
402
|
+
<div id="container" />
|
|
403
|
+
<Button id="next" margin="small">
|
|
404
|
+
Focus Me Next
|
|
405
|
+
</Button>
|
|
406
|
+
</div>
|
|
407
|
+
)
|
|
408
|
+
}
|
|
194
409
|
}
|
|
195
410
|
|
|
196
|
-
render
|
|
411
|
+
render(<Example />)
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
- ```js
|
|
415
|
+
const Example = () => {
|
|
416
|
+
const [isShowingContent, setIsShowingContent] = useState(false)
|
|
417
|
+
|
|
197
418
|
return (
|
|
198
|
-
<div
|
|
419
|
+
<div
|
|
420
|
+
style={{ paddingBottom: 50, display: 'flex', justifyContent: 'center' }}
|
|
421
|
+
>
|
|
199
422
|
<Popover
|
|
200
423
|
renderTrigger={<Button margin="small">Focus Me</Button>}
|
|
201
|
-
isShowingContent={
|
|
202
|
-
onShowContent={(
|
|
203
|
-
|
|
424
|
+
isShowingContent={isShowingContent}
|
|
425
|
+
onShowContent={() => {
|
|
426
|
+
setIsShowingContent(true)
|
|
204
427
|
}}
|
|
205
|
-
onHideContent={(
|
|
206
|
-
|
|
428
|
+
onHideContent={() => {
|
|
429
|
+
setIsShowingContent(false)
|
|
207
430
|
}}
|
|
208
|
-
on={['
|
|
431
|
+
on={['hover', 'focus']}
|
|
209
432
|
shouldContainFocus={false}
|
|
210
|
-
shouldFocusContentOnTriggerBlur
|
|
211
|
-
mountNode={() => document.getElementById('container')}
|
|
433
|
+
shouldFocusContentOnTriggerBlur={false}
|
|
212
434
|
>
|
|
213
435
|
<Button margin="small">Focus Me When Trigger Blurs</Button>
|
|
214
436
|
</Popover>
|
|
215
|
-
<div id="container"/>
|
|
216
|
-
<Button id="next" margin="small">
|
|
437
|
+
<div id="container" />
|
|
438
|
+
<Button id="next" margin="small">
|
|
439
|
+
Focus Me Next
|
|
440
|
+
</Button>
|
|
217
441
|
</div>
|
|
218
442
|
)
|
|
219
443
|
}
|
|
220
|
-
}
|
|
221
444
|
|
|
222
|
-
render(<Example />)
|
|
223
|
-
```
|
|
445
|
+
render(<Example />)
|
|
446
|
+
```
|
|
224
447
|
|
|
225
448
|
#### Custom elements as renderTrigger
|
|
226
449
|
|
|
227
450
|
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:
|
|
228
451
|
|
|
229
|
-
```js
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
452
|
+
- ```js
|
|
453
|
+
class MyComponent extends React.Component {
|
|
454
|
+
constructor(props) {
|
|
455
|
+
super(props)
|
|
456
|
+
this.ref = React.createRef()
|
|
457
|
+
}
|
|
458
|
+
render() {
|
|
459
|
+
// Spread the props to the underlying DOM element
|
|
460
|
+
return (
|
|
461
|
+
<div {...this.props} ref={this.ref} style={{ width: '10rem' }}>
|
|
462
|
+
My custom component
|
|
463
|
+
</div>
|
|
464
|
+
)
|
|
465
|
+
}
|
|
237
466
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
467
|
+
;<Popover renderTrigger={<MyComponent />}>
|
|
468
|
+
This text is wrapped by a Popover
|
|
469
|
+
</Popover>
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
- ```js
|
|
473
|
+
const MyComponent = React.forwardRef((props, ref) => {
|
|
474
|
+
return (
|
|
475
|
+
<div {...props} ref={ref} style={{ width: '10rem' }}>
|
|
476
|
+
My custom component
|
|
477
|
+
</div>
|
|
478
|
+
)
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
render(<MyComponent />)
|
|
482
|
+
;<Popover renderTrigger={<MyComponent />}>
|
|
483
|
+
This text is wrapped by a Popover
|
|
484
|
+
</Popover>
|
|
485
|
+
```
|
|
247
486
|
|
|
248
487
|
#### Popover playground
|
|
249
488
|
|
|
250
|
-
```js
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
shadow: 'topmost',
|
|
262
|
-
color : 'primary'
|
|
263
|
-
}
|
|
264
|
-
static placementsValues = [
|
|
489
|
+
- ```js
|
|
490
|
+
class Example extends React.Component {
|
|
491
|
+
state = {
|
|
492
|
+
shouldAlignArrow: true,
|
|
493
|
+
isShowingContent: true,
|
|
494
|
+
withArrow: true,
|
|
495
|
+
placement: 'top',
|
|
496
|
+
shadow: 'topmost',
|
|
497
|
+
color: 'primary'
|
|
498
|
+
}
|
|
499
|
+
static placementsValues = [
|
|
265
500
|
'top',
|
|
266
501
|
'end',
|
|
267
502
|
'bottom',
|
|
@@ -280,54 +515,211 @@ class Example extends React.Component {
|
|
|
280
515
|
'top center',
|
|
281
516
|
'center end',
|
|
282
517
|
'center start'
|
|
283
|
-
]
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
518
|
+
]
|
|
519
|
+
static shadowValues = ['none', 'resting', 'above', 'topmost']
|
|
520
|
+
changePlacement = (e, { value }) => this.setState({ placement: value })
|
|
521
|
+
changeShadow = (e, { value }) => this.setState({ shadow: value })
|
|
522
|
+
toggleWithArrow = (event) =>
|
|
523
|
+
this.setState({ withArrow: !this.state.withArrow })
|
|
524
|
+
toggleAlignArrow = (event) =>
|
|
525
|
+
this.setState({ shouldAlignArrow: !this.state.shouldAlignArrow })
|
|
526
|
+
toggleShowContent = (event) =>
|
|
527
|
+
this.setState({ isShowingContent: !this.state.isShowingContent })
|
|
528
|
+
changeColor = (event, value) => this.setState({ color: value })
|
|
529
|
+
render() {
|
|
530
|
+
return (
|
|
531
|
+
<View as="div" background="primary" padding="small">
|
|
532
|
+
<Flex margin="small small large" justifyItems="space-around">
|
|
533
|
+
<Flex.Item align="start">
|
|
534
|
+
<FormFieldGroup description="Popover Example">
|
|
535
|
+
<Checkbox
|
|
536
|
+
checked={this.state.isShowingContent}
|
|
537
|
+
label="Show Content"
|
|
538
|
+
onChange={this.toggleShowContent}
|
|
539
|
+
/>
|
|
540
|
+
<Checkbox
|
|
541
|
+
checked={this.state.withArrow}
|
|
542
|
+
label="With Arrow"
|
|
543
|
+
onChange={this.toggleWithArrow}
|
|
544
|
+
/>
|
|
545
|
+
<Checkbox
|
|
546
|
+
checked={this.state.shouldAlignArrow}
|
|
547
|
+
label="Align Arrow"
|
|
548
|
+
onChange={this.toggleAlignArrow}
|
|
549
|
+
/>
|
|
550
|
+
</FormFieldGroup>
|
|
551
|
+
</Flex.Item>
|
|
552
|
+
<Flex.Item>
|
|
553
|
+
<View as="div" margin="none" maxWidth="15rem">
|
|
554
|
+
<SimpleSelect
|
|
555
|
+
renderLabel="Placement"
|
|
556
|
+
value={this.state.placement}
|
|
557
|
+
onChange={this.changePlacement}
|
|
558
|
+
>
|
|
559
|
+
{Example.placementsValues.map((placement, index) => (
|
|
560
|
+
<SimpleSelect.Option
|
|
561
|
+
key={index}
|
|
562
|
+
id={`${index}`}
|
|
563
|
+
value={placement}
|
|
564
|
+
>
|
|
565
|
+
{placement}
|
|
566
|
+
</SimpleSelect.Option>
|
|
567
|
+
))}
|
|
568
|
+
</SimpleSelect>
|
|
569
|
+
</View>
|
|
570
|
+
<View as="div" margin="medium none" maxWidth="15rem">
|
|
571
|
+
<SimpleSelect
|
|
572
|
+
value={this.state.shadow}
|
|
573
|
+
onChange={this.changeShadow}
|
|
574
|
+
renderLabel="Shadow"
|
|
575
|
+
>
|
|
576
|
+
{Example.shadowValues.map((shadow, index) => (
|
|
577
|
+
<SimpleSelect.Option
|
|
578
|
+
key={index}
|
|
579
|
+
id={`${index}`}
|
|
580
|
+
value={shadow}
|
|
581
|
+
>
|
|
582
|
+
{shadow}
|
|
583
|
+
</SimpleSelect.Option>
|
|
584
|
+
))}
|
|
585
|
+
</SimpleSelect>
|
|
586
|
+
</View>
|
|
587
|
+
</Flex.Item>
|
|
588
|
+
<Flex.Item align="start">
|
|
589
|
+
<View as="div" margin="none">
|
|
590
|
+
<RadioInputGroup
|
|
591
|
+
name="changeColor"
|
|
592
|
+
defaultValue="primary"
|
|
593
|
+
description="Color:"
|
|
594
|
+
variant="toggle"
|
|
595
|
+
size="small"
|
|
596
|
+
onChange={this.changeColor}
|
|
597
|
+
>
|
|
598
|
+
<RadioInput label="Primary" value="primary" />
|
|
599
|
+
<RadioInput label="Primary inverse" value="primary-inverse" />
|
|
600
|
+
</RadioInputGroup>
|
|
601
|
+
</View>
|
|
602
|
+
</Flex.Item>
|
|
603
|
+
</Flex>
|
|
604
|
+
<View as="div" display="block" padding="large" textAlign="center">
|
|
605
|
+
<Popover
|
|
606
|
+
renderTrigger={
|
|
607
|
+
<div
|
|
608
|
+
style={{
|
|
609
|
+
display: 'inline-block',
|
|
610
|
+
height: '3px',
|
|
611
|
+
width: '3px',
|
|
612
|
+
background: 'blue'
|
|
613
|
+
}}
|
|
614
|
+
/>
|
|
615
|
+
}
|
|
616
|
+
isShowingContent={this.state.isShowingContent}
|
|
617
|
+
placement={this.state.placement}
|
|
618
|
+
withArrow={this.state.withArrow}
|
|
619
|
+
shouldAlignArrow={this.state.shouldAlignArrow}
|
|
620
|
+
shadow={this.state.shadow}
|
|
621
|
+
color={this.state.color}
|
|
622
|
+
>
|
|
623
|
+
<Heading>
|
|
624
|
+
Small
|
|
625
|
+
<br />
|
|
626
|
+
Target
|
|
627
|
+
</Heading>
|
|
628
|
+
</Popover>
|
|
629
|
+
</View>
|
|
630
|
+
</View>
|
|
631
|
+
)
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
render(<Example />)
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
- ```js
|
|
639
|
+
const placementsValues = [
|
|
640
|
+
'top',
|
|
641
|
+
'end',
|
|
642
|
+
'bottom',
|
|
643
|
+
'start',
|
|
644
|
+
'top start',
|
|
645
|
+
'start top',
|
|
646
|
+
'start center',
|
|
647
|
+
'start bottom',
|
|
648
|
+
'bottom start',
|
|
649
|
+
'bottom center',
|
|
650
|
+
'bottom end',
|
|
651
|
+
'end bottom',
|
|
652
|
+
'end center',
|
|
653
|
+
'end top',
|
|
654
|
+
'top end',
|
|
655
|
+
'top center',
|
|
656
|
+
'center end',
|
|
657
|
+
'center start'
|
|
658
|
+
]
|
|
659
|
+
|
|
660
|
+
const shadowValues = ['none', 'resting', 'above', 'topmost']
|
|
661
|
+
|
|
662
|
+
const Example = () => {
|
|
663
|
+
const [shouldAlignArrow, setShouldAlignArrow] = useState(true)
|
|
664
|
+
const [isShowingContent, setIsShowingContent] = useState(true)
|
|
665
|
+
const [withArrow, setWithArrow] = useState(true)
|
|
666
|
+
const [placement, setPlacement] = useState('top')
|
|
667
|
+
const [shadow, setShadow] = useState('topmost')
|
|
668
|
+
const [color, setColor] = useState('primary')
|
|
669
|
+
|
|
670
|
+
const changePlacement = (e, { value }) => {
|
|
671
|
+
setPlacement(value)
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
const changeShadow = (e, { value }) => {
|
|
675
|
+
setShadow(value)
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
const toggleWithArrow = () => {
|
|
679
|
+
setWithArrow((withArrow) => !withArrow)
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
const toggleAlignArrow = () => {
|
|
683
|
+
setShouldAlignArrow((shouldAlignArrow) => !shouldAlignArrow)
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
const toggleShowContent = () =>
|
|
687
|
+
setIsShowingContent((isShowingContent) => !isShowingContent)
|
|
688
|
+
|
|
689
|
+
const changeColor = (event, value) => {
|
|
690
|
+
setColor(value)
|
|
691
|
+
}
|
|
692
|
+
|
|
297
693
|
return (
|
|
298
694
|
<View as="div" background="primary" padding="small">
|
|
299
695
|
<Flex margin="small small large" justifyItems="space-around">
|
|
300
696
|
<Flex.Item align="start">
|
|
301
697
|
<FormFieldGroup description="Popover Example">
|
|
302
698
|
<Checkbox
|
|
303
|
-
checked={
|
|
699
|
+
checked={isShowingContent}
|
|
304
700
|
label="Show Content"
|
|
305
|
-
onChange={
|
|
701
|
+
onChange={toggleShowContent}
|
|
306
702
|
/>
|
|
307
703
|
<Checkbox
|
|
308
|
-
checked={
|
|
704
|
+
checked={withArrow}
|
|
309
705
|
label="With Arrow"
|
|
310
|
-
onChange={
|
|
706
|
+
onChange={toggleWithArrow}
|
|
311
707
|
/>
|
|
312
708
|
<Checkbox
|
|
313
|
-
checked={
|
|
709
|
+
checked={shouldAlignArrow}
|
|
314
710
|
label="Align Arrow"
|
|
315
|
-
onChange={
|
|
711
|
+
onChange={toggleAlignArrow}
|
|
316
712
|
/>
|
|
317
713
|
</FormFieldGroup>
|
|
318
714
|
</Flex.Item>
|
|
319
715
|
<Flex.Item>
|
|
320
|
-
<View
|
|
321
|
-
as="div"
|
|
322
|
-
margin="none"
|
|
323
|
-
maxWidth="15rem"
|
|
324
|
-
>
|
|
716
|
+
<View as="div" margin="none" maxWidth="15rem">
|
|
325
717
|
<SimpleSelect
|
|
326
718
|
renderLabel="Placement"
|
|
327
|
-
value={
|
|
328
|
-
onChange={
|
|
719
|
+
value={placement}
|
|
720
|
+
onChange={changePlacement}
|
|
329
721
|
>
|
|
330
|
-
{
|
|
722
|
+
{placementsValues.map((placement, index) => (
|
|
331
723
|
<SimpleSelect.Option
|
|
332
724
|
key={index}
|
|
333
725
|
id={`${index}`}
|
|
@@ -338,26 +730,21 @@ class Example extends React.Component {
|
|
|
338
730
|
))}
|
|
339
731
|
</SimpleSelect>
|
|
340
732
|
</View>
|
|
341
|
-
<View
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
>
|
|
346
|
-
<SimpleSelect value={this.state.shadow}
|
|
347
|
-
onChange={this.changeShadow}
|
|
733
|
+
<View as="div" margin="medium none" maxWidth="15rem">
|
|
734
|
+
<SimpleSelect
|
|
735
|
+
value={shadow}
|
|
736
|
+
onChange={changeShadow}
|
|
348
737
|
renderLabel="Shadow"
|
|
349
738
|
>
|
|
350
|
-
{
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
))
|
|
360
|
-
}
|
|
739
|
+
{shadowValues.map((shadow, index) => (
|
|
740
|
+
<SimpleSelect.Option
|
|
741
|
+
key={index}
|
|
742
|
+
id={`${index}`}
|
|
743
|
+
value={shadow}
|
|
744
|
+
>
|
|
745
|
+
{shadow}
|
|
746
|
+
</SimpleSelect.Option>
|
|
747
|
+
))}
|
|
361
748
|
</SimpleSelect>
|
|
362
749
|
</View>
|
|
363
750
|
</Flex.Item>
|
|
@@ -369,38 +756,46 @@ class Example extends React.Component {
|
|
|
369
756
|
description="Color:"
|
|
370
757
|
variant="toggle"
|
|
371
758
|
size="small"
|
|
372
|
-
onChange={
|
|
373
|
-
|
|
759
|
+
onChange={changeColor}
|
|
760
|
+
>
|
|
761
|
+
<RadioInput label="Primary" value="primary" />
|
|
374
762
|
<RadioInput label="Primary inverse" value="primary-inverse" />
|
|
375
763
|
</RadioInputGroup>
|
|
376
764
|
</View>
|
|
377
765
|
</Flex.Item>
|
|
378
766
|
</Flex>
|
|
379
|
-
<View
|
|
380
|
-
as="div"
|
|
381
|
-
display="block"
|
|
382
|
-
padding="large"
|
|
383
|
-
textAlign="center">
|
|
767
|
+
<View as="div" display="block" padding="large" textAlign="center">
|
|
384
768
|
<Popover
|
|
385
|
-
renderTrigger={
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
769
|
+
renderTrigger={
|
|
770
|
+
<div
|
|
771
|
+
style={{
|
|
772
|
+
display: 'inline-block',
|
|
773
|
+
height: '3px',
|
|
774
|
+
width: '3px',
|
|
775
|
+
background: 'blue'
|
|
776
|
+
}}
|
|
777
|
+
/>
|
|
778
|
+
}
|
|
779
|
+
isShowingContent={isShowingContent}
|
|
780
|
+
placement={placement}
|
|
781
|
+
withArrow={withArrow}
|
|
782
|
+
shouldAlignArrow={shouldAlignArrow}
|
|
783
|
+
shadow={shadow}
|
|
784
|
+
color={color}
|
|
393
785
|
>
|
|
394
|
-
<Heading>
|
|
786
|
+
<Heading>
|
|
787
|
+
Small
|
|
788
|
+
<br />
|
|
789
|
+
Target
|
|
790
|
+
</Heading>
|
|
395
791
|
</Popover>
|
|
396
792
|
</View>
|
|
397
793
|
</View>
|
|
398
794
|
)
|
|
399
795
|
}
|
|
400
|
-
}
|
|
401
796
|
|
|
402
|
-
render(<Example />)
|
|
403
|
-
```
|
|
797
|
+
render(<Example />)
|
|
798
|
+
```
|
|
404
799
|
|
|
405
800
|
### Guidelines
|
|
406
801
|
|