@patternfly/react-core 4.264.0 → 4.265.0

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.
Files changed (123) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/esm/components/Badge/Badge.d.ts +2 -0
  3. package/dist/esm/components/Badge/Badge.d.ts.map +1 -1
  4. package/dist/esm/components/Badge/Badge.js +4 -2
  5. package/dist/esm/components/Badge/Badge.js.map +1 -1
  6. package/dist/esm/components/TimePicker/TimePicker.d.ts +0 -1
  7. package/dist/esm/components/TimePicker/TimePicker.d.ts.map +1 -1
  8. package/dist/esm/components/TimePicker/TimePicker.js +1 -9
  9. package/dist/esm/components/TimePicker/TimePicker.js.map +1 -1
  10. package/dist/esm/next/components/Dropdown/DropdownItem.d.ts +2 -0
  11. package/dist/esm/next/components/Dropdown/DropdownItem.d.ts.map +1 -1
  12. package/dist/esm/next/components/Dropdown/DropdownItem.js +2 -2
  13. package/dist/esm/next/components/Dropdown/DropdownItem.js.map +1 -1
  14. package/dist/esm/next/components/Wizard/Wizard.d.ts +1 -1
  15. package/dist/esm/next/components/Wizard/Wizard.d.ts.map +1 -1
  16. package/dist/esm/next/components/Wizard/WizardContext.d.ts +2 -2
  17. package/dist/esm/next/components/Wizard/WizardContext.d.ts.map +1 -1
  18. package/dist/esm/next/components/Wizard/WizardFooter.d.ts +2 -2
  19. package/dist/esm/next/components/Wizard/WizardFooter.d.ts.map +1 -1
  20. package/dist/esm/next/components/Wizard/WizardNavInternal.js +2 -2
  21. package/dist/esm/next/components/Wizard/WizardNavInternal.js.map +1 -1
  22. package/dist/esm/next/components/Wizard/WizardNavItem.js +1 -1
  23. package/dist/esm/next/components/Wizard/WizardNavItem.js.map +1 -1
  24. package/dist/esm/next/components/Wizard/WizardStep.d.ts +2 -0
  25. package/dist/esm/next/components/Wizard/WizardStep.d.ts.map +1 -1
  26. package/dist/esm/next/components/Wizard/WizardStep.js.map +1 -1
  27. package/dist/esm/next/components/Wizard/types.d.ts +4 -2
  28. package/dist/esm/next/components/Wizard/types.d.ts.map +1 -1
  29. package/dist/esm/next/components/Wizard/types.js.map +1 -1
  30. package/dist/js/components/Badge/Badge.d.ts +2 -0
  31. package/dist/js/components/Badge/Badge.d.ts.map +1 -1
  32. package/dist/js/components/Badge/Badge.js +4 -2
  33. package/dist/js/components/Badge/Badge.js.map +1 -1
  34. package/dist/js/components/TimePicker/TimePicker.d.ts +0 -1
  35. package/dist/js/components/TimePicker/TimePicker.d.ts.map +1 -1
  36. package/dist/js/components/TimePicker/TimePicker.js +1 -9
  37. package/dist/js/components/TimePicker/TimePicker.js.map +1 -1
  38. package/dist/js/next/components/Dropdown/DropdownItem.d.ts +2 -0
  39. package/dist/js/next/components/Dropdown/DropdownItem.d.ts.map +1 -1
  40. package/dist/js/next/components/Dropdown/DropdownItem.js +2 -2
  41. package/dist/js/next/components/Dropdown/DropdownItem.js.map +1 -1
  42. package/dist/js/next/components/Wizard/Wizard.d.ts +1 -1
  43. package/dist/js/next/components/Wizard/Wizard.d.ts.map +1 -1
  44. package/dist/js/next/components/Wizard/WizardContext.d.ts +2 -2
  45. package/dist/js/next/components/Wizard/WizardContext.d.ts.map +1 -1
  46. package/dist/js/next/components/Wizard/WizardFooter.d.ts +2 -2
  47. package/dist/js/next/components/Wizard/WizardFooter.d.ts.map +1 -1
  48. package/dist/js/next/components/Wizard/WizardNavInternal.js +2 -2
  49. package/dist/js/next/components/Wizard/WizardNavInternal.js.map +1 -1
  50. package/dist/js/next/components/Wizard/WizardNavItem.js +1 -1
  51. package/dist/js/next/components/Wizard/WizardNavItem.js.map +1 -1
  52. package/dist/js/next/components/Wizard/WizardStep.d.ts +2 -0
  53. package/dist/js/next/components/Wizard/WizardStep.d.ts.map +1 -1
  54. package/dist/js/next/components/Wizard/WizardStep.js.map +1 -1
  55. package/dist/js/next/components/Wizard/types.d.ts +4 -2
  56. package/dist/js/next/components/Wizard/types.d.ts.map +1 -1
  57. package/dist/js/next/components/Wizard/types.js.map +1 -1
  58. package/dist/umd/react-core.min.css +80 -80
  59. package/dist/umd/react-core.min.js +2 -2
  60. package/package.json +14 -7
  61. package/src/components/Badge/Badge.tsx +4 -0
  62. package/src/components/Badge/__tests__/Badge.test.tsx +10 -0
  63. package/src/components/Badge/examples/BadgeUnread.tsx +12 -1
  64. package/src/components/Menu/examples/MenuWithDrilldownBreadcrumbs.tsx +60 -22
  65. package/src/components/TimePicker/TimePicker.tsx +0 -11
  66. package/src/components/Tooltip/examples/Tooltip.md +5 -285
  67. package/src/components/Tooltip/examples/TooltipBasic.tsx +16 -0
  68. package/src/components/Tooltip/examples/TooltipIcon.tsx +24 -0
  69. package/src/components/Tooltip/examples/TooltipOptions.tsx +197 -0
  70. package/src/components/Tooltip/examples/TooltipReactRef.tsx +22 -0
  71. package/src/components/Tooltip/examples/TooltipSelectorRef.tsx +19 -0
  72. package/src/next/components/Dropdown/DropdownItem.tsx +4 -1
  73. package/src/next/components/Wizard/Wizard.tsx +1 -1
  74. package/src/next/components/Wizard/WizardContext.tsx +2 -2
  75. package/src/next/components/Wizard/WizardFooter.tsx +2 -2
  76. package/src/next/components/Wizard/WizardNavInternal.tsx +1 -1
  77. package/src/next/components/Wizard/WizardNavItem.tsx +1 -1
  78. package/src/next/components/Wizard/WizardStep.tsx +2 -0
  79. package/src/next/components/Wizard/__tests__/Wizard.test.tsx +33 -1
  80. package/src/next/components/Wizard/__tests__/WizardStep.test.tsx +1 -2
  81. package/src/next/components/Wizard/examples/Wizard.md +1 -1
  82. package/src/next/components/Wizard/examples/WizardKitchenSink.tsx +21 -2
  83. package/src/next/components/Wizard/types.tsx +9 -4
  84. package/dist/esm/components/Button/__mocks__/Button.d.ts +0 -8
  85. package/dist/esm/components/Button/__mocks__/Button.d.ts.map +0 -1
  86. package/dist/esm/components/Button/__mocks__/Button.js +0 -14
  87. package/dist/esm/components/Button/__mocks__/Button.js.map +0 -1
  88. package/dist/esm/components/Button/__mocks__/index.d.ts +0 -2
  89. package/dist/esm/components/Button/__mocks__/index.d.ts.map +0 -1
  90. package/dist/esm/components/Button/__mocks__/index.js +0 -2
  91. package/dist/esm/components/Button/__mocks__/index.js.map +0 -1
  92. package/dist/esm/components/HelperText/__mocks__/HelperText.d.ts +0 -4
  93. package/dist/esm/components/HelperText/__mocks__/HelperText.d.ts.map +0 -1
  94. package/dist/esm/components/HelperText/__mocks__/HelperText.js +0 -5
  95. package/dist/esm/components/HelperText/__mocks__/HelperText.js.map +0 -1
  96. package/dist/esm/components/HelperText/__mocks__/HelperTextItem.d.ts +0 -4
  97. package/dist/esm/components/HelperText/__mocks__/HelperTextItem.d.ts.map +0 -1
  98. package/dist/esm/components/HelperText/__mocks__/HelperTextItem.js +0 -5
  99. package/dist/esm/components/HelperText/__mocks__/HelperTextItem.js.map +0 -1
  100. package/dist/esm/components/HelperText/__mocks__/index.d.ts +0 -3
  101. package/dist/esm/components/HelperText/__mocks__/index.d.ts.map +0 -1
  102. package/dist/esm/components/HelperText/__mocks__/index.js +0 -3
  103. package/dist/esm/components/HelperText/__mocks__/index.js.map +0 -1
  104. package/dist/js/components/Button/__mocks__/Button.d.ts +0 -8
  105. package/dist/js/components/Button/__mocks__/Button.d.ts.map +0 -1
  106. package/dist/js/components/Button/__mocks__/Button.js +0 -18
  107. package/dist/js/components/Button/__mocks__/Button.js.map +0 -1
  108. package/dist/js/components/Button/__mocks__/index.d.ts +0 -2
  109. package/dist/js/components/Button/__mocks__/index.d.ts.map +0 -1
  110. package/dist/js/components/Button/__mocks__/index.js +0 -5
  111. package/dist/js/components/Button/__mocks__/index.js.map +0 -1
  112. package/dist/js/components/HelperText/__mocks__/HelperText.d.ts +0 -4
  113. package/dist/js/components/HelperText/__mocks__/HelperText.d.ts.map +0 -1
  114. package/dist/js/components/HelperText/__mocks__/HelperText.js +0 -10
  115. package/dist/js/components/HelperText/__mocks__/HelperText.js.map +0 -1
  116. package/dist/js/components/HelperText/__mocks__/HelperTextItem.d.ts +0 -4
  117. package/dist/js/components/HelperText/__mocks__/HelperTextItem.d.ts.map +0 -1
  118. package/dist/js/components/HelperText/__mocks__/HelperTextItem.js +0 -10
  119. package/dist/js/components/HelperText/__mocks__/HelperTextItem.js.map +0 -1
  120. package/dist/js/components/HelperText/__mocks__/index.d.ts +0 -3
  121. package/dist/js/components/HelperText/__mocks__/index.d.ts.map +0 -1
  122. package/dist/js/components/HelperText/__mocks__/index.js +0 -6
  123. package/dist/js/components/HelperText/__mocks__/index.js.map +0 -1
