@patternfly/react-core 6.2.0-prerelease.1 → 6.2.0-prerelease.11

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 (172) hide show
  1. package/CHANGELOG.md +55 -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/ClipboardCopy/ClipboardCopy.d.ts +1 -1
  115. package/dist/esm/components/ClipboardCopy/ClipboardCopy.d.ts.map +1 -1
  116. package/dist/esm/components/ClipboardCopy/ClipboardCopy.js +4 -2
  117. package/dist/esm/components/ClipboardCopy/ClipboardCopy.js.map +1 -1
  118. package/dist/esm/components/FileUpload/FileUploadField.d.ts +2 -0
  119. package/dist/esm/components/FileUpload/FileUploadField.d.ts.map +1 -1
  120. package/dist/esm/components/FileUpload/FileUploadField.js +2 -2
  121. package/dist/esm/components/FileUpload/FileUploadField.js.map +1 -1
  122. package/dist/esm/components/TextArea/TextArea.d.ts +3 -2
  123. package/dist/esm/components/TextArea/TextArea.d.ts.map +1 -1
  124. package/dist/esm/components/TextArea/TextArea.js +5 -2
  125. package/dist/esm/components/TextArea/TextArea.js.map +1 -1
  126. package/dist/esm/components/Truncate/Truncate.d.ts.map +1 -1
  127. package/dist/esm/components/Truncate/Truncate.js +5 -7
  128. package/dist/esm/components/Truncate/Truncate.js.map +1 -1
  129. package/dist/js/components/ClipboardCopy/ClipboardCopy.d.ts +1 -1
  130. package/dist/js/components/ClipboardCopy/ClipboardCopy.d.ts.map +1 -1
  131. package/dist/js/components/ClipboardCopy/ClipboardCopy.js +4 -2
  132. package/dist/js/components/ClipboardCopy/ClipboardCopy.js.map +1 -1
  133. package/dist/js/components/FileUpload/FileUploadField.d.ts +2 -0
  134. package/dist/js/components/FileUpload/FileUploadField.d.ts.map +1 -1
  135. package/dist/js/components/FileUpload/FileUploadField.js +2 -2
  136. package/dist/js/components/FileUpload/FileUploadField.js.map +1 -1
  137. package/dist/js/components/TextArea/TextArea.d.ts +3 -2
  138. package/dist/js/components/TextArea/TextArea.d.ts.map +1 -1
  139. package/dist/js/components/TextArea/TextArea.js +5 -2
  140. package/dist/js/components/TextArea/TextArea.js.map +1 -1
  141. package/dist/js/components/Truncate/Truncate.d.ts.map +1 -1
  142. package/dist/js/components/Truncate/Truncate.js +5 -7
  143. package/dist/js/components/Truncate/Truncate.js.map +1 -1
  144. package/dist/umd/assets/{output-BwnR4NQh.css → output-DYYMgGsx.css} +18811 -18811
  145. package/dist/umd/react-core.min.js +2 -2
  146. package/helpers/package.json +1 -1
  147. package/layouts/package.json +1 -1
  148. package/next/package.json +1 -1
  149. package/package.json +8 -8
  150. package/src/components/ClipboardCopy/ClipboardCopy.tsx +5 -3
  151. package/src/components/ClipboardCopy/__tests__/ClipboardCopy.test.tsx +15 -0
  152. package/src/components/ClipboardCopy/__tests__/__snapshots__/ClipboardCopy.test.tsx.snap +1 -1
  153. package/src/components/FileUpload/FileUploadField.tsx +4 -1
  154. package/src/components/FileUpload/__tests__/FileUploadField.test.tsx +15 -1
  155. package/src/components/FileUpload/examples/FileUploadCustomUpload.tsx +8 -0
  156. package/src/components/TextArea/TextArea.tsx +8 -7
  157. package/src/components/TextArea/__tests__/TextArea.test.tsx +18 -0
  158. package/src/components/TextArea/examples/TextArea.md +6 -0
  159. package/src/components/TextArea/examples/TextAreaResizableNone.tsx +14 -0
  160. package/src/components/Toolbar/examples/Toolbar.md +8 -8
  161. package/src/components/TreeView/examples/TreeView.md +7 -1
  162. package/src/components/TreeView/examples/TreeViewWithIconPerItem.tsx +64 -0
  163. package/src/components/Truncate/Truncate.tsx +17 -14
  164. package/src/components/Truncate/__tests__/Truncate.test.tsx +17 -1
  165. package/src/demos/DataList/examples/DataListActionable.tsx +134 -0
  166. package/src/demos/DataListDemo.md +5 -0
  167. package/src/demos/DescriptionList/DescriptionList.md +7 -1
  168. package/src/demos/DescriptionList/examples/DescriptionListInDrawer.tsx +162 -0
  169. package/src/demos/Skeleton.md +13 -0
  170. package/src/demos/examples/Skeleton/SkeletonCard.tsx +40 -0
  171. package/src/components/DataList/examples/DataListDraggable.tsx +0 -108
  172. package/src/components/DualListSelector/examples/DualListSelectorDragDrop.tsx +0 -177
