@patternfly/react-core 6.5.0-prerelease.24 → 6.5.0-prerelease.26

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 (164) hide show
  1. package/CHANGELOG.md +12 -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/Compass/package.json +1 -1
  23. package/dist/dynamic/components/Content/package.json +1 -1
  24. package/dist/dynamic/components/DataList/package.json +1 -1
  25. package/dist/dynamic/components/DatePicker/package.json +1 -1
  26. package/dist/dynamic/components/DescriptionList/package.json +1 -1
  27. package/dist/dynamic/components/Divider/package.json +1 -1
  28. package/dist/dynamic/components/Drawer/package.json +1 -1
  29. package/dist/dynamic/components/Dropdown/package.json +1 -1
  30. package/dist/dynamic/components/DualListSelector/package.json +1 -1
  31. package/dist/dynamic/components/EmptyState/package.json +1 -1
  32. package/dist/dynamic/components/ExpandableSection/package.json +1 -1
  33. package/dist/dynamic/components/FileUpload/package.json +1 -1
  34. package/dist/dynamic/components/Form/package.json +1 -1
  35. package/dist/dynamic/components/FormSelect/package.json +1 -1
  36. package/dist/dynamic/components/HelperText/package.json +1 -1
  37. package/dist/dynamic/components/Hero/package.json +1 -1
  38. package/dist/dynamic/components/Hint/package.json +1 -1
  39. package/dist/dynamic/components/Icon/package.json +1 -1
  40. package/dist/dynamic/components/InputGroup/package.json +1 -1
  41. package/dist/dynamic/components/JumpLinks/package.json +1 -1
  42. package/dist/dynamic/components/Label/package.json +1 -1
  43. package/dist/dynamic/components/List/package.json +1 -1
  44. package/dist/dynamic/components/LoginPage/package.json +1 -1
  45. package/dist/dynamic/components/Masthead/package.json +1 -1
  46. package/dist/dynamic/components/Menu/package.json +1 -1
  47. package/dist/dynamic/components/MenuToggle/package.json +1 -1
  48. package/dist/dynamic/components/Modal/package.json +1 -1
  49. package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
  50. package/dist/dynamic/components/Nav/package.json +1 -1
  51. package/dist/dynamic/components/NotificationBadge/package.json +1 -1
  52. package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
  53. package/dist/dynamic/components/NumberInput/package.json +1 -1
  54. package/dist/dynamic/components/OverflowMenu/package.json +1 -1
  55. package/dist/dynamic/components/Page/package.json +1 -1
  56. package/dist/dynamic/components/Pagination/package.json +1 -1
  57. package/dist/dynamic/components/Panel/package.json +1 -1
  58. package/dist/dynamic/components/Popover/package.json +1 -1
  59. package/dist/dynamic/components/Progress/package.json +1 -1
  60. package/dist/dynamic/components/ProgressStepper/package.json +1 -1
  61. package/dist/dynamic/components/Radio/package.json +1 -1
  62. package/dist/dynamic/components/SearchInput/package.json +1 -1
  63. package/dist/dynamic/components/Select/package.json +1 -1
  64. package/dist/dynamic/components/Sidebar/package.json +1 -1
  65. package/dist/dynamic/components/SimpleList/package.json +1 -1
  66. package/dist/dynamic/components/Skeleton/package.json +1 -1
  67. package/dist/dynamic/components/SkipToContent/package.json +1 -1
  68. package/dist/dynamic/components/Slider/package.json +1 -1
  69. package/dist/dynamic/components/Spinner/package.json +1 -1
  70. package/dist/dynamic/components/Switch/package.json +1 -1
  71. package/dist/dynamic/components/Tabs/package.json +1 -1
  72. package/dist/dynamic/components/TextArea/package.json +1 -1
  73. package/dist/dynamic/components/TextInput/package.json +1 -1
  74. package/dist/dynamic/components/TextInputGroup/package.json +1 -1
  75. package/dist/dynamic/components/TimePicker/package.json +1 -1
  76. package/dist/dynamic/components/Timestamp/package.json +1 -1
  77. package/dist/dynamic/components/Title/package.json +1 -1
  78. package/dist/dynamic/components/ToggleGroup/package.json +1 -1
  79. package/dist/dynamic/components/Toolbar/package.json +1 -1
  80. package/dist/dynamic/components/Tooltip/package.json +1 -1
  81. package/dist/dynamic/components/TreeView/package.json +1 -1
  82. package/dist/dynamic/components/Truncate/package.json +1 -1
  83. package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
  84. package/dist/dynamic/components/Wizard/package.json +1 -1
  85. package/dist/dynamic/deprecated/components/Chip/package.json +1 -1
  86. package/dist/dynamic/deprecated/components/DragDrop/package.json +1 -1
  87. package/dist/dynamic/deprecated/components/DualListSelector/package.json +1 -1
  88. package/dist/dynamic/deprecated/components/Modal/package.json +1 -1
  89. package/dist/dynamic/deprecated/components/Tile/package.json +1 -1
  90. package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
  91. package/dist/dynamic/deprecated/components/package.json +1 -1
  92. package/dist/dynamic/helpers/AnimationsProvider/AnimationsProvider/package.json +1 -1
  93. package/dist/dynamic/helpers/AnimationsProvider/package.json +1 -1
  94. package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
  95. package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
  96. package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
  97. package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
  98. package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
  99. package/dist/dynamic/helpers/constants/package.json +1 -1
  100. package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
  101. package/dist/dynamic/helpers/fileUtils/package.json +1 -1
  102. package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
  103. package/dist/dynamic/helpers/package.json +1 -1
  104. package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
  105. package/dist/dynamic/helpers/typeUtils/package.json +1 -1
  106. package/dist/dynamic/helpers/useInterval/package.json +1 -1
  107. package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
  108. package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
  109. package/dist/dynamic/helpers/util/package.json +1 -1
  110. package/dist/dynamic/layouts/Bullseye/package.json +1 -1
  111. package/dist/dynamic/layouts/Flex/package.json +1 -1
  112. package/dist/dynamic/layouts/Gallery/package.json +1 -1
  113. package/dist/dynamic/layouts/Grid/package.json +1 -1
  114. package/dist/dynamic/layouts/Level/package.json +1 -1
  115. package/dist/dynamic/layouts/Split/package.json +1 -1
  116. package/dist/dynamic/layouts/Stack/package.json +1 -1
  117. package/dist/dynamic/styles/package.json +1 -1
  118. package/dist/esm/components/ClipboardCopy/ClipboardCopy.d.ts +8 -0
  119. package/dist/esm/components/ClipboardCopy/ClipboardCopy.d.ts.map +1 -1
  120. package/dist/esm/components/ClipboardCopy/ClipboardCopy.js +4 -2
  121. package/dist/esm/components/ClipboardCopy/ClipboardCopy.js.map +1 -1
  122. package/dist/esm/components/Label/Label.js +1 -1
  123. package/dist/esm/components/Label/Label.js.map +1 -1
  124. package/dist/js/components/ClipboardCopy/ClipboardCopy.d.ts +8 -0
  125. package/dist/js/components/ClipboardCopy/ClipboardCopy.d.ts.map +1 -1
  126. package/dist/js/components/ClipboardCopy/ClipboardCopy.js +4 -2
  127. package/dist/js/components/ClipboardCopy/ClipboardCopy.js.map +1 -1
  128. package/dist/js/components/Label/Label.js +1 -1
  129. package/dist/js/components/Label/Label.js.map +1 -1
  130. package/dist/umd/assets/{output-BbsSnXfK.css → output-BOKd1GXO.css} +18528 -18528
  131. package/dist/umd/react-core.min.js +2 -2
  132. package/helpers/package.json +1 -1
  133. package/layouts/package.json +1 -1
  134. package/next/package.json +1 -1
  135. package/package.json +2 -2
  136. package/src/components/ClipboardCopy/ClipboardCopy.tsx +16 -1
  137. package/src/components/ClipboardCopy/__tests__/ClipboardCopy.test.tsx +72 -0
  138. package/src/components/ClipboardCopy/__tests__/__snapshots__/ClipboardCopy.test.tsx.snap +1 -1
  139. package/src/components/Dropdown/examples/Dropdown.md +13 -1
  140. package/src/components/Dropdown/examples/DropdownWithSplit.tsx +97 -0
  141. package/src/components/Label/Label.tsx +1 -1
  142. package/src/demos/Banner.md +2 -139
  143. package/src/demos/DateTimePicker.md +2 -86
  144. package/src/demos/JumpLinks.md +2 -129
  145. package/src/demos/ProgressDemo.md +2 -65
  146. package/src/demos/ProgressStepperDemo.md +1 -72
  147. package/src/demos/Tabs.md +6 -417
  148. package/src/demos/examples/Banner/BannerBasicSticky.tsx +55 -0
  149. package/src/demos/examples/Banner/BannerTopBottom.tsx +81 -0
  150. package/src/demos/examples/DateTimePicker/DateTimeRangePicker.tsx +93 -0
  151. package/src/demos/examples/JumpLinks/JumpLinksScrollspy.tsx +125 -0
  152. package/src/demos/examples/JumpLinks/{JumpLinksWithDrawer.js → JumpLinksWithDrawer.tsx} +1 -1
  153. package/src/demos/examples/Progress/ProgressBasic.tsx +32 -0
  154. package/src/demos/examples/Progress/ProgressWithOnlyIncreasing.tsx +33 -0
  155. package/src/demos/examples/ProgressStepper/ProgressStepperBasic.tsx +72 -0
  156. package/src/demos/examples/Tabs/TabsOpen.tsx +185 -0
  157. package/src/demos/examples/Tabs/TabsOpenWithSecondaryTabs.tsx +228 -0
  158. package/src/layouts/Gallery/examples/Gallery.md +8 -99
  159. package/src/layouts/Gallery/examples/GalleryAdjustingMaxWidths.tsx +21 -0
  160. package/src/layouts/Gallery/examples/GalleryAdjustingMinMaxWidths.tsx +25 -0
  161. package/src/layouts/Gallery/examples/GalleryAdjustingMinWidths.tsx +22 -0
  162. package/src/layouts/Gallery/examples/GalleryAlternativeComponents.tsx +11 -0
  163. package/src/layouts/Gallery/examples/GalleryBasic.tsx +14 -0
  164. package/src/layouts/Gallery/examples/GalleryWithGutters.tsx +12 -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.5.0-prerelease.23","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.5.0-prerelease.25","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.5.0-prerelease.23","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.5.0-prerelease.25","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.5.0-prerelease.23","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.5.0-prerelease.25","private":true}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "6.5.0-prerelease.24",
