@patternfly/react-core 4.211.2 → 4.211.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 +30 -0
- package/dist/esm/components/Modal/Modal.d.ts +4 -0
- package/dist/esm/components/Modal/Modal.d.ts.map +1 -1
- package/dist/esm/components/Modal/Modal.js +2 -2
- package/dist/esm/components/Modal/Modal.js.map +1 -1
- package/dist/esm/components/Modal/ModalContent.d.ts +4 -0
- package/dist/esm/components/Modal/ModalContent.d.ts.map +1 -1
- package/dist/esm/components/Modal/ModalContent.js +3 -2
- package/dist/esm/components/Modal/ModalContent.js.map +1 -1
- package/dist/esm/components/Tooltip/Tooltip.d.ts +6 -0
- package/dist/esm/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/esm/components/Tooltip/Tooltip.js +2 -2
- package/dist/esm/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/esm/helpers/Popper/Popper.d.ts.map +1 -1
- package/dist/esm/helpers/Popper/Popper.js +7 -6
- package/dist/esm/helpers/Popper/Popper.js.map +1 -1
- package/dist/js/components/Modal/Modal.d.ts +4 -0
- package/dist/js/components/Modal/Modal.d.ts.map +1 -1
- package/dist/js/components/Modal/Modal.js +2 -2
- package/dist/js/components/Modal/Modal.js.map +1 -1
- package/dist/js/components/Modal/ModalContent.d.ts +4 -0
- package/dist/js/components/Modal/ModalContent.d.ts.map +1 -1
- package/dist/js/components/Modal/ModalContent.js +3 -2
- package/dist/js/components/Modal/ModalContent.js.map +1 -1
- package/dist/js/components/Tooltip/Tooltip.d.ts +6 -0
- package/dist/js/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/js/components/Tooltip/Tooltip.js +2 -2
- package/dist/js/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/js/helpers/Popper/Popper.d.ts.map +1 -1
- package/dist/js/helpers/Popper/Popper.js +7 -6
- package/dist/js/helpers/Popper/Popper.js.map +1 -1
- package/dist/umd/react-core.css +74 -69
- package/dist/umd/react-core.js +14 -12
- package/dist/umd/react-core.min.css +82 -77
- package/dist/umd/react-core.min.js +3 -3
- package/package.json +6 -6
- package/src/components/Modal/Modal.tsx +8 -0
- package/src/components/Modal/ModalContent.tsx +14 -1
- package/src/components/Modal/__tests__/Modal.test.tsx +56 -0
- package/src/components/Modal/examples/Modal.md +7 -0
- package/src/components/Modal/examples/ModalWithOverflowingContent.tsx +71 -0
- package/src/components/Tabs/examples/Tabs.md +144 -25
- package/src/components/Tooltip/Tooltip.tsx +8 -0
- package/src/components/Tooltip/examples/Tooltip.md +86 -41
- package/src/helpers/Popper/Popper.tsx +10 -7
|
@@ -12,6 +12,7 @@ import './TooltipExamples.css';
|
|
|
12
12
|
## Examples
|
|
13
13
|
|
|
14
14
|
### Basic
|
|
15
|
+
|
|
15
16
|
```js
|
|
16
17
|
import React from 'react';
|
|
17
18
|
import { Tooltip } from '@patternfly/react-core';
|
|
@@ -22,12 +23,15 @@ import { Tooltip } from '@patternfly/react-core';
|
|
|
22
23
|
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.</div>
|
|
23
24
|
}
|
|
24
25
|
>
|
|
25
|
-
<span tabIndex="0" style={{ border: '1px dashed' }}>
|
|
26
|
+
<span tabIndex="0" style={{ border: '1px dashed' }}>
|
|
27
|
+
I have a tooltip!
|
|
28
|
+
</span>
|
|
26
29
|
</Tooltip>
|
|
27
|
-
</div
|
|
30
|
+
</div>;
|
|
28
31
|
```
|
|
29
32
|
|
|
30
33
|
### Tooltip react ref
|
|
34
|
+
|
|
31
35
|
```js
|
|
32
36
|
import React from 'react';
|
|
33
37
|
import { Tooltip } from '@patternfly/react-core';
|
|
@@ -36,35 +40,49 @@ TooltipReactRef = () => {
|
|
|
36
40
|
const tooltipRef = React.useRef();
|
|
37
41
|
return (
|
|
38
42
|
<div style={{ margin: '100px' }}>
|
|
39
|
-
<button ref={tooltipRef}>
|
|
43
|
+
<button aria-describedby="tooltip-ref1" ref={tooltipRef}>
|
|
44
|
+
Tooltip attached via react ref
|
|
45
|
+
</button>
|
|
40
46
|
<Tooltip
|
|
47
|
+
id="tooltip-ref1"
|
|
41
48
|
content={
|
|
42
|
-
<div>
|
|
49
|
+
<div>
|
|
50
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.
|
|
51
|
+
</div>
|
|
43
52
|
}
|
|
44
53
|
reference={tooltipRef}
|
|
45
54
|
/>
|
|
46
55
|
</div>
|
|
47
56
|
);
|
|
48
|
-
}
|
|
57
|
+
};
|
|
49
58
|
```
|
|
50
59
|
|
|
51
60
|
### Tooltip selector ref
|
|
61
|
+
|
|
52
62
|
```js
|
|
53
63
|
import React from 'react';
|
|
54
64
|
import { Tooltip } from '@patternfly/react-core';
|
|
55
65
|
|
|
56
66
|
<div style={{ margin: '100px' }}>
|
|
57
|
-
<button id="tooltip-selector">
|
|
67
|
+
<button aria-describedby="tooltip-ref2" id="tooltip-selector">
|
|
68
|
+
Tooltip attached via selector ref
|
|
69
|
+
</button>
|
|
58
70
|
<Tooltip
|
|
71
|
+
id="tooltip-ref2"
|
|
59
72
|
content={
|
|
60
73
|
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.</div>
|
|
61
74
|
}
|
|
62
75
|
reference={() => document.getElementById('tooltip-selector')}
|
|
63
76
|
/>
|
|
64
|
-
</div
|
|
77
|
+
</div>;
|
|
65
78
|
```
|
|
66
79
|
|
|
67
|
-
### On icon
|
|
80
|
+
### On icon with dynamic content
|
|
81
|
+
|
|
82
|
+
When the tooltip is used as a wrapper and its content will dynamically update, the `aria` prop should have a value of "none" passed in. This prevents assistive technologies from announcing the tooltip contents more than once. Additionally, the `aria-live` prop should have a value of "polite" passed in, in order for assistive technologies to announce when the tooltip contents gets updated.
|
|
83
|
+
|
|
84
|
+
When using a React or selector ref with a tooltip that has dynamic content, the `aria` and `aria-live` props do not need to be manually passed in.
|
|
85
|
+
|
|
68
86
|
```js
|
|
69
87
|
import React from 'react';
|
|
70
88
|
import { Tooltip, Button } from '@patternfly/react-core';
|
|
@@ -77,8 +95,13 @@ IconExample = () => {
|
|
|
77
95
|
const [content, setContent] = React.useState(copyText);
|
|
78
96
|
return (
|
|
79
97
|
<div style={{ margin: '100px' }}>
|
|
80
|
-
<Tooltip content={showSuccessContent ? doneCopyText : copyText}>
|
|
81
|
-
<Button
|
|
98
|
+
<Tooltip aria="none" aria-live="polite" content={showSuccessContent ? doneCopyText : copyText}>
|
|
99
|
+
<Button
|
|
100
|
+
aria-label="Clipboard"
|
|
101
|
+
variant="plain"
|
|
102
|
+
id="tt-ref"
|
|
103
|
+
onClick={() => setShowSuccessContent(!showSuccessContent)}
|
|
104
|
+
>
|
|
82
105
|
<CopyIcon />
|
|
83
106
|
</Button>
|
|
84
107
|
</Tooltip>
|
|
@@ -88,6 +111,7 @@ IconExample = () => {
|
|
|
88
111
|
```
|
|
89
112
|
|
|
90
113
|
### Options
|
|
114
|
+
|
|
91
115
|
```js
|
|
92
116
|
import React from 'react';
|
|
93
117
|
import { Button, Tooltip, Checkbox, Select, SelectOption, TextInput } from '@patternfly/react-core';
|
|
@@ -105,26 +129,26 @@ OptionsTooltip = () => {
|
|
|
105
129
|
const [exitDelayInput, setExitDelayInput] = React.useState(0);
|
|
106
130
|
const [animationDuration, setAnimationDuration] = React.useState(300);
|
|
107
131
|
const tipBoxRef = React.useRef(null);
|
|
108
|
-
|
|
132
|
+
|
|
109
133
|
const scrollToRef = ref => {
|
|
110
134
|
if (ref && ref.current) {
|
|
111
135
|
ref.current.scrollTop = 400;
|
|
112
136
|
ref.current.scrollLeft = 300;
|
|
113
137
|
}
|
|
114
|
-
}
|
|
115
|
-
|
|
138
|
+
};
|
|
139
|
+
|
|
116
140
|
React.useEffect(() => {
|
|
117
141
|
scrollToRef(tipBoxRef);
|
|
118
142
|
}, []);
|
|
119
|
-
|
|
143
|
+
|
|
120
144
|
return (
|
|
121
145
|
<>
|
|
122
146
|
<div>
|
|
123
|
-
<div style={{ border: '1px solid'}}>
|
|
147
|
+
<div style={{ border: '1px solid' }}>
|
|
124
148
|
<Checkbox
|
|
125
149
|
label="trigger: mouseenter"
|
|
126
150
|
isChecked={trigger.includes('mouseenter')}
|
|
127
|
-
onChange={
|
|
151
|
+
onChange={checked => {
|
|
128
152
|
let updatedTrigger;
|
|
129
153
|
checked && (updatedTrigger = trigger.concat('mouseenter'));
|
|
130
154
|
!checked && (updatedTrigger = trigger.filter(t => t !== 'mouseenter'));
|
|
@@ -137,7 +161,7 @@ OptionsTooltip = () => {
|
|
|
137
161
|
<Checkbox
|
|
138
162
|
label="trigger: focus"
|
|
139
163
|
isChecked={trigger.includes('focus')}
|
|
140
|
-
onChange={
|
|
164
|
+
onChange={checked => {
|
|
141
165
|
let updatedTrigger;
|
|
142
166
|
checked && (updatedTrigger = trigger.concat('focus'));
|
|
143
167
|
!checked && (updatedTrigger = trigger.filter(t => t !== 'focus'));
|
|
@@ -150,7 +174,7 @@ OptionsTooltip = () => {
|
|
|
150
174
|
<Checkbox
|
|
151
175
|
label="trigger: click"
|
|
152
176
|
isChecked={trigger.includes('click')}
|
|
153
|
-
onChange={
|
|
177
|
+
onChange={checked => {
|
|
154
178
|
let updatedTrigger;
|
|
155
179
|
checked && (updatedTrigger = trigger.concat('click'));
|
|
156
180
|
!checked && (updatedTrigger = trigger.filter(t => t !== 'click'));
|
|
@@ -163,36 +187,36 @@ OptionsTooltip = () => {
|
|
|
163
187
|
<Checkbox
|
|
164
188
|
label="trigger: manual"
|
|
165
189
|
isChecked={trigger.includes('manual')}
|
|
166
|
-
onChange={
|
|
190
|
+
onChange={checked => {
|
|
167
191
|
let updatedTrigger;
|
|
168
192
|
checked && (updatedTrigger = trigger.concat('manual'));
|
|
169
193
|
!checked && (updatedTrigger = trigger.filter(t => t !== 'manual'));
|
|
170
194
|
setIsVisible(false);
|
|
171
195
|
setTrigger(updatedTrigger);
|
|
172
196
|
}}
|
|
173
|
-
aria-label="trigger: manual"
|
|
174
|
-
id="trigger_manual"
|
|
197
|
+
aria-label="trigger: manual"
|
|
198
|
+
id="trigger_manual"
|
|
175
199
|
/>
|
|
176
200
|
</div>
|
|
177
|
-
<div style={{ border: '1px solid'}}>
|
|
201
|
+
<div style={{ border: '1px solid' }}>
|
|
178
202
|
<Checkbox
|
|
179
203
|
label="content left-aligned"
|
|
180
204
|
isChecked={contentLeftAligned}
|
|
181
|
-
onChange={
|
|
205
|
+
onChange={checked => setContentLeftAligned(checked)}
|
|
182
206
|
aria-label="content left-aligned"
|
|
183
|
-
id="content_left_aligned"
|
|
207
|
+
id="content_left_aligned"
|
|
184
208
|
/>
|
|
185
209
|
</div>
|
|
186
|
-
<div style={{ border: '1px solid'}}>
|
|
210
|
+
<div style={{ border: '1px solid' }}>
|
|
187
211
|
<Checkbox
|
|
188
212
|
label="enableFlip"
|
|
189
213
|
isChecked={enableFlip}
|
|
190
|
-
onChange={
|
|
191
|
-
aria-label="enableFlip"
|
|
192
|
-
id="enable_flip"
|
|
214
|
+
onChange={checked => setEnableFlip(checked)}
|
|
215
|
+
aria-label="enableFlip"
|
|
216
|
+
id="enable_flip"
|
|
193
217
|
/>
|
|
194
218
|
</div>
|
|
195
|
-
<div style={{ border: '1px solid'}}>
|
|
219
|
+
<div style={{ border: '1px solid' }}>
|
|
196
220
|
position (will flip if enableFlip is true). The 'auto' position requires enableFlip to be set to true.
|
|
197
221
|
<Select
|
|
198
222
|
onToggle={() => setPositionSelectOpen(!positionSelectOpen)}
|
|
@@ -219,22 +243,41 @@ OptionsTooltip = () => {
|
|
|
219
243
|
<SelectOption value="right-end" />
|
|
220
244
|
</Select>
|
|
221
245
|
</div>
|
|
222
|
-
<div style={{ border: '1px solid'}}>
|
|
246
|
+
<div style={{ border: '1px solid' }}>
|
|
223
247
|
<Checkbox
|
|
224
248
|
label="isVisible (also set trigger to only manual to programmatically control it)"
|
|
225
249
|
isChecked={isVisible}
|
|
226
|
-
onChange={
|
|
227
|
-
aria-label="isVisible"
|
|
228
|
-
id="is_visible"
|
|
250
|
+
onChange={checked => setIsVisible(checked)}
|
|
251
|
+
aria-label="isVisible"
|
|
252
|
+
id="is_visible"
|
|
229
253
|
/>
|
|
230
254
|
</div>
|
|
231
|
-
<div style={{ border: '1px solid'}}>
|
|
232
|
-
Entry delay (ms)
|
|
233
|
-
|
|
234
|
-
|
|
255
|
+
<div style={{ border: '1px solid' }}>
|
|
256
|
+
Entry delay (ms){' '}
|
|
257
|
+
<TextInput
|
|
258
|
+
value={entryDelayInput}
|
|
259
|
+
type="number"
|
|
260
|
+
onChange={val => setEntryDelayInput(val)}
|
|
261
|
+
aria-label="entry delay"
|
|
262
|
+
/>
|
|
263
|
+
Exit delay (ms) <TextInput
|
|
264
|
+
value={exitDelayInput}
|
|
265
|
+
type="number"
|
|
266
|
+
onChange={val => setExitDelayInput(val)}
|
|
267
|
+
aria-label="exit delay"
|
|
268
|
+
/>
|
|
269
|
+
Animation duration (ms){' '}
|
|
270
|
+
<TextInput
|
|
271
|
+
value={animationDuration}
|
|
272
|
+
type="number"
|
|
273
|
+
onChange={val => setAnimationDuration(val)}
|
|
274
|
+
aria-label="animation duration"
|
|
275
|
+
/>
|
|
235
276
|
</div>
|
|
236
|
-
<div style={{ border: '1px solid'}}>
|
|
237
|
-
flip behavior examples (enableFlip has to be true). "flip" will try to flip the tooltip to the opposite of the
|
|
277
|
+
<div style={{ border: '1px solid' }}>
|
|
278
|
+
flip behavior examples (enableFlip has to be true). "flip" will try to flip the tooltip to the opposite of the
|
|
279
|
+
starting position. The second option ensures that there are 3 escape positions for every possible starting
|
|
280
|
+
position (default). This setting is ignored if position prop is set to 'auto'.
|
|
238
281
|
<Select
|
|
239
282
|
onToggle={() => setFlipSelectOpen(!flipSelectOpen)}
|
|
240
283
|
onSelect={(event, selection) => {
|
|
@@ -254,7 +297,9 @@ OptionsTooltip = () => {
|
|
|
254
297
|
<div id="tooltip-boundary" className="tooltip-box" ref={tipBoxRef}>
|
|
255
298
|
<Tooltip
|
|
256
299
|
content={
|
|
257
|
-
<div>
|
|
300
|
+
<div>
|
|
301
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.
|
|
302
|
+
</div>
|
|
258
303
|
}
|
|
259
304
|
trigger={trigger.join(' ')}
|
|
260
305
|
enableFlip={enableFlip}
|
|
@@ -272,5 +317,5 @@ OptionsTooltip = () => {
|
|
|
272
317
|
</div>
|
|
273
318
|
</>
|
|
274
319
|
);
|
|
275
|
-
}
|
|
320
|
+
};
|
|
276
321
|
```
|
|
@@ -165,6 +165,7 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
165
165
|
element.removeEventListener(event, listener);
|
|
166
166
|
}
|
|
167
167
|
};
|
|
168
|
+
|
|
168
169
|
React.useEffect(() => {
|
|
169
170
|
addEventListener(onMouseEnter, refOrTrigger, 'mouseenter');
|
|
170
171
|
addEventListener(onMouseLeave, refOrTrigger, 'mouseleave');
|
|
@@ -175,6 +176,13 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
175
176
|
addEventListener(onPopperClick, popperElement, 'click');
|
|
176
177
|
onDocumentClick && addEventListener(onDocumentClickCallback, document, 'click');
|
|
177
178
|
addEventListener(onDocumentKeyDown, document, 'keydown');
|
|
179
|
+
|
|
180
|
+
// Trigger a Popper update when content changes.
|
|
181
|
+
const observer = new MutationObserver(() => {
|
|
182
|
+
update && update();
|
|
183
|
+
});
|
|
184
|
+
popperElement && observer.observe(popperElement, { attributes: true, childList: true, subtree: true });
|
|
185
|
+
|
|
178
186
|
return () => {
|
|
179
187
|
removeEventListener(onMouseEnter, refOrTrigger, 'mouseenter');
|
|
180
188
|
removeEventListener(onMouseLeave, refOrTrigger, 'mouseleave');
|
|
@@ -185,6 +193,7 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
185
193
|
removeEventListener(onPopperClick, popperElement, 'click');
|
|
186
194
|
onDocumentClick && removeEventListener(onDocumentClickCallback, document, 'click');
|
|
187
195
|
removeEventListener(onDocumentKeyDown, document, 'keydown');
|
|
196
|
+
observer.disconnect();
|
|
188
197
|
};
|
|
189
198
|
}, [
|
|
190
199
|
triggerElement,
|
|
@@ -233,7 +242,7 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
233
242
|
[popperMatchesTriggerWidth]
|
|
234
243
|
);
|
|
235
244
|
|
|
236
|
-
const { styles: popperStyles, attributes,
|
|
245
|
+
const { styles: popperStyles, attributes, update } = usePopper(refOrTrigger, popperElement, {
|
|
237
246
|
placement: getPlacementMemo,
|
|
238
247
|
modifiers: [
|
|
239
248
|
{
|
|
@@ -262,12 +271,6 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
|
|
|
262
271
|
]
|
|
263
272
|
});
|
|
264
273
|
|
|
265
|
-
// force update when content changes
|
|
266
|
-
// https://github.com/patternfly/patternfly-react/issues/5620
|
|
267
|
-
React.useEffect(() => {
|
|
268
|
-
forceUpdate && forceUpdate();
|
|
269
|
-
}, [popper]);
|
|
270
|
-
|
|
271
274
|
// Returns the CSS modifier class in order to place the Popper's arrow properly
|
|
272
275
|
// Depends on the position of the Popper relative to the reference element
|
|
273
276
|
const modifierFromPopperPosition = () => {
|