@@ -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.2.0-prerelease.0","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.2.0-prerelease.10","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.2.0-prerelease.0","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.2.0-prerelease.10","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.2.0-prerelease.0","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.2.0-prerelease.10","private":true}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "6.2.0-prerelease.1",
3
+ "version": "6.2.0-prerelease.11",
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",
@@ -46,22 +46,22 @@
46
46
  "subpaths": "node ../../scripts/exportSubpaths.mjs --config subpaths.config.json"
47
47
  },
48
48
  "dependencies": {
49
- "@patternfly/react-icons": "^6.2.0-prerelease.0",
50
- "@patternfly/react-styles": "^6.2.0-prerelease.0",
51
- "@patternfly/react-tokens": "^6.2.0-prerelease.0",
52
- "focus-trap": "7.6.2",
49
+ "@patternfly/react-icons": "^6.2.0-prerelease.2",
50
+ "@patternfly/react-styles": "^6.2.0-prerelease.2",
51
+ "@patternfly/react-tokens": "^6.2.0-prerelease.2",
52
+ "focus-trap": "7.6.4",
53
53
  "react-dropzone": "^14.3.5",
54
54
  "tslib": "^2.8.1"
55
55
  },
56
56
  "devDependencies": {
57
- "@patternfly/patternfly": "6.1.0-prerelease.11",
57
+ "@patternfly/patternfly": "6.1.0",
58
58
  "case-anything": "^2.1.13",
59
59
  "css": "^3.0.0",
60
- "fs-extra": "^11.2.0"
60
+ "fs-extra": "^11.3.0"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "react": "^17 || ^18",
64
64
  "react-dom": "^17 || ^18"
65
65
  },
66
- "gitHead": "99e344c2f5d577d518bcae57d13b7ab5fa191c03"
66
+ "gitHead": "d6ab1b6db6cdfb7464de2ce020acbd0192e287d9"
67
67
  }
@@ -89,7 +89,7 @@ export interface ClipboardCopyProps extends Omit<React.HTMLProps<HTMLDivElement>
89
89
  /** A function that is triggered on changing the text. */
90
90
  onChange?: (event: React.FormEvent, text?: string) => void;
91
91
  /** The text which is copied. */
92
- children: string;
92
+ children: string | string[];
93
93
  /** Additional actions for inline clipboard copy. Should be wrapped with ClipboardCopyAction. */
94
94
  additionalActions?: React.ReactNode;
95
95
  /** Value to overwrite the randomly generated data-ouia-component-id.*/
@@ -103,7 +103,7 @@ class ClipboardCopy extends React.Component<ClipboardCopyProps, ClipboardCopySta
103
103
  timer = null as number;