3
+ "version": "6.5.0-prerelease.26",
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": "a5726d0a999e6397b5df4e339b03c01efdb0f070"
66
+ "gitHead": "296178f84f2073ea2034858f812ab6d5dd03f3f0"
67
67
  }
@@ -55,6 +55,10 @@ export interface ClipboardCopyProps extends Omit<React.HTMLProps<HTMLDivElement>
55
55
  textAriaLabel?: string;
56
56
  /** Aria-label to use on the ClipboardCopyToggle. */
57
57
  toggleAriaLabel?: string;
58
+ /** ID to use on the TextInput. */
59
+ inputId?: string;
60
+ /** Name attribute to use on the TextInput. */
61
+ inputName?: string;
58
62
  /** Flag to show if the input is read only. */
59
63
  isReadOnly?: boolean;
60
64
  /** Flag to determine if clipboard copy is in the expanded state initially */
@@ -91,6 +95,10 @@ export interface ClipboardCopyProps extends Omit<React.HTMLProps<HTMLDivElement>
91
95
  onCopy?: (event: React.ClipboardEvent<HTMLDivElement>, text?: React.ReactNode) => void;
92
96
  /** A function that is triggered on changing the text. */
93
97
  onChange?: (event: React.FormEvent, text?: string) => void;
98
+ /** Callback function when text input is focused */
99
+ onInputFocus?: (event?: any) => void;
100
+ /** Callback function when text input is blurred (focus leaves) */
101
+ onInputBlur?: (event?: any) => void;
94
102
  /** The text which is copied. */
