@patternfly/react-core 6.3.1-prerelease.3 → 6.3.1-prerelease.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.
Files changed (127) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/AboutModal/package.json +1 -1
  5. package/dist/dynamic/components/Accordion/package.json +1 -1
  6. package/dist/dynamic/components/ActionList/package.json +1 -1
  7. package/dist/dynamic/components/Alert/package.json +1 -1
  8. package/dist/dynamic/components/Avatar/package.json +1 -1
  9. package/dist/dynamic/components/BackToTop/package.json +1 -1
  10. package/dist/dynamic/components/Backdrop/package.json +1 -1
  11. package/dist/dynamic/components/BackgroundImage/package.json +1 -1
  12. package/dist/dynamic/components/Badge/package.json +1 -1
  13. package/dist/dynamic/components/Banner/package.json +1 -1
  14. package/dist/dynamic/components/Brand/package.json +1 -1
  15. package/dist/dynamic/components/Breadcrumb/package.json +1 -1
  16. package/dist/dynamic/components/Button/package.json +1 -1
  17. package/dist/dynamic/components/CalendarMonth/package.json +1 -1
  18. package/dist/dynamic/components/Card/package.json +1 -1
  19. package/dist/dynamic/components/Checkbox/package.json +1 -1
  20. package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
  21. package/dist/dynamic/components/CodeBlock/package.json +1 -1
  22. package/dist/dynamic/components/Content/package.json +1 -1
  23. package/dist/dynamic/components/DataList/package.json +1 -1
  24. package/dist/dynamic/components/DatePicker/package.json +1 -1
  25. package/dist/dynamic/components/DescriptionList/package.json +1 -1
  26. package/dist/dynamic/components/Divider/package.json +1 -1
  27. package/dist/dynamic/components/Drawer/package.json +1 -1
  28. package/dist/dynamic/components/Dropdown/package.json +1 -1
  29. package/dist/dynamic/components/DualListSelector/package.json +1 -1
  30. package/dist/dynamic/components/EmptyState/package.json +1 -1
  31. package/dist/dynamic/components/ExpandableSection/package.json +1 -1
  32. package/dist/dynamic/components/FileUpload/package.json +1 -1
  33. package/dist/dynamic/components/Form/package.json +1 -1
  34. package/dist/dynamic/components/FormSelect/package.json +1 -1
  35. package/dist/dynamic/components/HelperText/package.json +1 -1
  36. package/dist/dynamic/components/Hint/package.json +1 -1
  37. package/dist/dynamic/components/Icon/package.json +1 -1
  38. package/dist/dynamic/components/InputGroup/package.json +1 -1
  39. package/dist/dynamic/components/JumpLinks/package.json +1 -1
  40. package/dist/dynamic/components/Label/package.json +1 -1
  41. package/dist/dynamic/components/List/package.json +1 -1
  42. package/dist/dynamic/components/LoginPage/package.json +1 -1
  43. package/dist/dynamic/components/Masthead/package.json +1 -1
  44. package/dist/dynamic/components/Menu/package.json +1 -1
  45. package/dist/dynamic/components/MenuToggle/package.json +1 -1
  46. package/dist/dynamic/components/Modal/package.json +1 -1
  47. package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
  48. package/dist/dynamic/components/Nav/package.json +1 -1
  49. package/dist/dynamic/components/NotificationBadge/package.json +1 -1
  50. package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
  51. package/dist/dynamic/components/NumberInput/package.json +1 -1
  52. package/dist/dynamic/components/OverflowMenu/package.json +1 -1
  53. package/dist/dynamic/components/Page/package.json +1 -1
  54. package/dist/dynamic/components/Pagination/package.json +1 -1
  55. package/dist/dynamic/components/Panel/package.json +1 -1
  56. package/dist/dynamic/components/Popover/package.json +1 -1
  57. package/dist/dynamic/components/Progress/package.json +1 -1
  58. package/dist/dynamic/components/ProgressStepper/package.json +1 -1
  59. package/dist/dynamic/components/Radio/package.json +1 -1
  60. package/dist/dynamic/components/SearchInput/package.json +1 -1
  61. package/dist/dynamic/components/Select/package.json +1 -1
  62. package/dist/dynamic/components/Sidebar/package.json +1 -1
  63. package/dist/dynamic/components/SimpleList/package.json +1 -1
  64. package/dist/dynamic/components/Skeleton/package.json +1 -1
  65. package/dist/dynamic/components/SkipToContent/package.json +1 -1
  66. package/dist/dynamic/components/Slider/package.json +1 -1
  67. package/dist/dynamic/components/Spinner/package.json +1 -1
  68. package/dist/dynamic/components/Switch/package.json +1 -1
  69. package/dist/dynamic/components/Tabs/package.json +1 -1
  70. package/dist/dynamic/components/TextArea/package.json +1 -1
  71. package/dist/dynamic/components/TextInput/package.json +1 -1
  72. package/dist/dynamic/components/TextInputGroup/package.json +1 -1
  73. package/dist/dynamic/components/TimePicker/package.json +1 -1
  74. package/dist/dynamic/components/Timestamp/package.json +1 -1
  75. package/dist/dynamic/components/Title/package.json +1 -1
  76. package/dist/dynamic/components/ToggleGroup/package.json +1 -1
  77. package/dist/dynamic/components/Toolbar/package.json +1 -1
  78. package/dist/dynamic/components/Tooltip/package.json +1 -1
  79. package/dist/dynamic/components/TreeView/package.json +1 -1
  80. package/dist/dynamic/components/Truncate/package.json +1 -1
  81. package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
  82. package/dist/dynamic/components/Wizard/package.json +1 -1
  83. package/dist/dynamic/deprecated/components/Chip/package.json +1 -1
  84. package/dist/dynamic/deprecated/components/DragDrop/package.json +1 -1
  85. package/dist/dynamic/deprecated/components/DualListSelector/package.json +1 -1
  86. package/dist/dynamic/deprecated/components/Modal/package.json +1 -1
  87. package/dist/dynamic/deprecated/components/Tile/package.json +1 -1
  88. package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
  89. package/dist/dynamic/deprecated/components/package.json +1 -1
  90. package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
  91. package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
  92. package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
  93. package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
  94. package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
  95. package/dist/dynamic/helpers/constants/package.json +1 -1
  96. package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
  97. package/dist/dynamic/helpers/fileUtils/package.json +1 -1
  98. package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
  99. package/dist/dynamic/helpers/package.json +1 -1
  100. package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
  101. package/dist/dynamic/helpers/typeUtils/package.json +1 -1
  102. package/dist/dynamic/helpers/useInterval/package.json +1 -1
  103. package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
  104. package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
  105. package/dist/dynamic/helpers/util/package.json +1 -1
  106. package/dist/dynamic/layouts/Bullseye/package.json +1 -1
  107. package/dist/dynamic/layouts/Flex/package.json +1 -1
  108. package/dist/dynamic/layouts/Gallery/package.json +1 -1
  109. package/dist/dynamic/layouts/Grid/package.json +1 -1
  110. package/dist/dynamic/layouts/Level/package.json +1 -1
  111. package/dist/dynamic/layouts/Split/package.json +1 -1
  112. package/dist/dynamic/layouts/Stack/package.json +1 -1
  113. package/dist/dynamic/styles/package.json +1 -1
  114. package/dist/esm/components/Tooltip/Tooltip.d.ts.map +1 -1
  115. package/dist/esm/components/Tooltip/Tooltip.js +68 -3
  116. package/dist/esm/components/Tooltip/Tooltip.js.map +1 -1
  117. package/dist/js/components/Tooltip/Tooltip.d.ts.map +1 -1
  118. package/dist/js/components/Tooltip/Tooltip.js +68 -3
  119. package/dist/js/components/Tooltip/Tooltip.js.map +1 -1
  120. package/dist/umd/assets/{output-CtvIYag_.css → output-V7wLdO7O.css} +19604 -19604
  121. package/dist/umd/react-core.min.js +1 -1
  122. package/helpers/package.json +1 -1
  123. package/layouts/package.json +1 -1
  124. package/next/package.json +1 -1
  125. package/package.json +2 -2
  126. package/src/components/Tooltip/Tooltip.tsx +76 -3
  127. package/src/components/Tooltip/__tests__/Tooltip.test.tsx +126 -0