104
104
  constructor(props: ClipboardCopyProps) {
105
105
  super(props);
106
- const text = Array.isArray(this.props.children) ? this.props.children.join('') : (this.props.children as string);
106
+ const text = Array.isArray(this.props.children) ? this.props.children.join(' ') : (this.props.children as string);
107
107
  this.state = {
108
108
  text,
109
109
  expanded: this.props.isExpanded,
@@ -134,7 +134,9 @@ class ClipboardCopy extends React.Component<ClipboardCopyProps, ClipboardCopySta
134
134
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
135
135
  componentDidUpdate = (prevProps: ClipboardCopyProps, prevState: ClipboardCopyState) => {
136
136
  if (prevProps.children !== this.props.children) {
137
- const newText = this.props.children as string;
137
+ const newText = Array.isArray(this.props.children)
138
+ ? this.props.children.join(' ')
139
+ : (this.props.children as string);
138
140
  this.setState({ text: newText, textWhenExpanded: newText });
139
141
  }
140
142
  };
@@ -336,6 +336,21 @@ test('Does not call onCopy when ClipboardCopyButton is not clicked', async () =>
336
336
  expect(onCopyMock).not.toHaveBeenCalled();
337
337
  });
338
338
 
339
+ test('Can take array of strings as children', async () => {
340
+ const onCopyMock = jest.fn();
341
+ const user = userEvent.setup();
342
+ const childrenArray = children.split(' ');
343
+
344
+ // sanity check to ensure we are checking an array with at least 2 elements
345
+ expect(childrenArray.length).toBeGreaterThan(1);
346
+
347
+ render(<ClipboardCopy onCopy={onCopyMock}>{childrenArray}</ClipboardCopy>);
348
+
349
+ await user.click(screen.getByRole('button', { name: 'Test CCB clicker' }));
350
+
351
+ expect(onCopyMock).toHaveBeenCalledWith(expect.any(Object), children);
352
+ });
353
+
339
354
  test('Matches snapshot', () => {
340
355
  const { asFragment } = render(
341
356
  <ClipboardCopy id="snapshot" ouiaId="snapshot">
@@ -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-26"
21
+ data-ouia-component-id="OUIA-Generated-TextInputBase-27"
22
22
  data-ouia-component-type="PF6/TextInput"
23
23
  data-ouia-safe="true"
24
24
  id="text-input-generated-id"
@@ -43,6 +43,8 @@ export interface FileUploadFieldProps extends Omit<React.HTMLProps<HTMLDivElemen
43
43
  id: string;
44
44
  /** Name property for the text input. */
45
45
  name?: string;
46
+ /** Flag to disable the browse button. */
47
+ isBrowseButtonDisabled?: boolean;
46
48
  /** Flag to disable the clear button. */
47
49
  isClearButtonDisabled?: boolean;
48
50
  /** Flag to show if the field is disabled. */
@@ -114,6 +116,7 @@ export const FileUploadField: React.FunctionComponent<FileUploadFieldProps> = ({
114
116
  browseButtonText = 'Browse...',
115
117
  browseButtonAriaDescribedby,
116
118
  clearButtonText = 'Clear',
119
+ isBrowseButtonDisabled = false,
117
120
  isClearButtonDisabled = !filename && !value,
118
121
  containerRef = null as React.Ref<HTMLDivElement>,
119
122
  allowEditingUploadedText = false,
@@ -153,7 +156,7 @@ export const FileUploadField: React.FunctionComponent<FileUploadFieldProps> = ({
153
156
  <Button
154
157
  variant={ButtonVariant.control}
155
158
  onClick={onBrowseButtonClick}
156
- isDisabled={isDisabled}
159
+ isDisabled={isDisabled || isBrowseButtonDisabled}
157
160
  aria-describedby={browseButtonAriaDescribedby}
158
161
  >
159
162
  {browseButtonText}
@@ -1,6 +1,7 @@
1
1
  import { FileUploadField } from '../FileUploadField';
2
2
  import * as React from 'react';
3
3
  import { render, screen } from '@testing-library/react';
4
+ import '@testing-library/jest-dom';
4
5
 
5
6
  test('simple fileuploadfield', () => {
6
7
  const browserBtnClickHandler = jest.fn();
@@ -15,6 +16,7 @@ test('simple fileuploadfield', () => {
15
16
  filenamePlaceholder="Do something custom with this!"
16
17
  onBrowseButtonClick={browserBtnClickHandler}
17
18
  onClearButtonClick={clearBtnClickHandler}
19
+ isBrowseButtonDisabled={false}
18
20
  isClearButtonDisabled={false}
19
21
  isLoading={false}
20
22
  isDragActive={false}
@@ -32,7 +34,7 @@ test('Renders without aria-describedby on browse button by default', () => {
32
34
  expect(screen.getByRole('button', { name: 'Upload' })).not.toHaveAccessibleDescription();
33
35
  });
34
36
 
35
- test('Renders without aria-describedby on browse button by default', () => {
37
+ test('Renders with aria-describedby on browse button', () => {
36
38
  render(
37
39
  <FileUploadField id="file-upload-field" browseButtonText="Upload" browseButtonAriaDescribedby="helper-text">
38
40
  <div id="helper-text">Helper text</div>
@@ -41,3 +43,15 @@ test('Renders without aria-describedby on browse button by default', () => {
41
43
 
42
44
  expect(screen.getByRole('button', { name: 'Upload' })).toHaveAccessibleDescription('Helper text');
43
45
  });
46
+
47
+ test('Browse button is enabled by default', () => {
48
+ render(<FileUploadField id="file-upload-field" browseButtonText="Upload" />);
49
+
50
+ expect(screen.getByRole('button', { name: 'Upload' })).not.toHaveAttribute('disabled');
51
+ });
52
+
53
+ test('Browse button is disabled with isBrowseButtonDisabled prop', () => {
54
+ render(<FileUploadField id="file-upload-field" browseButtonText="Upload" isBrowseButtonDisabled={true} />);
55
+
56
+ expect(screen.getByRole('button', { name: 'Upload' })).toHaveAttribute('disabled');
57
+ });
@@ -4,6 +4,7 @@ import { FileUploadField, FileUploadHelperText, HelperText, HelperTextItem, Chec
4
4
  export const CustomPreviewFileUpload: React.FunctionComponent = () => {
5
5
  const properties = [
6
6
  'filename',
7
+ 'isBrowseButtonDisabled',
7
8
  'isClearButtonDisabled',
8
9
  'isDragActive',
9
10
  'isLoading',
@@ -15,6 +16,7 @@ export const CustomPreviewFileUpload: React.FunctionComponent = () => {
15
16
 
16
17
  const [value, setValue] = React.useState('');
17
18
  const [filename, setFilename] = React.useState(false);
19
+ const [isBrowseButtonDisabled, setIsBrowseButtonDisabled] = React.useState(true);
18
20
  const [isClearButtonDisabled, setIsClearButtonDisabled] = React.useState(true);
19
21
  const [isLoading, setIsLoading] = React.useState(false);
20
22
  const [isDragActive, setIsDragActive] = React.useState(false);
@@ -24,6 +26,7 @@ export const CustomPreviewFileUpload: React.FunctionComponent = () => {
24
26
  const [hasPlaceholderText, setHasPlaceholderText] = React.useState(false);
25
27
  const [checkedState, setCheckedState] = React.useState([
26
28
  filename,
29
+ isBrowseButtonDisabled,
27
30
  isClearButtonDisabled,
28
31
  isLoading,
29
32
  isDragActive,
@@ -44,6 +47,10 @@ export const CustomPreviewFileUpload: React.FunctionComponent = () => {
44
47
  checked ? setFilename(true) : setFilename(false);
45
48
  break;
46
49
 
50
+ case 'isBrowseButtonDisabled':
51
+ checked ? setIsBrowseButtonDisabled(true) : setIsBrowseButtonDisabled(false);
52
+ break;
53
+
47
54
  case 'isClearButtonDisabled':
48
55
  checked ? setIsClearButtonDisabled(true) : setIsClearButtonDisabled(false);
49
56
  break;
@@ -109,6 +116,7 @@ export const CustomPreviewFileUpload: React.FunctionComponent = () => {
109
116
  filenamePlaceholder="Do something custom with this!"
110
117
  onBrowseButtonClick={() => alert('Browse button clicked!')}
111
118
  onClearButtonClick={() => alert('Clear button clicked!')}
119
+ isBrowseButtonDisabled={isBrowseButtonDisabled}
112
120
  isClearButtonDisabled={isClearButtonDisabled}
113
121
  isLoading={isLoading}
114
122
  isDragActive={isDragActive}
@@ -8,7 +8,8 @@ import { FormControlIcon } from '../FormControl/FormControlIcon';
8
8
  export enum TextAreResizeOrientation {
9
9
  horizontal = 'horizontal',
10
10
  vertical = 'vertical',
11
- both = 'both'
11
+ both = 'both',
12
+ none = 'none'
12
13
  }
13
14
 
14
15
  export enum TextAreaReadOnlyVariant {
@@ -37,7 +38,7 @@ export interface TextAreaProps extends Omit<HTMLProps<HTMLTextAreaElement>, 'onC
37
38
  /** A callback for when the text area value changes. */
38
39
  onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;
39
40
  /** Sets the orientation to limit the resize to */
40
- resizeOrientation?: 'horizontal' | 'vertical' | 'both';
41
+ resizeOrientation?: 'horizontal' | 'vertical' | 'both' | 'none';
41
42
  /** Custom flag to show that the text area requires an associated id or aria-label. */
42
43
  'aria-label'?: string;
43
44
  /** @hide A reference object to attach to the text area. */
@@ -118,10 +119,10 @@ class TextAreaBase extends React.Component<TextAreaProps> {
118
119
  onFocus,
119
120
  ...props
120
121
  } = this.props;
121
- const orientation = `resize${capitalize(resizeOrientation)}` as
122
- | 'resizeVertical'
123
- | 'resizeHorizontal'
124
- | 'resizeBoth';
122
+ const orientation =
123
+ resizeOrientation !== 'none'
124
+ ? (`resize${capitalize(resizeOrientation)}` as 'resizeVertical' | 'resizeHorizontal' | 'resizeBoth')
125
+ : undefined;
125
126
  const hasStatusIcon = ['success', 'error', 'warning'].includes(validated);
126
127
 
127
128
  return (
@@ -130,7 +131,7 @@ class TextAreaBase extends React.Component<TextAreaProps> {
130
131
  styles.formControl,
131
132
  readOnlyVariant && styles.modifiers.readonly,
132
133
  readOnlyVariant === 'plain' && styles.modifiers.plain,
133
- resizeOrientation && styles.modifiers[orientation],
134
+ resizeOrientation !== 'none' && styles.modifiers[orientation],
134
135
  isDisabled && styles.modifiers.disabled,
135
136
  hasStatusIcon && styles.modifiers[validated as 'success' | 'warning' | 'error'],
136
137
  className
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import '@testing-library/jest-dom';
2
3
 
3
4
  import { render, screen } from '@testing-library/react';
4
5
  import userEvent from '@testing-library/user-event';
@@ -93,6 +94,16 @@ test('Text area is not invalid by default', () => {
93
94
  expect(screen.getByRole('textbox')).not.toBeInvalid();
94
95
  });
95
96
 
97
+ test('Renders vertically & resizable text area by default', () => {
98
+ render(<TextArea aria-label="vertical resize textarea" />);
99
+ expect(screen.getByRole('textbox').parentElement).toHaveClass('pf-m-resize-both');
100
+ });
101
+
102
+ test('Renders vertically & resizable text area when resizeOrientation is set to both', () => {
103
+ render(<TextArea aria-label="vertical resize textarea" resizeOrientation="both" />);
104
+ expect(screen.getByRole('textbox').parentElement).toHaveClass('pf-m-resize-both');
105
+ });
106
+
96
107
  test('Renders vertically resizable text area', () => {
97
108
  render(<TextArea aria-label="vertical resize textarea" resizeOrientation="vertical" />);
98
109
  expect(screen.getByRole('textbox').parentElement).toHaveClass('pf-m-resize-vertical');
@@ -103,6 +114,13 @@ test('Renders horizontally resizable text area', () => {
103
114
  expect(screen.getByRole('textbox').parentElement).toHaveClass('pf-m-resize-horizontal');
104
115
  });
105
116
 
117
+ test('Disables resizable text area', () => {
118
+ render(<TextArea aria-label="disabled resize textarea" resizeOrientation="none" />);
119
+ expect(screen.getByRole('textbox').parentElement).not.toHaveClass('pf-m-resize-vertical');
120
+ expect(screen.getByRole('textbox').parentElement).not.toHaveClass('pf-m-resize-horizontal');
121
+ expect(screen.getByRole('textbox').parentElement).not.toHaveClass('pf-m-resize-both');
122
+ });
123
+
106
124
  test('Throws console error when no aria-label or id is given', () => {
107
125
  jest.spyOn(global.console, 'error');
108
126
 
@@ -38,6 +38,12 @@ propComponents: ['TextArea']
38
38
 
39
39
  ```
40
40
 
41
+ ### Not resizable
42
+
43
+ ```ts file="./TextAreaResizableNone.tsx"
44
+
45
+ ```
46
+
41
47
  ### Uncontrolled
42
48
 
43
49
  ```ts file="./TextAreaUncontrolled.tsx"
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { TextArea } from '@patternfly/react-core';
3
+
4
+ export const TextAreaResizeNone: React.FunctionComponent = () => {
5
+ const [value, setValue] = React.useState('');
6
+ return (
7
+ <TextArea
8
+ value={value}
9
+ onChange={(_event, value) => setValue(value)}
10
+ resizeOrientation="none"
11
+ aria-label="text area resize none example"
12
+ />
13
+ );
14
+ };
@@ -62,6 +62,14 @@ Note: This example does not demonstrate responsive toolbar behavior. Responsive
62
62
 
63
63
  ```
64
64
 
65
+ ### Background color variants
66
+
67
+ To change the background color of a toolbar, use the `colorVariant` property on the `<Toolbar>`.
68
+
69
+ ```ts file="./ToolbarColorVariant.tsx"
70
+
71
+ ```
72
+
65
73
  ## Examples with toggle groups and filters
66
74
 
67
75
  The following examples use toggle groups to allow for more responsive and complex toolbars with multiple items and groups of items. To visualize responsive toolbar behavior in the following examples, resize the browser to a smaller screen width.
@@ -112,11 +120,3 @@ When all of a toolbar's required elements cannot fit in a single line, you can s
112
120
  ```ts file="./ToolbarStacked.tsx"
113
121
 
114
122
  ```
115
-
116
- ## Background color variants
117
-
118
- To change the background color of a toolbar, use the `colorVariant` property on the `<Toolbar>`.
119
-
120
- ```ts file="./ToolbarColorVariant.tsx"
121
-
122
- ```
@@ -5,7 +5,7 @@ cssPrefix: pf-v6-c-tree-view
5
5
  propComponents: ['TreeView', 'TreeViewDataItem', 'TreeViewSearch']
6
6
  ---
7
7
 
8
- import { FolderIcon, FolderOpenIcon, EllipsisVIcon, ClipboardIcon, HamburgerIcon } from '@patternfly/react-icons';
8
+ import { FolderIcon, FolderOpenIcon, EllipsisVIcon, ClipboardIcon, HamburgerIcon, GitlabIcon, GithubIcon, GoogleIcon } from '@patternfly/react-icons';
9
9
 
10
10
  ## Examples
11
11
 
@@ -51,6 +51,12 @@ A search input can be used to filter tree view items. It is recommended that a t
51
51
 
52
52
  ```
53
53
 
54
+ ### With unique icon per item
55
+
56
+ ```ts file='./TreeViewWithIconPerItem.tsx'
57
+
58
+ ```
59
+
54
60
  ### With badges
55
61
 
56
62
  ```ts file='./TreeViewWithBadges.tsx'
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import { TreeView, TreeViewDataItem } from '@patternfly/react-core';
3
+ import GitlabIcon from '@patternfly/react-icons/dist/esm/icons/gitlab-icon';
4
+ import GithubIcon from '@patternfly/react-icons/dist/esm/icons/github-icon';
5
+ import GoogleIcon from '@patternfly/react-icons/dist/esm/icons/google-icon';
6
+
7
+ export const TreeViewWithIconPerItem: React.FunctionComponent = () => {
8
+ const [activeItems, setActiveItems] = React.useState<TreeViewDataItem[]>();
9
+
10
+ const onSelect = (_event: React.MouseEvent, treeViewItem: TreeViewDataItem) => {
11
+ // Ignore folders for selection
12
+ if (treeViewItem && !treeViewItem.children) {
13
+ setActiveItems([treeViewItem]);
14
+ }
15
+ };
16
+ const options: TreeViewDataItem[] = [
17
+ {
18
+ name: 'Github accounts',
19
+ id: 'iconPerItem-Github',
20
+ icon: <GithubIcon />,
21
+ children: [
22
+ {
23
+ name: 'Account 1',
24
+ id: 'iconPerItem-Acc1'
25
+ },
26
+ {
27
+ name: 'Account 2',
28
+ id: 'iconPerItem-Acc2'
29
+ }
30
+ ],
31
+ defaultExpanded: true
32
+ },
33
+ {
34
+ name: 'Gitlab accounts',
35
+ id: 'iconPerItem-Gitlab',
36
+ icon: <GitlabIcon />,
37
+ children: [
38
+ {
39
+ name: 'Account 3',
40
+ id: 'iconPerItem-Acc3'
41
+ }
42
+ ]
43
+ },
44
+ {
45
+ name: 'Google accounts',
46
+ id: 'iconPerItem-Google',
47
+ icon: <GoogleIcon />,
48
+ children: [
49
+ {
50
+ name: 'Account 4',
51
+ id: 'iconPerItem-Acc4'
52
+ }
53
+ ]
54
+ }
55
+ ];
56
+ return (
57
+ <TreeView
58
+ aria-label="Tree View with unique icon per item example"
59
+ data={options}
60
+ activeItems={activeItems}
61
+ onSelect={onSelect}
62
+ />
63
+ );
64
+ };
@@ -88,7 +88,7 @@ export const Truncate: React.FunctionComponent<TruncateProps> = ({
88
88
  if (subParentRef && subParentRef.current.parentElement.parentElement && !parentElement) {
89
89
  setParentElement(subParentRef.current.parentElement.parentElement);
90
90
  }
91
- }, [textRef, subParentRef]);
91
+ }, [textRef, subParentRef, textElement, parentElement]);
92
92
 
93
93
  React.useEffect(() => {
94
94
  if (textElement && parentElement && !observer.current) {
@@ -106,7 +106,7 @@ export const Truncate: React.FunctionComponent<TruncateProps> = ({
106
106
  observer();
107
107
  };
108
108
  }
109
- }, [textElement, parentElement]);
109
+ }, [textElement, parentElement, trailingNumChars, content, position]);
110
110
 
111
111
  const truncateBody = (
112
112
  <span ref={subParentRef} className={css(styles.truncate, className)} {...props}>
@@ -116,18 +116,21 @@ export const Truncate: React.FunctionComponent<TruncateProps> = ({
116
116
  {position === TruncatePosition.start && <React.Fragment>&lrm;</React.Fragment>}
117
117
  </span>
118
118
  )}
119
- {position === TruncatePosition.middle &&
120
- content.slice(0, content.length - trailingNumChars).length > minWidthCharacters && (
121
- <React.Fragment>
122
- <span ref={textRef} className={styles.truncateStart}>
123
- {sliceContent(content, trailingNumChars)[0]}
124
- </span>
125
- <span className={styles.truncateEnd}>{sliceContent(content, trailingNumChars)[1]}</span>
126
- </React.Fragment>
127
- )}
128
- {position === TruncatePosition.middle &&
129
- content.slice(0, content.length - trailingNumChars).length <= minWidthCharacters &&
130
- content}
119
+ {position === TruncatePosition.middle && content.length - trailingNumChars > minWidthCharacters && (
120
+ <React.Fragment>
121
+ <span ref={textRef} className={styles.truncateStart}>
122
+ {sliceContent(content, trailingNumChars)[0]}
123
+ </span>
124
+ <span className={styles.truncateEnd}>{sliceContent(content, trailingNumChars)[1]}</span>
125
+ </React.Fragment>
126
+ )}
127
+ {position === TruncatePosition.middle && content.length - trailingNumChars <= minWidthCharacters && (
128
+ <React.Fragment>
129
+ <span ref={textRef} className={styles.truncateStart}>
130
+ {content}
131
+ </span>
132
+ </React.Fragment>
133
+ )}
131
134
  </span>
132
135
  );
133
136
 
@@ -1,7 +1,8 @@
1
- import React from 'react';
1
+ import * as React from 'react';
2
2
  import { render, screen } from '@testing-library/react';
3
3
  import { Truncate } from '../Truncate';
4
4
  import styles from '@patternfly/react-styles/css/components/Truncate/truncate';
5
+ import '@testing-library/jest-dom';
5
6
 
6
7
  jest.mock('../../Tooltip', () => ({
7
8
  Tooltip: ({ content, position, children, ...props }) => (
@@ -112,6 +113,21 @@ test('renders different content when trailingNumChars is passed with middle trun
112
113
  expect(end).toHaveClass(styles.truncateEnd);
113
114
  });
114
115
 
116
+ test('renders full content when trailingNumChars exceeds the length of the original string using middle truncate', () => {
117
+ render(
118
+ <Truncate
119
+ content={'Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.'} // 75 chars
120
+ trailingNumChars={80}
121
+ position="middle"
122
+ />
123
+ );
124
+
125
+ const start = screen.getByText('Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.');
126
+
127
+ expect(start).toHaveClass(styles.truncateStart);
128
+ expect(start).not.toHaveClass(styles.truncateEnd);
129
+ });
130
+
115
131
  test('renders tooltip position', () => {
116
132
  render(<Truncate content={''} tooltipPosition="top" />);
117
133