95
103
  children: string | string[];
96
104
  /** Additional actions for inline clipboard copy. Should be wrapped with ClipboardCopyAction. */
@@ -177,6 +185,8 @@ class ClipboardCopy extends Component<ClipboardCopyProps, ClipboardCopyState> {
177
185
  /* eslint-disable @typescript-eslint/no-unused-vars */
178
186
  isExpanded,
179
187
  onChange, // Don't pass to <div>
188
+ onInputFocus, // Don't pass to <div>
189
+ onInputBlur, // Don't pass to <div>
180
190
  /* eslint-enable @typescript-eslint/no-unused-vars */
181
191
  isReadOnly,
182
192
  isCode,
@@ -189,6 +199,8 @@ class ClipboardCopy extends Component<ClipboardCopyProps, ClipboardCopyState> {
189
199
  clickTip,
190
200
  textAriaLabel,
191
201
  toggleAriaLabel,
202
+ inputId,
203
+ inputName,
192
204
  variant,
193
205
  position,
194
206
  className,
@@ -295,8 +307,11 @@ class ClipboardCopy extends Component<ClipboardCopyProps, ClipboardCopyState> {
295
307
  readOnlyVariant={isReadOnly || this.state.expanded ? 'default' : undefined}
296
308
  onChange={this.updateText}
297
309
  value={this.state.expanded ? this.state.textWhenExpanded : copyableText}
298
- id={`text-input-${id}`}
310
+ id={inputId ?? `text-input-${id}`}
311
+ name={inputName}
299
312
  aria-label={textAriaLabel}
313
+ onFocus={onInputFocus}
314
+ onBlur={onInputBlur}
300
315
  {...(isCode && { dir: 'ltr' })}
301
316
  />
302
317
  <ClipboardCopyButton
@@ -309,6 +309,18 @@ test('Passes textAriaLabel to TextInput', () => {
309
309
  expect(screen.getByRole('textbox')).toHaveAccessibleName('text label');
310
310
  });
311
311
 
312
+ test('Passes inputId to TextInput', () => {
313
+ render(<ClipboardCopy inputId="custom-input-id">{children}</ClipboardCopy>);
314
+
315
+ expect(screen.getByRole('textbox')).toHaveAttribute('id', 'custom-input-id');
316
+ });
317
+
318
+ test('Passes inputName to TextInput', () => {
319
+ render(<ClipboardCopy inputName="custom-input-name">{children}</ClipboardCopy>);
320
+
321
+ expect(screen.getByRole('textbox')).toHaveAttribute('name', 'custom-input-name');
322
+ });
323
+
312
324
  test('Calls onChange when ClipboardCopy textinput is typed in', async () => {
313
325
  const onChangeMock = jest.fn();
314
326
  const user = userEvent.setup();
@@ -338,6 +350,66 @@ test('Does not call onChange when ClipboardCopy textinput is not typed in', asyn
338
350
  expect(onChangeMock).not.toHaveBeenCalled();
339
351
  });
340
352
 
353
+ test('Calls onFocus when ClipboardCopy textinput is focused', async () => {
354
+ const onFocusMock = jest.fn();
355
+ const user = userEvent.setup();
356
+
357
+ render(<ClipboardCopy onInputFocus={onFocusMock}>{children}</ClipboardCopy>);
358
+
359
+ await user.click(screen.getByRole('textbox'));
360
+
361
+ expect(onFocusMock).toHaveBeenCalledTimes(1);
362
+ });
363
+
364
+ test('Does not call onFocus when ClipboardCopy textinput is not focused', async () => {
365
+ const onFocusMock = jest.fn();
366
+ const user = userEvent.setup();
367
+
368
+ render(
369
+ <>
370
+ <ClipboardCopy onInputFocus={onFocusMock}>{children}</ClipboardCopy>
371
+ <input aria-label="native input" />
372
+ </>
373
+ );
374
+
375
+ await user.click(screen.getByRole('textbox', { name: 'native input' }));
376
+
377
+ expect(onFocusMock).not.toHaveBeenCalled();
378
+ });
379
+
380
+ test('Calls onBlur when ClipboardCopy textinput loses focus', async () => {
381
+ const onBlurMock = jest.fn();
382
+ const user = userEvent.setup();
383
+
384
+ render(
385
+ <>
386
+ <ClipboardCopy onInputBlur={onBlurMock}>{children}</ClipboardCopy>
387
+ <input aria-label="native input" />
388
+ </>
389
+ );
390
+
391
+ await user.click(screen.getByRole('textbox', { name: 'Copyable input' }));
392
+ await user.click(screen.getByRole('textbox', { name: 'native input' }));
393
+
394
+ expect(onBlurMock).toHaveBeenCalledTimes(1);
395
+ });
396
+
397
+ test('Does not call onBlur when ClipboardCopy textinput does not lose focus', async () => {
398
+ const onBlurMock = jest.fn();
399
+ const user = userEvent.setup();
400
+
401
+ render(
402
+ <>
403
+ <ClipboardCopy onInputBlur={onBlurMock}>{children}</ClipboardCopy>
404
+ <input aria-label="native input" />
405
+ </>
406
+ );
407
+
408
+ await user.click(screen.getByRole('textbox', { name: 'native input' }));
409
+
410
+ expect(onBlurMock).not.toHaveBeenCalled();
411
+ });
412
+
341
413
  test('Calls onCopy when ClipboardCopyButton is clicked', async () => {
342
414
  const onCopyMock = jest.fn();
343
415
  const user = userEvent.setup();
@@ -18,7 +18,7 @@ exports[`Matches snapshot 1`] = `
18
18
  <input
19
19
  aria-invalid="false"
20
20
  aria-label="Copyable input"
21
- data-ouia-component-id="OUIA-Generated-TextInputBase-36"
21
+ data-ouia-component-id="OUIA-Generated-TextInputBase-42"
22
22
  data-ouia-component-type="PF6/TextInput"
23
23
  data-ouia-safe="true"
24
24
  id="text-input-generated-id"
@@ -16,7 +16,7 @@ propComponents:
16
16
  ]
17
17
  ---
18
18
 
19
- import { useState } from 'react';
19
+ import { useState, useRef } from 'react';
20
20
  import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
21
21
 
22
22
  ## Examples
@@ -63,3 +63,15 @@ To provide users with more context about a `<DropdownItem>`, pass a short messag
63
63
  ```ts file="./DropdownWithDescriptions.tsx"
64
64
 
65
65
  ```
66
+
67
+ ### Split toggle with checkbox
68
+
69
+ To combine a checkbox or other control with a dropdown menu, use a split button.
70
+
71
+ A `<MenuToggle>` can be rendered as a split button via `splitButtonItems`. Elements to be displayed before the dropdown toggle button (like the `<MenuToggleCheckbox>`) must be included in the `splitButtonItems`.
72
+
73
+ If the dropdown menu closes upon selection, you will need to manually shift focus back to the toggle element after a user selects an item from the menu.
74
+
75
+ ```ts file="./DropdownWithSplit.tsx"
76
+
77
+ ```
@@ -0,0 +1,97 @@
1
+ import {
2
+ Dropdown,
3
+ MenuToggle,
4
+ MenuToggleCheckbox,
5
+ DropdownItem,
6
+ DropdownList,
7
+ Divider,
8
+ MenuToggleElement
9
+ } from '@patternfly/react-core';
10
+ import { useRef, useState } from 'react';
11
+
12
+ export const DropdownSplitButtonText: React.FunctionComponent = () => {
13
+ const [isOpen, setIsOpen] = useState(false);
14
+ const toggleRef = useRef<MenuToggleElement>(null);
15
+
16
+ const onFocus = () => {
17
+ if (!toggleRef.current) {
18
+ return;
19
+ }
20
+
21
+ const toggleButton = toggleRef.current.querySelector('button[aria-expanded]');
22
+ toggleButton?.focus();
23
+ };
24
+
25
+ const onSelect = () => {
26
+ setIsOpen(false);
27
+ onFocus();
28
+ };
29
+
30
+ const onToggleClick = () => {
31
+ setIsOpen(!isOpen);
32
+ };
33
+
34
+ return (
35
+ <Dropdown
36
+ onSelect={onSelect}
37
+ onOpenChange={(isOpen: boolean) => setIsOpen(isOpen)}
38
+ toggle={(toggleRefCallback: React.Ref<MenuToggleElement>) => (
39
+ <MenuToggle
40
+ ref={(node) => {
41
+ // Handle both callback ref and useRef
42
+ if (typeof toggleRefCallback === 'function') {
43
+ toggleRefCallback(node);
44
+ } else if (toggleRefCallback) {
45
+ (toggleRefCallback as React.MutableRefObject<MenuToggleElement | null>).current = node;
46
+ }
47
+ (toggleRef as React.MutableRefObject<MenuToggleElement | null>).current = node;
48
+ }}
49
+ splitButtonItems={[
50
+ <MenuToggleCheckbox id="split-button-checkbox-example" key="split-checkbox" aria-label="Select all" />
51
+ ]}
52
+ aria-label="Dropdown with checkbox split button"
53
+ onClick={onToggleClick}
54
+ isExpanded={isOpen}
55
+ />
56
+ )}
57
+ isOpen={isOpen}
58
+ >
59
+ <DropdownList>
60
+ <DropdownItem value={0} key="action">
61
+ Action
62
+ </DropdownItem>
63
+ <DropdownItem
64
+ value={1}
65
+ key="link"
66
+ to="#default-link2"
67
+ // Prevent the default onClick functionality for example purposes
68
+ onClick={(ev: any) => ev.preventDefault()}
69
+ >
70
+ Link
71
+ </DropdownItem>
72
+ <DropdownItem value={2} isDisabled key="disabled action">
73
+ Disabled Action
74
+ </DropdownItem>
75
+ <DropdownItem value={3} isDisabled key="disabled link" to="#default-link4">
76
+ Disabled Link
77
+ </DropdownItem>
78
+ <DropdownItem
79
+ value={4}
80
+ isAriaDisabled
81
+ key="aria-disabled link"
82
+ to="#default-link5"
83
+ tooltipProps={{ content: 'aria-disabled link', position: 'top' }}
84
+ >
85
+ Aria-disabled Link
86
+ </DropdownItem>
87
+ <Divider component="li" key="separator" />
88
+ <DropdownItem value={5} key="separated action">
89
+ Separated Action
90
+ </DropdownItem>
91
+ <DropdownItem value={6} key="separated link" to="#default-link6" onClick={(ev) => ev.preventDefault()}>
92
+ Separated Link
93
+ </DropdownItem>
94
+ </DropdownList>
95
+ </Dropdown>
96
+ );
97
+ };
@@ -338,7 +338,7 @@ export const Label: React.FunctionComponent<LabelProps> = ({
338
338
  );
339
339
  }
340
340
 
341
- const LabelComponent = (isOverflowLabel ? 'button' : 'span') as any;
341
+ const LabelComponent = (isOverflowLabel || isAddLabel ? 'button' : 'span') as any;
342
342
 
343
343
  return (
344
344
  <LabelComponent
@@ -11,148 +11,11 @@ import { DashboardWrapper } from '@patternfly/react-core/dist/js/demos/Dashboard
11
11
 
12
12
  ### Basic sticky banner
13
13
 
14
- ```js isFullscreen
15
- import { Fragment } from 'react';
16
- import { Banner, Card, CardBody, Flex, Gallery, GalleryItem, PageSection, Content } from '@patternfly/react-core';
17
-
18
- import { DashboardWrapper } from '@patternfly/react-core/dist/js/demos/DashboardWrapper';
19
- import { css } from '@patternfly/react-styles';
20
- import display from '@patternfly/react-styles/css/utilities/Display/display';
21
-
22
- class BannerDemo extends React.Component {
23
- render() {
24
- const banner = (
25
- <Banner isSticky>
26
- <Flex
27
- justifyContent={{ default: 'justifyContentCenter', lg: 'justifyContentSpaceBetween' }}
28
- flexWrap={{ default: 'nowrap' }}
29
- >
30
- <div className={css(display.displayNone, display.displayBlockOnLg)}>Localhost</div>
31
- <div className={css(display.displayNone, display.displayBlockOnLg)}>
32
- This message is sticky to the top of the page.
33
- </div>
34
- <div className={css(display.displayNoneOnLg)}>Drop some text on mobile, truncate if needed.</div>
35
- <div className={css(display.displayNone, display.displayBlockOnLg)}>Ned Username</div>
36
- </Flex>
37
- </Banner>
38
- );
39
- return (
40
- <Fragment>
41
- <DashboardWrapper banner={banner} breadcrumb={null}>
42
- <PageSection aria-labelledby="main-title">
43
- <Content>
44
- <h1 id="main-title">Main title</h1>
45
- <p>
46
- Body text should be Red Hat Text at 1rem(16px). It should have leading of 1.5rem(24px) because <br />
47
- of it’s relative line height of 1.5.
48
- </p>
49
- </Content>
50
- </PageSection>
51
- <PageSection aria-label='Cards gallery'>
52
- <Gallery hasGutter>
53
- {Array.from({ length: 30 }).map((_value, index) => (
54
- <GalleryItem key={index}>
55
- <Card key={index}>
56
- <CardBody>This is a card</CardBody>
57
- </Card>
58
- </GalleryItem>
59
- ))}
60
- </Gallery>
61
- </PageSection>
62
- </DashboardWrapper>
63
- </Fragment>
64
- );
65
- }
66
- }
14
+ ```ts file="examples/Banner/BannerBasicSticky.tsx" isFullscreen
67
15
  ```
68
16
 
69
17
  ### Top and bottom banner
70
18
 
71
- ```js isFullscreen
72
- import { Fragment } from 'react';
73
- import {
74
- Banner,
75
- Card,
76
- CardBody,
77
- Flex,
78
- FlexItem,
79
- Gallery,
80
- GalleryItem,
81
- PageSection,
82
- Content
83
- } from '@patternfly/react-core';
84
- import { DashboardWrapper } from '@patternfly/react-core/dist/js/demos/DashboardWrapper';
85
- import { css } from '@patternfly/react-styles';
86
- import display from '@patternfly/react-styles/css/utilities/Display/display';
19
+ ```ts file="examples/Banner/BannerTopBottom.tsx" isFullscreen
87
20
 
88
- class BannerDemo extends React.Component {
89
- render() {
90
- return (
91
- <Fragment>
92
- <Flex
93
- direction={{ default: 'column' }}
94
- flexWrap={{ default: 'nowrap' }}
95
- spaceItems={{ default: 'spaceItemsNone' }}
96
- style={{ height: '100%' }}
97
- >
98
- <FlexItem>
99
- <Banner isSticky>
100
- <Flex
101
- justifyContent={{ default: 'justifyContentCenter', lg: 'justifyContentSpaceBetween' }}
102
- flexWrap={{ default: 'nowrap' }}
103
- >
104
- <div className={css(display.displayNone, display.displayBlockOnLg)}>Localhost</div>
105
- <div className={css(display.displayNone, display.displayBlockOnLg)}>
106
- This message is sticky to the top of the page.
107
- </div>
108
- <div className={css(display.displayNoneOnLg)}>Drop some text on mobile, truncate if needed.</div>
109
- <div className={css(display.displayNone, display.displayBlockOnLg)}>Ned Username</div>
110
- </Flex>
111
- </Banner>
112
- </FlexItem>
113
- <FlexItem grow={{ default: 'grow' }} style={{ minHeight: 0 }}>
114
- <DashboardWrapper breadcrumb={null}>
115
- <PageSection aria-labelledby="main-title">
116
- <Content>
117
- <h1 id='main-title'>Main title</h1>
118
- <p>
119
- Body text should be Red Hat Text at 1rem(16px). It should have leading of 1.5rem(24px) because{' '}
120
- <br />
121
- of it’s relative line height of 1.5.
122
- </p>
123
- </Content>
124
- </PageSection>
125
- <PageSection aria-label='Cards gallery'>
126
- <Gallery hasGutter>
127
- {Array.from({ length: 30 }).map((_value, index) => (
128
- <GalleryItem key={index}>
129
- <Card key={index}>
130
- <CardBody>This is a card</CardBody>
131
- </Card>
132
- </GalleryItem>
133
- ))}
134
- </Gallery>
135
- </PageSection>
136
- </DashboardWrapper>
137
- </FlexItem>
138
- <FlexItem>
139
- <Banner isSticky>
140
- <Flex
141
- justifyContent={{ default: 'justifyContentCenter', lg: 'justifyContentSpaceBetween' }}
142
- flexWrap={{ default: 'nowrap' }}
143
- >
144
- <div className={css(display.displayNone, display.displayBlockOnLg)}>Localhost</div>
145
- <div className={css(display.displayNone, display.displayBlockOnLg)}>
146
- This message is sticky to the bottom of the page.
147
- </div>
148
- <div className={css(display.displayNoneOnLg)}>Drop some text on mobile, truncate if needed.</div>
149
- <div className={css(display.displayNone, display.displayBlockOnLg)}>Ned Username</div>
150
- </Flex>
151
- </Banner>
152
- </FlexItem>
153
- </Flex>
154
- </Fragment>
155
- );
156
- }
157
- }
158
21
  ```
@@ -14,96 +14,12 @@ In this demo, learn how to use a [CalendarMonth](/components/date-and-time/calen
14
14
 
15
15
  ### Date and time picker
16
16
 
17
- ```ts file="./examples/DateTimePicker/DateTimePicker.tsx"
17
+ ```ts file="examples/DateTimePicker/DateTimePicker.tsx"
18
18
 
19
19
  ```
20
20
 
21
21
  ### Date and time range picker
22
22
 
23
- ```js
24
- import { useState } from 'react';
25
- import { Flex, FlexItem, InputGroup, InputGroupItem, DatePicker, isValidDate, TimePicker, yyyyMMddFormat, updateDateTime } from '@patternfly/react-core';
26
-
27
- DateTimeRangePicker = () => {
28
- const [from, setFrom] = useState();
29
- const [to, setTo] = useState();
30
-
31
- const toValidator = (date) => {
32
- return isValidDate(from) && yyyyMMddFormat(date) >= yyyyMMddFormat(from)
33
- ? ''
34
- : 'The "to" date must be after the "from" date';
35
- };
36
-
37
- const onFromDateChange = (_event, inputDate, newFromDate) => {
38
- if (isValidDate(from) && isValidDate(newFromDate) && inputDate === yyyyMMddFormat(newFromDate)) {
39
- newFromDate.setHours(from.getHours());
40
- newFromDate.setMinutes(from.getMinutes());
41
- }
42
- if (isValidDate(newFromDate) && inputDate === yyyyMMddFormat(newFromDate)) {
43
- setFrom(new Date(newFromDate));
44
- }
45
- };
46
-
47
- const onFromTimeChange = (_event, time, hour, minute) => {
48
- if (isValidDate(from)) {
49
- const updatedFromDate = new Date(from);
50
- updatedFromDate.setHours(hour);
51
- updatedFromDate.setMinutes(minute);
52
- setFrom(updatedFromDate);
53
- }
54
- };
55
-
56
- const onToDateChange = (_event, inputDate, newToDate) => {
57
- if (isValidDate(to) && isValidDate(newToDate) && inputDate === yyyyMMddFormat(newToDate)) {
58
- newToDate.setHours(to.getHours());
59
- newToDate.setMinutes(to.getMinutes());
60
- }
61
- if (isValidDate(newToDate) && inputDate === yyyyMMddFormat(newToDate)) {
62
- setTo(newToDate);
63
- }
64
- };
65
-
66
- const onToTimeChange = (_event, time, hour, minute) => {
67
- if (isValidDate(to)) {
68
- const updatedToDate = new Date(to);
69
- updatedToDate.setHours(hour);
70
- updatedToDate.setMinutes(minute);
71
- setTo(updatedToDate);
72
- }
73
- };
23
+ ```ts file="examples/DateTimePicker/DateTimeRangePicker.tsx"
74
24
 
75
- return (
76
- <Flex direction={{ default: 'column', lg: 'row' }}>
77
- <FlexItem>
78
- <InputGroup>
79
- <InputGroupItem>
80
- <DatePicker onChange={onFromDateChange} aria-label="Start date" placeholder="YYYY-MM-DD" />
81
- </InputGroupItem>
82
- <InputGroupItem>
83
- <TimePicker aria-label="Start time" style={{ width: '150px' }} onChange={onFromTimeChange} />
84
- </InputGroupItem>
85
- </InputGroup>
86
- </FlexItem>
87
- <FlexItem>to</FlexItem>
88
- <FlexItem>
89
- <InputGroup>
90
- <InputGroupItem>
91
- <DatePicker
92
- value={isValidDate(to) ? yyyyMMddFormat(to) : to}
93
- onChange={onToDateChange}
94
- isDisabled={!isValidDate(from)}
95
- rangeStart={from}
96
- validators={[toValidator]}
97
- aria-label="End date"
98
- placeholder="YYYY-MM-DD"
99
- />
100
- </InputGroupItem>
101
- <InputGroupItem>
102
- <TimePicker style={{ width: '150px' }} onChange={onToTimeChange} isDisabled={!isValidDate(from)} />
103
- </InputGroupItem>
104
- </InputGroup>
105
- </FlexItem>
106
- </Flex>
107
- );
108
- }
109
25
  ```