package/package.json CHANGED
@@ -1,10 +1,17 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.264.0",
3
+ "version": "4.265.0",
4
4
  "description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
5
5
  "main": "dist/js/index.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "types": "dist/esm/index.d.ts",
8
+ "exports": {
9
+ ".": "./dist/esm/index.js",
10
+ "./dist/*": "./dist/*",
11
+ "./next": "./dist/esm/next",
12
+ "./deprecated": "./dist/esm/deprecated",
13
+ "./package.json": "./package.json"
14
+ },
8
15
  "typesVersions": {
9
16
  "*": {
10
17
  "next": [
@@ -44,18 +51,18 @@
44
51
  "generate": "node scripts/copyStyles.js"
45
52
  },
46
53
  "dependencies": {
47
- "@patternfly/react-icons": "^4.93.0",
48
- "@patternfly/react-styles": "^4.92.0",
49
- "@patternfly/react-tokens": "^4.94.0",
54
+ "@patternfly/react-icons": "^4.93.1",
55
+ "@patternfly/react-styles": "^4.92.1",
56
+ "@patternfly/react-tokens": "^4.94.1",
50
57
  "focus-trap": "6.9.2",
51
58
  "react-dropzone": "9.0.0",
52
59
  "tippy.js": "5.1.2",
53
60
  "tslib": "^2.0.0"
54
61
  },
55
62
  "devDependencies": {
56
- "@patternfly/patternfly": "4.221.2",
63
+ "@patternfly/patternfly": "4.221.3",
57
64
  "@rollup/plugin-commonjs": "^21.0.0",
58
- "@rollup/plugin-node-resolve": "^13.0.0",
65
+ "@rollup/plugin-node-resolve": "^15.0.1",
59
66
  "@rollup/plugin-replace": "^3.0.0",
60
67
  "css": "^2.2.3",
61
68
  "fs-extra": "^6.0.1",
@@ -70,5 +77,5 @@
70
77
  "react": "^16.8 || ^17 || ^18",
71
78
  "react-dom": "^16.8 || ^17 || ^18"
72
79
  },
73
- "gitHead": "e1f95ce96852165dd4d102cd87c6b49288f01eff"
80
+ "gitHead": "47c6127c70191349261aec122b56e6ca61fa0c99"
74
81
  }
@@ -3,6 +3,8 @@ import { css } from '@patternfly/react-styles';
3
3
  import styles from '@patternfly/react-styles/css/components/Badge/badge';
4
4
 
5
5
  export interface BadgeProps extends React.HTMLProps<HTMLSpanElement> {
6
+ /** Text announced by screen readers to indicate the current content/status of the badge. */
7
+ screenReaderText?: string;
6
8
  /** Adds styling to the badge to indicate it has been read */
7
9
  isRead?: boolean;
8
10
  /** content rendered inside the Badge */
@@ -15,6 +17,7 @@ export const Badge: React.FunctionComponent<BadgeProps> = ({
15
17
  isRead = false,
16
18
  className = '',
17
19
  children = '',
20
+ screenReaderText,
18
21
  ...props
19
22
  }: BadgeProps) => (
20
23
  <span
@@ -22,6 +25,7 @@ export const Badge: React.FunctionComponent<BadgeProps> = ({
22
25
  className={css(styles.badge, (isRead ? styles.modifiers.read : styles.modifiers.unread) as any, className)}
23
26
  >
24
27
  {children}
28
+ {screenReaderText && <span className="pf-screen-reader">{screenReaderText}</span>}
25
29
  </span>
26
30
  );
27
31
  Badge.displayName = 'Badge';
@@ -31,6 +31,16 @@ test('Renders with class name pf-m-read when isRead prop is true', () => {
31
31
  expect(screen.getByText('Test')).toHaveClass('pf-m-read');
32
32
  });
33
33
 
34
+ test('Does not render pf-screen-reader class by default', () => {
35
+ render(<Badge>Test</Badge>);
36
+ expect(screen.getByText('Test')).not.toContainHTML('<span class="pf-screen-reader"></span>');
37
+ });
38
+
39
+ test('Renders screenReaderText passed via prop', () => {
40
+ render(<Badge screenReaderText="Custom screen reader text">Test</Badge>);
41
+ expect(screen.getByText('Custom screen reader text')).toBeInTheDocument();
42
+ });
43
+
34
44
  test('Renders with custom class name when className prop is provided', () => {
35
45
  render(<Badge className="custom-class">Test</Badge>);
36
46
  expect(screen.getByText('Test')).toHaveClass('custom-class');
@@ -3,6 +3,17 @@ import { Badge } from '@patternfly/react-core';
3
3
 
4
4
  export const BadgeUnread: React.FunctionComponent = () => (
5
5
  <React.Fragment>
6
- <Badge key={1}>7</Badge> <Badge key={2}>24</Badge> <Badge key={3}>240</Badge> <Badge key={4}>999+</Badge>
6
+ <Badge key={1} screenReaderText="Unread Messages">
7
+ 7
8
+ </Badge>
9
+ <Badge key={2} screenReaderText="Unread Messages">
10
+ 24
11
+ </Badge>
12
+ <Badge key={3} screenReaderText="Unread Messages">
13
+ 240
14
+ </Badge>
15
+ <Badge key={4} screenReaderText="Unread Messages">
16
+ 999+
17
+ </Badge>
7
18
  </React.Fragment>
8
19
  );
@@ -26,7 +26,7 @@ export const MenuWithDrilldownBreadcrumbs: React.FunctionComponent = () => {
26
26
  const [drilldownPath, setDrilldownPath] = React.useState<string[]>([]);
27
27
  const [menuHeights, setMenuHeights] = React.useState<any>({});
28
28
  const [activeMenu, setActiveMenu] = React.useState<string>('breadcrumbs-rootMenu');
29
- const [breadcrumb, setBreadcrumb] = React.useState<JSX.Element>();
29
+ const [breadcrumb, setBreadcrumb] = React.useState<JSX.Element | null>();
30
30
  const [withMaxMenuHeight, setWithMaxMenuHeight] = React.useState(false);
31
31
 
32
32
  const onToggle = (isOpen: boolean, key: string) => {
@@ -37,6 +37,12 @@ export const MenuWithDrilldownBreadcrumbs: React.FunctionComponent = () => {
37
37
  case 'label':
38
38
  setBreadcrumb(labelsBreadcrumb(isOpen));
39
39
  break;
40
+ case 'pause-app':
41
+ setBreadcrumb(pauseRolloutsAppGrpBreadcrumb(isOpen));
42
+ break;
43
+ case 'pause-label':
44
+ setBreadcrumb(pauseRolloutsLabelsBreadcrumb(isOpen));
45
+ break;
40
46
  default:
41
47
  break;
42
48
  }
@@ -46,14 +52,17 @@ export const MenuWithDrilldownBreadcrumbs: React.FunctionComponent = () => {
46
52
  setWithMaxMenuHeight(checked);
47
53
  };
48
54
 
49
- const drillOut = (toMenuId: string, fromPathId: string, _breadcrumb: JSX.Element | null) => {
50
- const indexOfMenuId = menuDrilledIn.indexOf(toMenuId);
51
- const menuDrilledInSansLast = menuDrilledIn.slice(0, indexOfMenuId);
52
- const indexOfMenuIdPath = drilldownPath.indexOf(fromPathId);
53
- const pathSansLast = drilldownPath.slice(0, indexOfMenuIdPath);
54
- setMenuDrilledIn(menuDrilledInSansLast);
55
- setDrilldownPath(pathSansLast);
55
+ const drillOut = (toMenuId: string, fromPathId: string, breadcrumb: JSX.Element | null) => {
56
+ setMenuDrilledIn(prevMenuDrilledIn => {
57
+ const indexOfMenuId = prevMenuDrilledIn.indexOf(toMenuId);
58
+ return prevMenuDrilledIn.slice(0, indexOfMenuId);
59
+ });
60
+ setDrilldownPath(prevDrilldownPath => {
61
+ const indexOfMenuIdPath = prevDrilldownPath.indexOf(fromPathId);
62
+ return prevDrilldownPath.slice(0, indexOfMenuIdPath);
63
+ });
56
64
  setActiveMenu(toMenuId);
65
+ setBreadcrumb(breadcrumb);
57
66
  };
58
67
 
59
68
  const setHeight = (menuId: string, height: number) => {
@@ -146,31 +155,59 @@ export const MenuWithDrilldownBreadcrumbs: React.FunctionComponent = () => {
146
155
  </Breadcrumb>
147
156
  );
148
157
 
149
- const pauseRolloutsAppGrpBreadcrumb = (
158
+ const pauseRolloutsAppGrpBreadcrumb = (isOpen: boolean) => (
150
159
  <Breadcrumb>
151
160
  <BreadcrumbItem component="button" onClick={() => drillOut('breadcrumbs-rootMenu', 'group:pause_rollout', null)}>
152
161
  Root
153
162
  </BreadcrumbItem>
154
- <BreadcrumbItem
155
- component="button"
156
- onClick={() => drillOut('breadcrumbs-drilldownMenuPause', 'group:app_grouping', pauseRolloutsBreadcrumb)}
157
- >
158
- Pause rollouts
163
+ <BreadcrumbItem isDropdown>
164
+ <Dropdown
165
+ toggle={
166
+ <BadgeToggle id="toggle-id" onToggle={open => onToggle(open, 'pause-app')}>
167
+ 1
168
+ </BadgeToggle>
169
+ }
170
+ isOpen={isOpen}
171
+ dropdownItems={[
172
+ <DropdownItem
173
+ key="dropdown-pause"
174
+ component="button"
175
+ icon={<AngleLeftIcon />}
176
+ onClick={() => drillOut('breadcrumbs-drilldownMenuPause', 'group:app_grouping', pauseRolloutsBreadcrumb)}
177
+ >
178
+ Pause rollouts
179
+ </DropdownItem>
180
+ ]}
181
+ />
159
182
  </BreadcrumbItem>
160
183
  <BreadcrumbHeading component="button">Application Grouping</BreadcrumbHeading>
161
184
  </Breadcrumb>
162
185
  );
163
186
 
164
- const pauseRolloutsLabelsBreadcrumb = (
187
+ const pauseRolloutsLabelsBreadcrumb = (isOpen: boolean) => (
165
188
  <Breadcrumb>
166
189
  <BreadcrumbItem component="button" onClick={() => drillOut('breadcrumbs-rootMenu', 'group:pause_rollout', null)}>
167
190
  Root
168
191
  </BreadcrumbItem>
169
- <BreadcrumbItem
170
- component="button"
171
- onClick={() => drillOut('breadcrumbs-drilldownMenuPause', 'group:labels', pauseRolloutsBreadcrumb)}
172
- >
173
- Pause rollouts
192
+ <BreadcrumbItem isDropdown>
193
+ <Dropdown
194
+ toggle={
195
+ <BadgeToggle id="toggle-id" onToggle={open => onToggle(open, 'pause-label')}>
196
+ 1
197
+ </BadgeToggle>
198
+ }
199
+ isOpen={isOpen}
200
+ dropdownItems={[
201
+ <DropdownItem
202
+ key="dropdown-pause"
203
+ component="button"
204
+ icon={<AngleLeftIcon />}
205
+ onClick={() => drillOut('breadcrumbs-drilldownMenuPause', 'group:labels', pauseRolloutsBreadcrumb)}
206
+ >
207
+ Pause rollouts
208
+ </DropdownItem>
209
+ ]}
210
+ />
174
211
  </BreadcrumbItem>
175
212
  <BreadcrumbHeading component="button">Labels</BreadcrumbHeading>
176
213
  </Breadcrumb>
@@ -205,6 +242,7 @@ export const MenuWithDrilldownBreadcrumbs: React.FunctionComponent = () => {
205
242
  onDrillIn={drillIn}
206
243
  onDrillOut={() => drillOut}
207
244
  onGetMenuHeight={setHeight}
245
+ isScrollable={withMaxMenuHeight}
208
246
  >
209
247
  {breadcrumb && (
210
248
  <>
@@ -270,7 +308,7 @@ export const MenuWithDrilldownBreadcrumbs: React.FunctionComponent = () => {
270
308
  itemId="group:app_grouping"
271
309
  description="Groups A-C"
272
310
  direction="down"
273
- onClick={() => setBreadcrumb(pauseRolloutsAppGrpBreadcrumb)}
311
+ onClick={() => setBreadcrumb(pauseRolloutsAppGrpBreadcrumb(false))}
274
312
  drilldownMenu={
275
313
  <DrilldownMenu id="breadcrumbs-drilldownMenuGrouping">
276
314
  <MenuItem itemId="group_a">Group A</MenuItem>
@@ -285,7 +323,7 @@ export const MenuWithDrilldownBreadcrumbs: React.FunctionComponent = () => {
285
323
  <MenuItem
286
324
  itemId="group:labels"
287
325
  direction="down"
288
- onClick={() => setBreadcrumb(pauseRolloutsLabelsBreadcrumb)}
326
+ onClick={() => setBreadcrumb(pauseRolloutsLabelsBreadcrumb(false))}
289
327
  drilldownMenu={
290
328
  <DrilldownMenu id="breadcrumbs-drilldownMenuLabels">
291
329
  <MenuItem itemId="label_1">Label 1</MenuItem>
@@ -426,16 +426,6 @@ export class TimePicker extends React.Component<TimePickerProps, TimePickerState
426
426
  });
427
427
  };
428
428
 
429
- onBlur = (event: React.FocusEvent<HTMLInputElement>) => {
430
- const { timeRegex } = this.state;
431
- const { delimiter, is24Hour, includeSeconds } = this.props;
432
- const time = parseTime(event.currentTarget.value, timeRegex, delimiter, !is24Hour, includeSeconds);
433
-
434
- this.setState({
435
- isInvalid: !this.isValid(time)
436
- });
437
- };
438
-
439
429
  render() {
440
430
  const {
441
431
  'aria-label': ariaLabel,
@@ -507,7 +497,6 @@ export class TimePicker extends React.Component<TimePickerProps, TimePickerState
507
497
  iconVariant="clock"
508
498
  onClick={this.onInputClick}
509
499
  onChange={this.onInputChange}
510
- onBlur={this.onBlur}
511
500
  autoComplete="off"
512
501
  isDisabled={isDisabled}
513
502
  ref={this.inputRef}
@@ -13,68 +13,17 @@ import './TooltipExamples.css';
13
13
 
14
14
  ### Basic
15
15
 
16
- ```js
17
- import React from 'react';
18
- import { Tooltip } from '@patternfly/react-core';
19
-
20
- <div style={{ margin: '100px' }}>
21
- <Tooltip
22
- content={
23
- <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.</div>
24
- }
25
- >
26
- <span tabIndex="0" style={{ border: '1px dashed' }}>
27
- I have a tooltip!
28
- </span>
29
- </Tooltip>
30
- </div>;
16
+ ```ts file="./TooltipBasic.tsx"
31
17
  ```
32
18
 
33
19
  ### Tooltip react ref
34
20
 
35
- ```js
36
- import React from 'react';
37
- import { Tooltip } from '@patternfly/react-core';
38
-
39
- TooltipReactRef = () => {
40
- const tooltipRef = React.useRef();
41
- return (
42
- <div style={{ margin: '100px' }}>
43
- <button aria-describedby="tooltip-ref1" ref={tooltipRef}>
44
- Tooltip attached via react ref
45
- </button>
46
- <Tooltip
47
- id="tooltip-ref1"
48
- content={
49
- <div>
50
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.
51
- </div>
52
- }
53
- reference={tooltipRef}
54
- />
55
- </div>
56
- );
57
- };
21
+ ```ts file="./TooltipReactRef.tsx"
58
22
  ```
59
23
 
60
24
  ### Tooltip selector ref
61
25
 
62
- ```js
63
- import React from 'react';
64
- import { Tooltip } from '@patternfly/react-core';
65
-
66
- <div style={{ margin: '100px' }}>
67
- <button aria-describedby="tooltip-ref2" id="tooltip-selector">
68
- Tooltip attached via selector ref
69
- </button>
70
- <Tooltip
71
- id="tooltip-ref2"
72
- content={
73
- <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.</div>
74
- }
75
- reference={() => document.getElementById('tooltip-selector')}
76
- />
77
- </div>;
26
+ ```ts file="./TooltipSelectorRef.tsx"
78
27
  ```
79
28
 
80
29
  ### On icon with dynamic content
@@ -83,239 +32,10 @@ When the tooltip is used as a wrapper and its content will dynamically update, t
83
32
 
84
33
  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
34
 
86
- ```js
87
- import React from 'react';
88
- import { Tooltip, Button } from '@patternfly/react-core';
89
- import CopyIcon from '@patternfly/react-icons/dist/esm/icons/copy-icon';
90
-
91
- IconExample = () => {
92
- const [showSuccessContent, setShowSuccessContent] = React.useState(false);
93
- const copyText = 'Copy to clipboard';
94
- const doneCopyText = 'Successfully copied to clipboard!';
95
- const [content, setContent] = React.useState(copyText);
96
- return (
97
- <div style={{ margin: '100px' }}>
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
- >
105
- <CopyIcon />
106
- </Button>
107
- </Tooltip>
108
- </div>
109
- );
110
- };
35
+ ```ts file="./TooltipIcon.tsx"
111
36
  ```
112
37
 
113
38
  ### Options
114
39
 
115
- ```js
116
- import React from 'react';
117
- import { Button, Tooltip, Checkbox, Select, SelectOption, TextInput } from '@patternfly/react-core';
118
-
119
- OptionsTooltip = () => {
120
- const [trigger, setTrigger] = React.useState(['mouseenter', 'focus']);
121
- const [isVisible, setIsVisible] = React.useState(true);
122
- const [contentLeftAligned, setContentLeftAligned] = React.useState(false);
123
- const [enableFlip, setEnableFlip] = React.useState(true);
124
- const [position, setPosition] = React.useState('top');
125
- const [positionSelectOpen, setPositionSelectOpen] = React.useState(false);
126
- const [flipSelectOpen, setFlipSelectOpen] = React.useState(false);
127
- const [flipBehavior, setFlipBehavior] = React.useState('flip');
128
- const [entryDelayInput, setEntryDelayInput] = React.useState(0);
129
- const [exitDelayInput, setExitDelayInput] = React.useState(0);
130
- const [animationDuration, setAnimationDuration] = React.useState(300);
131
- const tipBoxRef = React.useRef(null);
132
-
133
- const scrollToRef = ref => {
134
- if (ref && ref.current) {
135
- ref.current.scrollTop = 400;
136
- ref.current.scrollLeft = 300;
137
- }
138
- };
139
-
140
- React.useEffect(() => {
141
- scrollToRef(tipBoxRef);
142
- }, []);
143
-
144
- return (
145
- <>
146
- <div>
147
- <div style={{ border: '1px solid' }}>
148
- <Checkbox
149
- label="trigger: mouseenter"
150
- isChecked={trigger.includes('mouseenter')}
151
- onChange={checked => {
152
- let updatedTrigger;
153
- checked && (updatedTrigger = trigger.concat('mouseenter'));
154
- !checked && (updatedTrigger = trigger.filter(t => t !== 'mouseenter'));
155
- setIsVisible(false);
156
- setTrigger(updatedTrigger);
157
- }}
158
- aria-label="trigger: mouseenter"
159
- id="trigger_mouseenter"
160
- />
161
- <Checkbox
162
- label="trigger: focus"
163
- isChecked={trigger.includes('focus')}
164
- onChange={checked => {
165
- let updatedTrigger;
166
- checked && (updatedTrigger = trigger.concat('focus'));
167
- !checked && (updatedTrigger = trigger.filter(t => t !== 'focus'));
168
- setIsVisible(false);
169
- setTrigger(updatedTrigger);
170
- }}
171
- aria-label="trigger: focus"
172
- id="trigger_focus"
173
- />
174
- <Checkbox
175
- label="trigger: click"
176
- isChecked={trigger.includes('click')}
177
- onChange={checked => {
178
- let updatedTrigger;
179
- checked && (updatedTrigger = trigger.concat('click'));
180
- !checked && (updatedTrigger = trigger.filter(t => t !== 'click'));
181
- setIsVisible(false);
182
- setTimeout(() => setTrigger(updatedTrigger));
183
- }}
184
- aria-label="trigger: click"
185
- id="trigger_click"
186
- />
187
- <Checkbox
188
- label="trigger: manual"
189
- isChecked={trigger.includes('manual')}
190
- onChange={checked => {
191
- let updatedTrigger;
192
- checked && (updatedTrigger = trigger.concat('manual'));
193
- !checked && (updatedTrigger = trigger.filter(t => t !== 'manual'));
194
- setIsVisible(false);
195
- setTrigger(updatedTrigger);
196
- }}
197
- aria-label="trigger: manual"
198
- id="trigger_manual"
199
- />
200
- </div>
201
- <div style={{ border: '1px solid' }}>
202
- <Checkbox
203
- label="content left-aligned"
204
- isChecked={contentLeftAligned}
205
- onChange={checked => setContentLeftAligned(checked)}
206
- aria-label="content left-aligned"
207
- id="content_left_aligned"
208
- />
209
- </div>
210
- <div style={{ border: '1px solid' }}>
211
- <Checkbox
212
- label="enableFlip"
213
- isChecked={enableFlip}
214
- onChange={checked => setEnableFlip(checked)}
215
- aria-label="enableFlip"
216
- id="enable_flip"
217
- />
218
- </div>
219
- <div style={{ border: '1px solid' }}>
220
- position (will flip if enableFlip is true). The 'auto' position requires enableFlip to be set to true.
221
- <Select
222
- onToggle={() => setPositionSelectOpen(!positionSelectOpen)}
223
- onSelect={(event, selection) => {
224
- setPosition(selection);
225
- setPositionSelectOpen(false);
226
- }}
227
- isOpen={positionSelectOpen}
228
- selections={position}
229
- menuAppendTo={() => document.body}
230
- >
231
- <SelectOption value="auto" />
232
- <SelectOption value="top" />
233
- <SelectOption value="bottom" />
234
- <SelectOption value="left" />
235
- <SelectOption value="right" />
236
- <SelectOption value="top-start" />
237
- <SelectOption value="top-end" />
238
- <SelectOption value="bottom-start" />
239
- <SelectOption value="bottom-end" />
240
- <SelectOption value="left-start" />
241
- <SelectOption value="left-end" />
242
- <SelectOption value="right-start" />
243
- <SelectOption value="right-end" />
244
- </Select>
245
- </div>
246
- <div style={{ border: '1px solid' }}>
247
- <Checkbox
248
- label="isVisible (also set trigger to only manual to programmatically control it)"
249
- isChecked={isVisible}
250
- onChange={checked => setIsVisible(checked)}
251
- aria-label="isVisible"
252
- id="is_visible"
253
- />
254
- </div>
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
- />
276
- </div>
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'.
281
- <Select
282
- onToggle={() => setFlipSelectOpen(!flipSelectOpen)}
283
- onSelect={(event, selection) => {
284
- console.log(selection);
285
- setFlipBehavior(selection);
286
- setFlipSelectOpen(false);
287
- }}
288
- isOpen={flipSelectOpen}
289
- selections={flipBehavior}
290
- menuAppendTo={() => document.body}
291
- >
292
- <SelectOption value="flip" />
293
- <SelectOption value="clockwise">['top', 'right', 'bottom', 'left', 'top', 'right', 'bottom']</SelectOption>
294
- </Select>
295
- </div>
296
- </div>
297
- <div id="tooltip-boundary" className="tooltip-box" ref={tipBoxRef}>
298
- <Tooltip
299
- content={
300
- <div>
301
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.
302
- </div>
303
- }
304
- trigger={trigger.join(' ')}
305
- enableFlip={enableFlip}
306
- flipBehavior={flipBehavior === 'flip' ? 'flip' : ['top', 'right', 'bottom', 'left', 'top', 'right', 'bottom']}
307
- position={position}
308
- isVisible={isVisible}
309
- entryDelay={entryDelayInput}
310
- exitDelay={exitDelayInput}
311
- animationDuration={animationDuration}
312
- isContentLeftAligned={contentLeftAligned}
313
- appendTo={() => document.getElementById('tooltip-boundary')}
314
- >
315
- <Button className="tooltip-button">Tooltip</Button>
316
- </Tooltip>
317
- </div>
318
- </>
319
- );
320
- };
40
+ ```ts file="./TooltipOptions.tsx"
321
41
  ```
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { Button, Tooltip } from '@patternfly/react-core';
3
+
4
+ export const TooltipBasic: React.FunctionComponent = () => (
5
+ <div style={{ margin: '100px' }}>
6
+ <Tooltip
7
+ content={
8
+ <div>
9
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis.
10
+ </div>
11
+ }
12
+ >
13
+ <Button>I have a tooltip!</Button>
14
+ </Tooltip>
15
+ </div>
16
+ );
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Tooltip, Button } from '@patternfly/react-core';
3
+ import CopyIcon from '@patternfly/react-icons/dist/esm/icons/copy-icon';
4
+
5
+ export const TooltipIcon: React.FunctionComponent = () => {
6
+ const [showSuccessContent, setShowSuccessContent] = React.useState(false);
7
+ const copyText: string = 'Copy to clipboard';
8
+ const doneCopyText: string = 'Successfully copied to clipboard!';
9
+
10
+ return (
11
+ <div style={{ margin: '100px' }}>
12
+ <Tooltip aria="none" aria-live="polite" content={showSuccessContent ? doneCopyText : copyText}>
13
+ <Button
14
+ aria-label="Clipboard"
15
+ variant="plain"
16
+ id="tt-ref"
17
+ onClick={() => setShowSuccessContent(!showSuccessContent)}
18
+ >
19
+ <CopyIcon />
20
+ </Button>
21
+ </Tooltip>
22
+ </div>
23
+ );
24
+ };