@@ -1 +1 @@
1
- {"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"6.3.1-prerelease.2","private":true}
1
+ {"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"6.3.1-prerelease.3","private":true}
@@ -1 +1 @@
1
- {"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"6.3.1-prerelease.2","private":true}
1
+ {"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"6.3.1-prerelease.3","private":true}
package/next/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"6.3.1-prerelease.2","private":true}
1
+ {"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"6.3.1-prerelease.3","private":true}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "6.3.1-prerelease.3",
3
+ "version": "6.3.1-prerelease.4",
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",
@@ -63,5 +63,5 @@
63
63
  "react": "^17 || ^18 || ^19",
64
64
  "react-dom": "^17 || ^18 || ^19"
65
65
  },
66
- "gitHead": "18c9c578856041efeb380437b915e3fd51c9c2df"
66
+ "gitHead": "f0bf2bc5afde17af6fcee4e790d76f484c5bb4e5"
67
67
  }
@@ -174,6 +174,75 @@ export const Tooltip: React.FunctionComponent<TooltipProps> = ({
174
174
  const [visible, setVisible] = useState(false);
175
175
  const popperRef = createRef<HTMLDivElement>();
176
176
 
177
+ const getTriggerRefElement = (): HTMLElement | null => {
178
+ if (typeof triggerRef === 'function') {
179
+ return triggerRef();
180
+ } else if (triggerRef && typeof triggerRef === 'object' && 'current' in triggerRef) {
181
+ return triggerRef.current;
182
+ } else if (triggerRef instanceof HTMLElement) {
183
+ return triggerRef;
184
+ }
185
+ return null;
186
+ };
187
+
188
+ const getAriaAttributeName = () => (aria !== 'none' ? `aria-${aria}` : null);
189
+
190
+ const addAriaToRefElement = (element: HTMLElement): void => {
191
+ const attributeName = getAriaAttributeName();
192
+ if (!element || !attributeName) {
193
+ return;
194
+ }
195
+
196
+ const existingAria = element.getAttribute(attributeName);
197
+ if (!existingAria || !existingAria.includes(id)) {
198
+ const newAria = existingAria ? `${existingAria} ${id}` : id;
199
+ element.setAttribute(attributeName, newAria);
200
+ }
201
+ };
202
+
203
+ const removeAriaFromRefElement = (element: HTMLElement): void => {
204
+ const attributeName = getAriaAttributeName();
205
+ if (!element || !attributeName) {
206
+ return;
207
+ }
208
+
209
+ const existingAria = element.getAttribute(attributeName);
210
+ if (!existingAria) {
211
+ return;
212
+ }
213
+ const newAria = existingAria.replace(new RegExp(`\\b${id}\\b`, 'g'), '').trim();
214
+ if (newAria) {
215
+ element.setAttribute(attributeName, newAria);
216
+ } else {
217
+ element.removeAttribute(attributeName);
218
+ }
219
+ };
220
+
221
+ const updateTriggerElementAria = (shouldAddAria: boolean): void => {
222
+ if (aria === 'none' || !triggerRef || children) {
223
+ return;
224
+ }
225
+
226
+ const triggerElement = getTriggerRefElement();
227
+ if (!triggerElement) {
228
+ return;
229
+ }
230
+
231
+ if (shouldAddAria) {
232
+ addAriaToRefElement(triggerElement);
233
+ } else {
234
+ removeAriaFromRefElement(triggerElement);
235
+ }
236
+ };
237
+
238
+ useEffect(() => {
239
+ updateTriggerElementAria(visible);
240
+
241
+ return () => {
242
+ updateTriggerElementAria(false);
243
+ };
244
+ }, [visible, aria, triggerRef, children, id]);
245
+
177
246
  const onDocumentKeyDown = (event: KeyboardEvent) => {
178
247
  if (!triggerManually) {
179
248
  if (event.key === KeyTypes.Escape && visible) {
@@ -258,8 +327,12 @@ export const Tooltip: React.FunctionComponent<TooltipProps> = ({
258
327
  }
259
328
  };
260
329
 
261
- const addAriaToTrigger = () => {
262
- if (aria === 'describedby' && children && children.props && !children.props['aria-describedby']) {
330
+ const addAriaToChildren = () => {
331
+ if (!children) {
332
+ return;
333
+ }
334
+
335
+ if (aria === 'describedby' && children.props && !children.props['aria-describedby']) {
263
336
  return cloneElement(children, { 'aria-describedby': id });
264
337
  } else if (aria === 'labelledby' && children.props && !children.props['aria-labelledby']) {
265
338
  return cloneElement(children, { 'aria-labelledby': id });
@@ -269,7 +342,7 @@ export const Tooltip: React.FunctionComponent<TooltipProps> = ({
269
342
 
270
343
  return (
271
344
  <Popper
272
- trigger={aria !== 'none' && visible ? addAriaToTrigger() : children}
345
+ trigger={aria !== 'none' && visible ? addAriaToChildren() : children}
273
346
  triggerRef={triggerRef}
274
347
  popper={content}
275
348
  popperRef={popperRef}
@@ -204,3 +204,129 @@ test('Matches snapshot', async () => {
204
204
  const tooltip = await screen.findByRole('tooltip');
205
205
  expect(tooltip).toMatchSnapshot();
206
206
  });
207
+
208
+ test('Applies aria-describedby to triggerRef element when no children are provided', async () => {
209
+ const triggerRef = createRef<HTMLButtonElement>();
210
+
211
+ render(
212
+ <>
213
+ <button ref={triggerRef}>Trigger</button>
214
+ <Tooltip id="trigger-ref-test" triggerRef={triggerRef} isVisible content="Test description" />
215
+ </>
216
+ );
217
+
218
+ await screen.findByRole('tooltip');
219
+ expect(triggerRef.current).toHaveAccessibleDescription('Test description');
220
+ });
221
+
222
+ test('Applies aria-labelledby to triggerRef element when no children are provided', async () => {
223
+ const triggerRef = createRef<HTMLButtonElement>();
224
+
225
+ render(
226
+ <>
227
+ <button ref={triggerRef}>Trigger</button>
228
+ <Tooltip id="trigger-ref-test" aria="labelledby" triggerRef={triggerRef} isVisible content="Test label" />
229
+ </>
230
+ );
231
+
232
+ await screen.findByRole('tooltip');
233
+ expect(triggerRef.current).toHaveAccessibleName('Test label');
234
+ });
235
+
236
+ test('Removes aria-describedby from triggerRef element when tooltip is hidden', async () => {
237
+ const triggerRef = createRef<HTMLButtonElement>();
238
+
239
+ const TooltipTest = () => {
240
+ const [isVisible, setIsVisible] = useState(true);
241
+
242
+ return (
243
+ <>
244
+ <button ref={triggerRef} onClick={() => setIsVisible(!isVisible)}>
245
+ Trigger
246
+ </button>
247
+ <Tooltip id="trigger-ref-test" triggerRef={triggerRef} isVisible={isVisible} content="Test description" />
248
+ </>
249
+ );
250
+ };
251
+
252
+ render(<TooltipTest />);
253
+
254
+ // Tooltip should be visible initially
255
+ await screen.findByRole('tooltip');
256
+ expect(triggerRef.current).toHaveAccessibleDescription('Test description');
257
+
258
+ // Hide tooltip
259
+ const user = userEvent.setup();
260
+ await user.click(triggerRef.current);
261
+
262
+ // aria-describedby should be removed
263
+ expect(triggerRef.current).not.toHaveAccessibleDescription();
264
+ });
265
+
266
+ test('Removes aria-labelledby from triggerRef element when tooltip is hidden', async () => {
267
+ const triggerRef = createRef<HTMLButtonElement>();
268
+
269
+ const TooltipTest = () => {
270
+ const [isVisible, setIsVisible] = useState(true);
271
+
272
+ return (
273
+ <>
274
+ <button ref={triggerRef} onClick={() => setIsVisible(!isVisible)} />
275
+ <Tooltip
276
+ aria="labelledby"
277
+ id="trigger-ref-test"
278
+ triggerRef={triggerRef}
279
+ isVisible={isVisible}
280
+ content="Test label"
281
+ />
282
+ </>
283
+ );
284
+ };
285
+
286
+ render(<TooltipTest />);
287
+
288
+ // Tooltip should be visible initially
289
+ await screen.findByRole('tooltip');
290
+ expect(triggerRef.current).toHaveAccessibleName('Test label');
291
+
292
+ // Hide tooltip
293
+ const user = userEvent.setup();
294
+ await user.click(triggerRef.current);
295
+
296
+ // aria-describedby should be removed
297
+ expect(triggerRef.current).not.toHaveAccessibleName();
298
+ });
299
+
300
+ test('Preserves existing aria-describedby on triggerRef element', async () => {
301
+ const triggerRef = createRef<HTMLButtonElement>();
302
+
303
+ render(
304
+ <>
305
+ <div id="existing-aria">Existing description</div>
306
+ <button ref={triggerRef} aria-describedby="existing-aria">
307
+ Trigger
308
+ </button>
309
+ <Tooltip id="trigger-ref-test" triggerRef={triggerRef} isVisible content="Test description" />
310
+ </>
311
+ );
312
+
313
+ await screen.findByRole('tooltip');
314
+ expect(triggerRef.current).toHaveAccessibleDescription('Existing description Test description');
315
+ });
316
+
317
+ test('Preserves existing aria-labelledby on triggerRef element', async () => {
318
+ const triggerRef = createRef<HTMLButtonElement>();
319
+
320
+ render(
321
+ <>
322
+ <div id="existing-aria">Existing label</div>
323
+ <button ref={triggerRef} aria-labelledby="existing-aria">
324
+ Trigger
325
+ </button>
326
+ <Tooltip aria="labelledby" id="trigger-ref-test" triggerRef={triggerRef} isVisible content="Test label" />
327
+ </>
328
+ );
329
+
330
+ await screen.findByRole('tooltip');
331
+ expect(triggerRef.current).toHaveAccessibleName('Existing label Test label');
332
+ });