@patternfly/react-core 4.211.1 → 4.211.4
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/Menu/Menu.js +1 -1
- package/dist/esm/components/Menu/Menu.js.map +1 -1
- 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/Page/PageBreadcrumb.d.ts.map +1 -1
- package/dist/esm/components/Page/PageBreadcrumb.js +1 -1
- package/dist/esm/components/Page/PageBreadcrumb.js.map +1 -1
- package/dist/esm/components/Page/PageGroup.d.ts.map +1 -1
- package/dist/esm/components/Page/PageGroup.js +1 -1
- package/dist/esm/components/Page/PageGroup.js.map +1 -1
- package/dist/esm/components/Page/PageNavigation.d.ts.map +1 -1
- package/dist/esm/components/Page/PageNavigation.js +1 -1
- package/dist/esm/components/Page/PageNavigation.js.map +1 -1
- package/dist/esm/components/Page/PageSection.d.ts.map +1 -1
- package/dist/esm/components/Page/PageSection.js +1 -1
- package/dist/esm/components/Page/PageSection.js.map +1 -1
- package/dist/esm/components/Panel/Panel.d.ts +3 -1
- package/dist/esm/components/Panel/Panel.d.ts.map +1 -1
- package/dist/esm/components/Panel/Panel.js +4 -3
- package/dist/esm/components/Panel/Panel.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/KeyboardHandler.d.ts +2 -0
- package/dist/esm/helpers/KeyboardHandler.d.ts.map +1 -1
- package/dist/esm/helpers/KeyboardHandler.js +3 -2
- package/dist/esm/helpers/KeyboardHandler.js.map +1 -1
- package/dist/js/components/Menu/Menu.js +1 -1
- package/dist/js/components/Menu/Menu.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/Page/PageBreadcrumb.d.ts.map +1 -1
- package/dist/js/components/Page/PageBreadcrumb.js +1 -1
- package/dist/js/components/Page/PageBreadcrumb.js.map +1 -1
- package/dist/js/components/Page/PageGroup.d.ts.map +1 -1
- package/dist/js/components/Page/PageGroup.js +1 -1
- package/dist/js/components/Page/PageGroup.js.map +1 -1
- package/dist/js/components/Page/PageNavigation.d.ts.map +1 -1
- package/dist/js/components/Page/PageNavigation.js +1 -1
- package/dist/js/components/Page/PageNavigation.js.map +1 -1
- package/dist/js/components/Page/PageSection.d.ts.map +1 -1
- package/dist/js/components/Page/PageSection.js +1 -1
- package/dist/js/components/Page/PageSection.js.map +1 -1
- package/dist/js/components/Panel/Panel.d.ts +3 -1
- package/dist/js/components/Panel/Panel.d.ts.map +1 -1
- package/dist/js/components/Panel/Panel.js +4 -4
- package/dist/js/components/Panel/Panel.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/KeyboardHandler.d.ts +2 -0
- package/dist/js/helpers/KeyboardHandler.d.ts.map +1 -1
- package/dist/js/helpers/KeyboardHandler.js +3 -2
- package/dist/js/helpers/KeyboardHandler.js.map +1 -1
- package/dist/umd/react-core.css +5 -0
- package/dist/umd/react-core.js +19 -16
- package/dist/umd/react-core.min.css +5 -0
- package/dist/umd/react-core.min.js +4 -4
- package/package.json +6 -6
- package/src/components/Menu/Menu.tsx +1 -1
- 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/Page/PageBreadcrumb.tsx +1 -0
- package/src/components/Page/PageGroup.tsx +1 -0
- package/src/components/Page/PageNavigation.tsx +1 -0
- package/src/components/Page/PageSection.tsx +1 -0
- package/src/components/Page/__tests__/__snapshots__/PageBreadcrumb.test.tsx.snap +1 -0
- package/src/components/Page/__tests__/__snapshots__/PageGroup.test.tsx.snap +1 -0
- package/src/components/Page/__tests__/__snapshots__/PageNavigation.test.tsx.snap +1 -0
- package/src/components/Page/__tests__/__snapshots__/PageSection.test.tsx.snap +1 -0
- package/src/components/Panel/Panel.tsx +8 -1
- 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/demos/ComposableMenu/ComposableMenu.md +2 -0
- package/src/demos/ComposableMenu/examples/ComposableTreeViewMenu.tsx +62 -28
- package/src/helpers/KeyboardHandler.tsx +7 -2
|
@@ -56,7 +56,12 @@ class SimpleTabs extends React.Component {
|
|
|
56
56
|
|
|
57
57
|
return (
|
|
58
58
|
<div>
|
|
59
|
-
<Tabs
|
|
59
|
+
<Tabs
|
|
60
|
+
activeKey={activeTabKey}
|
|
61
|
+
onSelect={this.handleTabClick}
|
|
62
|
+
isBox={isBox}
|
|
63
|
+
aria-label="Tabs in the default example"
|
|
64
|
+
>
|
|
60
65
|
<Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>
|
|
61
66
|
Users
|
|
62
67
|
</Tab>
|
|
@@ -99,7 +104,9 @@ class SimpleTabs extends React.Component {
|
|
|
99
104
|
|
|
100
105
|
### With tooltip react ref
|
|
101
106
|
|
|
102
|
-
When using a React ref to link a Tooltip to a Tab component
|
|
107
|
+
When using a React ref to link a Tooltip to a Tab component via the `reference` prop, you should avoid manually passing in a value of "off" to the `aria-live` prop. Doing so may lead to the tooltip becoming less accessible to assistive technologies.
|
|
108
|
+
|
|
109
|
+
The tooltip should also have the `id` prop passed in. The value given to this prop should then be passed into the tab's `aria-describedby` prop. This ensures a tooltip used with a React ref will be announced by the JAWS and NVDA screen readers.
|
|
103
110
|
|
|
104
111
|
```js
|
|
105
112
|
import React from 'react';
|
|
@@ -132,7 +139,12 @@ class SimpleTabs extends React.Component {
|
|
|
132
139
|
|
|
133
140
|
return (
|
|
134
141
|
<div>
|
|
135
|
-
<Tabs
|
|
142
|
+
<Tabs
|
|
143
|
+
activeKey={activeTabKey}
|
|
144
|
+
onSelect={this.handleTabClick}
|
|
145
|
+
isBox={isBox}
|
|
146
|
+
aria-label="Tabs in the example with a tooltip ref"
|
|
147
|
+
>
|
|
136
148
|
<Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>
|
|
137
149
|
Users
|
|
138
150
|
</Tab>
|
|
@@ -153,15 +165,15 @@ class SimpleTabs extends React.Component {
|
|
|
153
165
|
title={<TabTitleText>ARIA Disabled (Tooltip)</TabTitleText>}
|
|
154
166
|
isAriaDisabled
|
|
155
167
|
ref={tooltipRef}
|
|
156
|
-
aria-describedby="tooltip-
|
|
168
|
+
aria-describedby="tooltip-ref1"
|
|
157
169
|
>
|
|
158
170
|
ARIA Disabled (Tooltip)
|
|
159
171
|
</Tab>
|
|
160
172
|
</Tabs>
|
|
161
173
|
<Tooltip
|
|
174
|
+
id="tooltip-ref1"
|
|
162
175
|
content="Aria-disabled tabs are like disabled tabs, but focusable. Allows for tooltip support."
|
|
163
176
|
reference={tooltipRef}
|
|
164
|
-
id="tooltip-tab-5"
|
|
165
177
|
/>
|
|
166
178
|
<div style={{ marginTop: '20px' }}>
|
|
167
179
|
<Checkbox
|
|
@@ -338,7 +350,12 @@ class ScrollButtonsPrimaryTabs extends React.Component {
|
|
|
338
350
|
const { activeTabKey, isBox } = this.state;
|
|
339
351
|
return (
|
|
340
352
|
<div>
|
|
341
|
-
<Tabs
|
|
353
|
+
<Tabs
|
|
354
|
+
activeKey={activeTabKey}
|
|
355
|
+
onSelect={this.handleTabClick}
|
|
356
|
+
isBox={isBox}
|
|
357
|
+
aria-label="Tabs in the default overflow example"
|
|
358
|
+
>
|
|
342
359
|
<Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>
|
|
343
360
|
Users
|
|
344
361
|
</Tab>
|
|
@@ -424,7 +441,13 @@ class VerticalTabs extends React.Component {
|
|
|
424
441
|
|
|
425
442
|
return (
|
|
426
443
|
<div>
|
|
427
|
-
<Tabs
|
|
444
|
+
<Tabs
|
|
445
|
+
activeKey={activeTabKey}
|
|
446
|
+
onSelect={this.handleTabClick}
|
|
447
|
+
isVertical
|
|
448
|
+
isBox={isBox}
|
|
449
|
+
aria-label="Tabs in the vertical example"
|
|
450
|
+
>
|
|
428
451
|
<Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>
|
|
429
452
|
Users
|
|
430
453
|
</Tab>
|
|
@@ -689,7 +712,13 @@ class PageInsetsTabs extends React.Component {
|
|
|
689
712
|
const { activeTabKey, isBox } = this.state;
|
|
690
713
|
return (
|
|
691
714
|
<div>
|
|
692
|
-
<Tabs
|
|
715
|
+
<Tabs
|
|
716
|
+
activeKey={activeTabKey}
|
|
717
|
+
onSelect={this.handleTabClick}
|
|
718
|
+
usePageInsets
|
|
719
|
+
isBox={isBox}
|
|
720
|
+
aria-label="Tabs in the page insets example"
|
|
721
|
+
>
|
|
693
722
|
<Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>
|
|
694
723
|
Users
|
|
695
724
|
</Tab>
|
|
@@ -753,7 +782,11 @@ class IconAndTextTabs extends React.Component {
|
|
|
753
782
|
|
|
754
783
|
render() {
|
|
755
784
|
return (
|
|
756
|
-
<Tabs
|
|
785
|
+
<Tabs
|
|
786
|
+
activeKey={this.state.activeTabKey}
|
|
787
|
+
onSelect={this.handleTabClick}
|
|
788
|
+
aria-label="Tabs in the icons and text example"
|
|
789
|
+
>
|
|
757
790
|
<Tab
|
|
758
791
|
eventKey={0}
|
|
759
792
|
title={
|
|
@@ -876,9 +909,19 @@ class SecondaryTabs extends React.Component {
|
|
|
876
909
|
const { activeTabKey1, activeTabKey2, isBox } = this.state;
|
|
877
910
|
return (
|
|
878
911
|
<div>
|
|
879
|
-
<Tabs
|
|
912
|
+
<Tabs
|
|
913
|
+
activeKey={activeTabKey1}
|
|
914
|
+
onSelect={this.handleTabClickFirst}
|
|
915
|
+
isBox={isBox}
|
|
916
|
+
aria-label="Tabs in the tabs with subtabs example"
|
|
917
|
+
>
|
|
880
918
|
<Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>
|
|
881
|
-
<Tabs
|
|
919
|
+
<Tabs
|
|
920
|
+
aria-label="secondary tabs for users"
|
|
921
|
+
activeKey={activeTabKey2}
|
|
922
|
+
isSecondary
|
|
923
|
+
onSelect={this.handleTabClickSecond}
|
|
924
|
+
>
|
|
882
925
|
<Tab eventKey={20} title={<TabTitleText>Secondary tab item 1</TabTitleText>}>
|
|
883
926
|
Secondary tab item 1 item section
|
|
884
927
|
</Tab>
|
|
@@ -983,7 +1026,13 @@ class FilledTabs extends React.Component {
|
|
|
983
1026
|
const { activeTabKey, isBox } = this.state;
|
|
984
1027
|
return (
|
|
985
1028
|
<div>
|
|
986
|
-
<Tabs
|
|
1029
|
+
<Tabs
|
|
1030
|
+
isFilled
|
|
1031
|
+
activeKey={activeTabKey}
|
|
1032
|
+
onSelect={this.handleTabClick}
|
|
1033
|
+
isBox={isBox}
|
|
1034
|
+
aria-label="Tabs in the filled example"
|
|
1035
|
+
>
|
|
987
1036
|
<Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>
|
|
988
1037
|
Users
|
|
989
1038
|
</Tab>
|
|
@@ -1044,7 +1093,13 @@ class FilledTabsWithIcons extends React.Component {
|
|
|
1044
1093
|
const { activeTabKey, isBox } = this.state;
|
|
1045
1094
|
return (
|
|
1046
1095
|
<div>
|
|
1047
|
-
<Tabs
|
|
1096
|
+
<Tabs
|
|
1097
|
+
isFilled
|
|
1098
|
+
activeKey={activeTabKey}
|
|
1099
|
+
onSelect={this.handleTabClick}
|
|
1100
|
+
isBox={isBox}
|
|
1101
|
+
aria-label="Tabs in the filled with icons example"
|
|
1102
|
+
>
|
|
1048
1103
|
<Tab
|
|
1049
1104
|
eventKey={0}
|
|
1050
1105
|
title={
|
|
@@ -1270,7 +1325,11 @@ class SeparateTabContent extends React.Component {
|
|
|
1270
1325
|
render() {
|
|
1271
1326
|
return (
|
|
1272
1327
|
<React.Fragment>
|
|
1273
|
-
<Tabs
|
|
1328
|
+
<Tabs
|
|
1329
|
+
activeKey={this.state.activeTabKey}
|
|
1330
|
+
onSelect={this.handleTabClick}
|
|
1331
|
+
aria-label="Tabs in the seperate content example"
|
|
1332
|
+
>
|
|
1274
1333
|
<Tab
|
|
1275
1334
|
eventKey={0}
|
|
1276
1335
|
title={<TabTitleText>Tab item 1</TabTitleText>}
|
|
@@ -1291,13 +1350,30 @@ class SeparateTabContent extends React.Component {
|
|
|
1291
1350
|
/>
|
|
1292
1351
|
</Tabs>
|
|
1293
1352
|
<div>
|
|
1294
|
-
<TabContent
|
|
1353
|
+
<TabContent
|
|
1354
|
+
eventKey={0}
|
|
1355
|
+
id="refTab1Section"
|
|
1356
|
+
ref={this.contentRef1}
|
|
1357
|
+
aria-label="This is content for the first tab"
|
|
1358
|
+
>
|
|
1295
1359
|
Tab 1 section
|
|
1296
1360
|
</TabContent>
|
|
1297
|
-
<TabContent
|
|
1361
|
+
<TabContent
|
|
1362
|
+
eventKey={1}
|
|
1363
|
+
id="refTab2Section"
|
|
1364
|
+
ref={this.contentRef2}
|
|
1365
|
+
aria-label="This is content for the second tab"
|
|
1366
|
+
hidden
|
|
1367
|
+
>
|
|
1298
1368
|
Tab 2 section
|
|
1299
1369
|
</TabContent>
|
|
1300
|
-
<TabContent
|
|
1370
|
+
<TabContent
|
|
1371
|
+
eventKey={2}
|
|
1372
|
+
id="refTab3Section"
|
|
1373
|
+
ref={this.contentRef3}
|
|
1374
|
+
aria-label="This is content for the third tab"
|
|
1375
|
+
hidden
|
|
1376
|
+
>
|
|
1301
1377
|
Tab 3 section
|
|
1302
1378
|
</TabContent>
|
|
1303
1379
|
</div>
|
|
@@ -1351,10 +1427,22 @@ const TabContentWithBody = () => {
|
|
|
1351
1427
|
<TabContent eventKey={0} id="refTab1Section" ref={contentRef1} aria-label="This is content for the first tab">
|
|
1352
1428
|
<TabContentBody hasPadding> Tab 1 section </TabContentBody>
|
|
1353
1429
|
</TabContent>
|
|
1354
|
-
<TabContent
|
|
1430
|
+
<TabContent
|
|
1431
|
+
eventKey={1}
|
|
1432
|
+
id="refTab2Section"
|
|
1433
|
+
ref={contentRef2}
|
|
1434
|
+
aria-label="This is content for the second tab"
|
|
1435
|
+
hidden
|
|
1436
|
+
>
|
|
1355
1437
|
<TabContentBody hasPadding> Tab 2 section </TabContentBody>
|
|
1356
1438
|
</TabContent>
|
|
1357
|
-
<TabContent
|
|
1439
|
+
<TabContent
|
|
1440
|
+
eventKey={2}
|
|
1441
|
+
id="refTab3Section"
|
|
1442
|
+
ref={contentRef3}
|
|
1443
|
+
aria-label="This is content for the third tab"
|
|
1444
|
+
hidden
|
|
1445
|
+
>
|
|
1358
1446
|
<TabContentBody hasPadding> Tab 3 section </TabContentBody>
|
|
1359
1447
|
</TabContent>
|
|
1360
1448
|
</div>
|
|
@@ -1385,7 +1473,12 @@ class MountingSimpleTabs extends React.Component {
|
|
|
1385
1473
|
|
|
1386
1474
|
render() {
|
|
1387
1475
|
return (
|
|
1388
|
-
<Tabs
|
|
1476
|
+
<Tabs
|
|
1477
|
+
mountOnEnter
|
|
1478
|
+
activeKey={this.state.activeTabKey}
|
|
1479
|
+
onSelect={this.handleTabClick}
|
|
1480
|
+
aria-label="Tabs in the children mounting on click example"
|
|
1481
|
+
>
|
|
1389
1482
|
<Tab eventKey={0} title={<TabTitleText>Tab item 1</TabTitleText>}>
|
|
1390
1483
|
Tab 1 section
|
|
1391
1484
|
</Tab>
|
|
@@ -1423,7 +1516,12 @@ class UnmountingSimpleTabs extends React.Component {
|
|
|
1423
1516
|
|
|
1424
1517
|
render() {
|
|
1425
1518
|
return (
|
|
1426
|
-
<Tabs
|
|
1519
|
+
<Tabs
|
|
1520
|
+
unmountOnExit
|
|
1521
|
+
activeKey={this.state.activeTabKey}
|
|
1522
|
+
onSelect={this.handleTabClick}
|
|
1523
|
+
aria-label="Tabs in the unmounting invisible children example"
|
|
1524
|
+
>
|
|
1427
1525
|
<Tab eventKey={0} title={<TabTitleText>Tab item 1</TabTitleText>}>
|
|
1428
1526
|
Tab 1 section
|
|
1429
1527
|
</Tab>
|
|
@@ -1473,7 +1571,11 @@ class ToggledSeparateContent extends React.Component {
|
|
|
1473
1571
|
{isTab2Hidden ? 'Show' : 'Hide'} tab 2
|
|
1474
1572
|
</Button>
|
|
1475
1573
|
<Divider style={{ paddingTop: '1rem', paddingBottom: '1rem' }} />
|
|
1476
|
-
<Tabs
|
|
1574
|
+
<Tabs
|
|
1575
|
+
activeKey={this.state.activeTabKey}
|
|
1576
|
+
onSelect={this.handleTabClick}
|
|
1577
|
+
aria-label="Tabs in the toggled separate content example"
|
|
1578
|
+
>
|
|
1477
1579
|
<Tab eventKey={0} title="Tab item 1" tabContentId="refTab1Section" tabContentRef={this.contentRef1} />
|
|
1478
1580
|
{!isTab2Hidden && (
|
|
1479
1581
|
<Tab eventKey={1} title="Tab item 2" tabContentId="refTab2Section" tabContentRef={this.contentRef2} />
|
|
@@ -1481,15 +1583,32 @@ class ToggledSeparateContent extends React.Component {
|
|
|
1481
1583
|
<Tab eventKey={2} title="Tab item 3" tabContentId="refTab3Section" tabContentRef={this.contentRef3} />
|
|
1482
1584
|
</Tabs>
|
|
1483
1585
|
<div>
|
|
1484
|
-
<TabContent
|
|
1586
|
+
<TabContent
|
|
1587
|
+
eventKey={0}
|
|
1588
|
+
id="refTab1Section"
|
|
1589
|
+
ref={this.contentRef1}
|
|
1590
|
+
aria-label="This is content for the first tab"
|
|
1591
|
+
>
|
|
1485
1592
|
Tab 1 section
|
|
1486
1593
|
</TabContent>
|
|
1487
1594
|
{!isTab2Hidden && (
|
|
1488
|
-
<TabContent
|
|
1595
|
+
<TabContent
|
|
1596
|
+
eventKey={1}
|
|
1597
|
+
id="refTab2Section"
|
|
1598
|
+
ref={this.contentRef2}
|
|
1599
|
+
aria-label="This is content for the second tab"
|
|
1600
|
+
hidden
|
|
1601
|
+
>
|
|
1489
1602
|
Tab 2 section
|
|
1490
1603
|
</TabContent>
|
|
1491
1604
|
)}
|
|
1492
|
-
<TabContent
|
|
1605
|
+
<TabContent
|
|
1606
|
+
eventKey={2}
|
|
1607
|
+
id="refTab3Section"
|
|
1608
|
+
ref={this.contentRef3}
|
|
1609
|
+
aria-label="This is content for the third tab"
|
|
1610
|
+
hidden
|
|
1611
|
+
>
|
|
1493
1612
|
Tab 3 section
|
|
1494
1613
|
</TabContent>
|
|
1495
1614
|
</div>
|
|
@@ -35,6 +35,12 @@ export interface TooltipProps extends Omit<React.HTMLProps<HTMLDivElement>, 'con
|
|
|
35
35
|
* If you don't want that or prefer to add the aria attribute yourself on the trigger, set aria to 'none'.
|
|
36
36
|
*/
|
|
37
37
|
aria?: 'describedby' | 'labelledby' | 'none';
|
|
38
|
+
/**
|
|
39
|
+
* Determines whether the tooltip is an aria-live region. If the reference prop is passed in the
|
|
40
|
+
* default behavior is 'polite' in order to ensure the tooltip contents is announced to
|
|
41
|
+
* assistive technologies. Otherwise the default behavior is 'off'.
|
|
42
|
+
*/
|
|
43
|
+
'aria-live'?: 'off' | 'polite';
|
|
38
44
|
/**
|
|
39
45
|
* The reference element to which the Tooltip is relatively placed to.
|
|
40
46
|
* If you cannot wrap the reference with the Tooltip, you can use the reference prop instead.
|
|
@@ -155,6 +161,7 @@ export const Tooltip: React.FunctionComponent<TooltipProps> = ({
|
|
|
155
161
|
children,
|
|
156
162
|
animationDuration = 300,
|
|
157
163
|
reference,
|
|
164
|
+
'aria-live': ariaLive = reference ? 'polite' : 'off',
|
|
158
165
|
boundary,
|
|
159
166
|
isAppLauncher,
|
|
160
167
|
tippyProps,
|
|
@@ -251,6 +258,7 @@ export const Tooltip: React.FunctionComponent<TooltipProps> = ({
|
|
|
251
258
|
const hasCustomMaxWidth = maxWidth !== tooltipMaxWidth.value;
|
|
252
259
|
const content = (
|
|
253
260
|
<div
|
|
261
|
+
aria-live={ariaLive}
|
|
254
262
|
className={css(styles.tooltip, className)}
|
|
255
263
|
role="tooltip"
|
|
256
264
|
id={id}
|
|
@@ -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
|
```
|
|
@@ -47,6 +47,8 @@ Composable menus currently require consumer keyboard handling and use of our und
|
|
|
47
47
|
|
|
48
48
|
### Composable tree view menu
|
|
49
49
|
|
|
50
|
+
When rendering a menu-like element that does not contain MenuItem components, [Panel](/components/panel) allows more flexible control and customization.
|
|
51
|
+
|
|
50
52
|
```ts file="./examples/ComposableTreeViewMenu.tsx"
|
|
51
53
|
```
|
|
52
54
|
|