@patternfly/react-core 5.0.0-alpha.32 → 5.0.0-alpha.33

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 (155) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/components/EmptyState/EmptyState.d.ts +6 -6
  3. package/components/EmptyState/EmptyState.d.ts.map +1 -1
  4. package/components/EmptyState/EmptyState.js +4 -4
  5. package/components/EmptyState/EmptyState.js.map +1 -1
  6. package/components/EmptyState/EmptyStateActions.d.ts +9 -0
  7. package/components/EmptyState/EmptyStateActions.d.ts.map +1 -0
  8. package/components/EmptyState/EmptyStateActions.js +10 -0
  9. package/components/EmptyState/EmptyStateActions.js.map +1 -0
  10. package/components/EmptyState/EmptyStateBody.d.ts +2 -2
  11. package/components/EmptyState/EmptyStateBody.d.ts.map +1 -1
  12. package/components/EmptyState/EmptyStateBody.js +1 -1
  13. package/components/EmptyState/EmptyStateBody.js.map +1 -1
  14. package/components/EmptyState/EmptyStateFooter.d.ts +9 -0
  15. package/components/EmptyState/EmptyStateFooter.d.ts.map +1 -0
  16. package/components/EmptyState/EmptyStateFooter.js +10 -0
  17. package/components/EmptyState/EmptyStateFooter.js.map +1 -0
  18. package/components/EmptyState/EmptyStateHeader.d.ts +18 -0
  19. package/components/EmptyState/EmptyStateHeader.d.ts.map +1 -0
  20. package/components/EmptyState/EmptyStateHeader.js +14 -0
  21. package/components/EmptyState/EmptyStateHeader.js.map +1 -0
  22. package/components/EmptyState/EmptyStateIcon.d.ts +3 -9
  23. package/components/EmptyState/EmptyStateIcon.d.ts.map +1 -1
  24. package/components/EmptyState/EmptyStateIcon.js +6 -4
  25. package/components/EmptyState/EmptyStateIcon.js.map +1 -1
  26. package/components/EmptyState/index.d.ts +4 -3
  27. package/components/EmptyState/index.d.ts.map +1 -1
  28. package/components/EmptyState/index.js +4 -3
  29. package/components/EmptyState/index.js.map +1 -1
  30. package/dist/esm/components/EmptyState/EmptyState.d.ts +6 -6
  31. package/dist/esm/components/EmptyState/EmptyState.d.ts.map +1 -1
  32. package/dist/esm/components/EmptyState/EmptyState.js +4 -4
  33. package/dist/esm/components/EmptyState/EmptyState.js.map +1 -1
  34. package/dist/esm/components/EmptyState/EmptyStateActions.d.ts +9 -0
  35. package/dist/esm/components/EmptyState/EmptyStateActions.d.ts.map +1 -0
  36. package/dist/esm/components/EmptyState/EmptyStateActions.js +10 -0
  37. package/dist/esm/components/EmptyState/EmptyStateActions.js.map +1 -0
  38. package/dist/esm/components/EmptyState/EmptyStateBody.d.ts +2 -2
  39. package/dist/esm/components/EmptyState/EmptyStateBody.d.ts.map +1 -1
  40. package/dist/esm/components/EmptyState/EmptyStateBody.js +1 -1
  41. package/dist/esm/components/EmptyState/EmptyStateBody.js.map +1 -1
  42. package/dist/esm/components/EmptyState/EmptyStateFooter.d.ts +9 -0
  43. package/dist/esm/components/EmptyState/EmptyStateFooter.d.ts.map +1 -0
  44. package/dist/esm/components/EmptyState/EmptyStateFooter.js +10 -0
  45. package/dist/esm/components/EmptyState/EmptyStateFooter.js.map +1 -0
  46. package/dist/esm/components/EmptyState/EmptyStateHeader.d.ts +18 -0
  47. package/dist/esm/components/EmptyState/EmptyStateHeader.d.ts.map +1 -0
  48. package/dist/esm/components/EmptyState/EmptyStateHeader.js +14 -0
  49. package/dist/esm/components/EmptyState/EmptyStateHeader.js.map +1 -0
  50. package/dist/esm/components/EmptyState/EmptyStateIcon.d.ts +3 -9
  51. package/dist/esm/components/EmptyState/EmptyStateIcon.d.ts.map +1 -1
  52. package/dist/esm/components/EmptyState/EmptyStateIcon.js +6 -4
  53. package/dist/esm/components/EmptyState/EmptyStateIcon.js.map +1 -1
  54. package/dist/esm/components/EmptyState/index.d.ts +4 -3
  55. package/dist/esm/components/EmptyState/index.d.ts.map +1 -1
  56. package/dist/esm/components/EmptyState/index.js +4 -3
  57. package/dist/esm/components/EmptyState/index.js.map +1 -1
  58. package/dist/js/components/EmptyState/EmptyState.d.ts +6 -6
  59. package/dist/js/components/EmptyState/EmptyState.d.ts.map +1 -1
  60. package/dist/js/components/EmptyState/EmptyState.js +4 -4
  61. package/dist/js/components/EmptyState/EmptyState.js.map +1 -1
  62. package/dist/js/components/EmptyState/EmptyStateActions.d.ts +9 -0
  63. package/dist/js/components/EmptyState/EmptyStateActions.d.ts.map +1 -0
  64. package/dist/js/components/EmptyState/EmptyStateActions.js +14 -0
  65. package/dist/js/components/EmptyState/EmptyStateActions.js.map +1 -0
  66. package/dist/js/components/EmptyState/EmptyStateBody.d.ts +2 -2
  67. package/dist/js/components/EmptyState/EmptyStateBody.d.ts.map +1 -1
  68. package/dist/js/components/EmptyState/EmptyStateBody.js +1 -1
  69. package/dist/js/components/EmptyState/EmptyStateBody.js.map +1 -1
  70. package/dist/js/components/EmptyState/EmptyStateFooter.d.ts +9 -0
  71. package/dist/js/components/EmptyState/EmptyStateFooter.d.ts.map +1 -0
  72. package/dist/js/components/EmptyState/EmptyStateFooter.js +14 -0
  73. package/dist/js/components/EmptyState/EmptyStateFooter.js.map +1 -0
  74. package/dist/js/components/EmptyState/EmptyStateHeader.d.ts +18 -0
  75. package/dist/js/components/EmptyState/EmptyStateHeader.d.ts.map +1 -0
  76. package/dist/js/components/EmptyState/EmptyStateHeader.js +18 -0
  77. package/dist/js/components/EmptyState/EmptyStateHeader.js.map +1 -0
  78. package/dist/js/components/EmptyState/EmptyStateIcon.d.ts +3 -9
  79. package/dist/js/components/EmptyState/EmptyStateIcon.d.ts.map +1 -1
  80. package/dist/js/components/EmptyState/EmptyStateIcon.js +6 -4
  81. package/dist/js/components/EmptyState/EmptyStateIcon.js.map +1 -1
  82. package/dist/js/components/EmptyState/index.d.ts +4 -3
  83. package/dist/js/components/EmptyState/index.d.ts.map +1 -1
  84. package/dist/js/components/EmptyState/index.js +4 -3
  85. package/dist/js/components/EmptyState/index.js.map +1 -1
  86. package/dist/umd/react-core.min.js +1 -1
  87. package/package.json +2 -2
  88. package/src/components/DualListSelector/examples/DualListSelectorComposable.tsx +32 -30
  89. package/src/components/DualListSelector/examples/DualListSelectorComposableTree.tsx +38 -34
  90. package/src/components/EmptyState/EmptyState.tsx +9 -9
  91. package/src/components/EmptyState/EmptyStateActions.tsx +21 -0
  92. package/src/components/EmptyState/EmptyStateBody.tsx +3 -3
  93. package/src/components/EmptyState/EmptyStateFooter.tsx +21 -0
  94. package/src/components/EmptyState/EmptyStateHeader.tsx +42 -0
  95. package/src/components/EmptyState/EmptyStateIcon.tsx +15 -18
  96. package/src/components/EmptyState/__tests__/EmptyState.test.tsx +53 -60
  97. package/src/components/EmptyState/__tests__/Generated/{EmptyStatePrimary.test.tsx → EmptyStateActions.test.tsx} +3 -3
  98. package/src/components/EmptyState/__tests__/Generated/EmptyStateIcon.test.tsx +3 -6
  99. package/src/components/EmptyState/__tests__/Generated/__snapshots__/{EmptyStateSecondaryActions.test.tsx.snap → EmptyStateActions.test.tsx.snap} +2 -2
  100. package/src/components/EmptyState/__tests__/Generated/__snapshots__/EmptyStateIcon.test.tsx.snap +41 -22
  101. package/src/components/EmptyState/__tests__/__snapshots__/EmptyState.test.tsx.snap +115 -56
  102. package/src/components/EmptyState/examples/EmptyState.md +7 -3
  103. package/src/components/EmptyState/examples/EmptyStateBasic.tsx +20 -18
  104. package/src/components/EmptyState/examples/EmptyStateCustomIconColor.tsx +17 -0
  105. package/src/components/EmptyState/examples/EmptyStateExtraLarge.tsx +20 -18
  106. package/src/components/EmptyState/examples/EmptyStateExtraSmall.tsx +16 -15
  107. package/src/components/EmptyState/examples/EmptyStateLarge.tsx +21 -19
  108. package/src/components/EmptyState/examples/EmptyStateNoMatchFound.tsx +15 -8
  109. package/src/components/EmptyState/examples/EmptyStateSmall.tsx +21 -19
  110. package/src/components/EmptyState/examples/EmptyStateSpinner.tsx +2 -5
  111. package/src/components/EmptyState/index.ts +4 -3
  112. package/src/components/NotificationDrawer/examples/NotificationDrawerGroups.tsx +15 -11
  113. package/src/components/NotificationDrawer/examples/NotificationDrawerLightweight.tsx +14 -10
  114. package/src/components/Wizard/examples/Wizard.md +1 -1
  115. package/src/components/Wizard/examples/WizardFinished.tsx +18 -14
  116. package/src/components/Wizard/examples/WizardValidateOnButtonPress.tsx +20 -16
  117. package/src/demos/Card/Card.md +13 -8
  118. package/src/demos/Filters/FilterDemos.md +4 -2
  119. package/src/demos/Filters/examples/FilterAttributeSearch.tsx +20 -20
  120. package/src/demos/Filters/examples/FilterFaceted.tsx +19 -19
  121. package/src/demos/Filters/examples/FilterMixedSelectGroup.tsx +19 -19
  122. package/src/demos/Filters/examples/FilterSameSelectGroup.tsx +19 -19
  123. package/src/demos/Filters/examples/FilterSearchInput.tsx +18 -18
  124. package/src/demos/NotificationDrawer/NotificationDrawer.md +52 -39
  125. package/src/demos/examples/AlertGroup/AlertGroupToastWithNotificationDrawer.tsx +19 -17
  126. package/src/next/components/Wizard/examples/WizardValidateOnButtonPress.tsx +19 -15
  127. package/src/next/components/Wizard/examples/WizardWithSubmitProgress.tsx +18 -14
  128. package/components/EmptyState/EmptyStatePrimary.d.ts +0 -9
  129. package/components/EmptyState/EmptyStatePrimary.d.ts.map +0 -1
  130. package/components/EmptyState/EmptyStatePrimary.js +0 -9
  131. package/components/EmptyState/EmptyStatePrimary.js.map +0 -1
  132. package/components/EmptyState/EmptyStateSecondaryActions.d.ts +0 -9
  133. package/components/EmptyState/EmptyStateSecondaryActions.d.ts.map +0 -1
  134. package/components/EmptyState/EmptyStateSecondaryActions.js +0 -9
  135. package/components/EmptyState/EmptyStateSecondaryActions.js.map +0 -1
  136. package/dist/esm/components/EmptyState/EmptyStatePrimary.d.ts +0 -9
  137. package/dist/esm/components/EmptyState/EmptyStatePrimary.d.ts.map +0 -1
  138. package/dist/esm/components/EmptyState/EmptyStatePrimary.js +0 -9
  139. package/dist/esm/components/EmptyState/EmptyStatePrimary.js.map +0 -1
  140. package/dist/esm/components/EmptyState/EmptyStateSecondaryActions.d.ts +0 -9
  141. package/dist/esm/components/EmptyState/EmptyStateSecondaryActions.d.ts.map +0 -1
  142. package/dist/esm/components/EmptyState/EmptyStateSecondaryActions.js +0 -9
  143. package/dist/esm/components/EmptyState/EmptyStateSecondaryActions.js.map +0 -1
  144. package/dist/js/components/EmptyState/EmptyStatePrimary.d.ts +0 -9
  145. package/dist/js/components/EmptyState/EmptyStatePrimary.d.ts.map +0 -1
  146. package/dist/js/components/EmptyState/EmptyStatePrimary.js +0 -13
  147. package/dist/js/components/EmptyState/EmptyStatePrimary.js.map +0 -1
  148. package/dist/js/components/EmptyState/EmptyStateSecondaryActions.d.ts +0 -9
  149. package/dist/js/components/EmptyState/EmptyStateSecondaryActions.d.ts.map +0 -1
  150. package/dist/js/components/EmptyState/EmptyStateSecondaryActions.js +0 -13
  151. package/dist/js/components/EmptyState/EmptyStateSecondaryActions.js.map +0 -1
  152. package/src/components/EmptyState/EmptyStatePrimary.tsx +0 -20
  153. package/src/components/EmptyState/EmptyStateSecondaryActions.tsx +0 -18
  154. package/src/components/EmptyState/__tests__/Generated/EmptyStateSecondaryActions.test.tsx +0 -13
  155. package/src/components/EmptyState/__tests__/Generated/__snapshots__/EmptyStatePrimary.test.tsx.snap +0 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "5.0.0-alpha.32",
3
+ "version": "5.0.0-alpha.33",
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",
@@ -70,5 +70,5 @@
70
70
  "react": "^16.8 || ^17 || ^18",
71
71
  "react-dom": "^16.8 || ^17 || ^18"
72
72
  },
73
- "gitHead": "ae6e5dacc213505fbe7623395b6ca395ee853579"
73
+ "gitHead": "5d285a4ff66639a3bd8fcc4ecb1677c3847985a6"
74
74
  }
@@ -9,12 +9,13 @@ import {
9
9
  DualListSelectorControlsWrapper,
10
10
  DualListSelectorControl,
11
11
  SearchInput,
12
- Title,
13
12
  EmptyState,
14
13
  EmptyStateVariant,
15
- EmptyStateIcon,
14
+ EmptyStateHeader,
15
+ EmptyStateFooter,
16
16
  EmptyStateBody,
17
- EmptyStatePrimary
17
+ EmptyStateIcon,
18
+ EmptyStateActions
18
19
  } from '@patternfly/react-core';
19
20
  import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon';
20
21
  import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';
@@ -68,11 +69,11 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
68
69
  // callback for moving all options between lists
69
70
  const moveAll = (fromAvailable: boolean) => {
70
71
  if (fromAvailable) {
71
- setChosenOptions([...availableOptions.filter(option => option.isVisible), ...chosenOptions]);
72
- setAvailableOptions([...availableOptions.filter(option => !option.isVisible)]);
72
+ setChosenOptions([...availableOptions.filter((option) => option.isVisible), ...chosenOptions]);
73
+ setAvailableOptions([...availableOptions.filter((option) => !option.isVisible)]);
73
74
  } else {
74
- setAvailableOptions([...chosenOptions.filter(option => option.isVisible), ...availableOptions]);
75
- setChosenOptions([...chosenOptions.filter(option => !option.isVisible)]);
75
+ setAvailableOptions([...chosenOptions.filter((option) => option.isVisible), ...availableOptions]);
76
+ setChosenOptions([...chosenOptions.filter((option) => !option.isVisible)]);
76
77
  }
77
78
  };
78
79
 
@@ -96,7 +97,7 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
96
97
  const onFilterChange = (value: string, isAvailable: boolean) => {
97
98
  isAvailable ? setAvailableFilter(value) : setChosenFilter(value);
98
99
  const toFilter = isAvailable ? [...availableOptions] : [...chosenOptions];
99
- toFilter.forEach(option => {
100
+ toFilter.forEach((option) => {
100
101
  option.isVisible = value === '' || option.text.toLowerCase().includes(value.toLowerCase());
101
102
  });
102
103
  };
@@ -138,17 +139,16 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
138
139
  };
139
140
 
140
141
  const buildEmptyState = (isAvailable: boolean) => (
141
- <EmptyState variant={EmptyStateVariant.small}>
142
- <EmptyStateIcon icon={SearchIcon} />
143
- <Title headingLevel="h4" size="md">
144
- No results found
145
- </Title>
142
+ <EmptyState variant={EmptyStateVariant.sm}>
143
+ <EmptyStateHeader headingLevel="h4" titleText="No results found" icon={<EmptyStateIcon icon={SearchIcon} />} />
146
144
  <EmptyStateBody>No results match the filter criteria. Clear all filters and try again.</EmptyStateBody>
147
- <EmptyStatePrimary>
148
- <Button variant="link" onClick={() => onFilterChange('', isAvailable)}>
149
- Clear all filters
150
- </Button>
151
- </EmptyStatePrimary>
145
+ <EmptyStateFooter>
146
+ <EmptyStateActions>
147
+ <Button variant="link" onClick={() => onFilterChange('', isAvailable)}>
148
+ Clear all filters
149
+ </Button>
150
+ </EmptyStateActions>
151
+ </EmptyStateFooter>
152
152
  </EmptyState>
153
153
  );
154
154
 
@@ -156,17 +156,17 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
156
156
  <DualListSelector>
157
157
  <DualListSelectorPane
158
158
  title="Available"
159
- status={`${availableOptions.filter(option => option.selected && option.isVisible).length} of ${
160
- availableOptions.filter(option => option.isVisible).length
159
+ status={`${availableOptions.filter((option) => option.selected && option.isVisible).length} of ${
160
+ availableOptions.filter((option) => option.isVisible).length
161
161
  } options selected`}
162
162
  searchInput={buildSearchInput(true)}
163
163
  actions={[buildSort(true)]}
164
164
  listMinHeight="300px"
165
165
  >
166
166
  {availableFilter !== '' &&
167
- availableOptions.filter(option => option.isVisible).length === 0 &&
167
+ availableOptions.filter((option) => option.isVisible).length === 0 &&
168
168
  buildEmptyState(true)}
169
- {availableOptions.filter(option => option.isVisible).length > 0 && (
169
+ {availableOptions.filter((option) => option.isVisible).length > 0 && (
170
170
  <DualListSelectorList>
171
171
  {availableOptions.map((option, index) =>
172
172
  option.isVisible ? (
@@ -174,7 +174,7 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
174
174
  key={index}
175
175
  isSelected={option.selected}
176
176
  id={`composable-available-option-${index}`}
177
- onOptionSelect={e => onOptionSelect(e, index, false)}
177
+ onOptionSelect={(e) => onOptionSelect(e, index, false)}
178
178
  >
179
179
  {option.text}
180
180
  </DualListSelectorListItem>
@@ -185,7 +185,7 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
185
185
  </DualListSelectorPane>
186
186
  <DualListSelectorControlsWrapper>
187
187
  <DualListSelectorControl
188
- isDisabled={!availableOptions.some(option => option.selected)}
188
+ isDisabled={!availableOptions.some((option) => option.selected)}
189
189
  onClick={() => moveSelected(true)}
190
190
  aria-label="Add selected"
191
191
  tooltipContent="Add selected"
@@ -210,7 +210,7 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
210
210
  </DualListSelectorControl>
211
211
  <DualListSelectorControl
212
212
  onClick={() => moveSelected(false)}
213
- isDisabled={!chosenOptions.some(option => option.selected)}
213
+ isDisabled={!chosenOptions.some((option) => option.selected)}
214
214
  aria-label="Remove selected"
215
215
  tooltipContent="Remove selected"
216
216
  >
@@ -219,16 +219,18 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
219
219
  </DualListSelectorControlsWrapper>
220
220
  <DualListSelectorPane
221
221
  title="Chosen"
222
- status={`${chosenOptions.filter(option => option.selected && option.isVisible).length} of ${
223
- chosenOptions.filter(option => option.isVisible).length
222
+ status={`${chosenOptions.filter((option) => option.selected && option.isVisible).length} of ${
223
+ chosenOptions.filter((option) => option.isVisible).length
224
224
  } options selected`}
225
225
  searchInput={buildSearchInput(false)}
226
226
  actions={[buildSort(false)]}
227
227
  isChosen
228
228
  listMinHeight="300px"
229
229
  >
230
- {chosenFilter !== '' && chosenOptions.filter(option => option.isVisible).length === 0 && buildEmptyState(false)}
231
- {chosenOptions.filter(option => option.isVisible).length > 0 && (
230
+ {chosenFilter !== '' &&
231
+ chosenOptions.filter((option) => option.isVisible).length === 0 &&
232
+ buildEmptyState(false)}
233
+ {chosenOptions.filter((option) => option.isVisible).length > 0 && (
232
234
  <DualListSelectorList>
233
235
  {chosenOptions.map((option, index) =>
234
236
  option.isVisible ? (
@@ -236,7 +238,7 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
236
238
  key={index}
237
239
  isSelected={option.selected}
238
240
  id={`composable-chosen-option-${index}`}
239
- onOptionSelect={e => onOptionSelect(e, index, true)}
241
+ onOptionSelect={(e) => onOptionSelect(e, index, true)}
240
242
  >
241
243
  {option.text}
242
244
  </DualListSelectorListItem>
@@ -8,13 +8,14 @@ import {
8
8
  DualListSelectorTree,
9
9
  DualListSelectorTreeItemData,
10
10
  SearchInput,
11
- Title,
12
11
  Button,
13
12
  EmptyState,
14
13
  EmptyStateVariant,
15
- EmptyStateIcon,
14
+ EmptyStateHeader,
15
+ EmptyStateFooter,
16
16
  EmptyStateBody,
17
- EmptyStatePrimary
17
+ EmptyStateActions,
18
+ EmptyStateIcon
18
19
  } from '@patternfly/react-core';
19
20
  import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon';
20
21
  import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';
@@ -48,7 +49,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
48
49
  }
49
50
  textById[node.id] = node.text;
50
51
  if (node.children) {
51
- node.children.forEach(child => {
52
+ node.children.forEach((child) => {
52
53
  textById = { ...textById, ...buildTextById(child) };
53
54
  });
54
55
  }
@@ -61,7 +62,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
61
62
  return [node.id];
62
63
  } else {
63
64
  let childrenIds: string[] = [];
64
- node.children.forEach(child => {
65
+ node.children.forEach((child) => {
65
66
  childrenIds = [...childrenIds, ...getDescendantLeafIds(child)];
66
67
  });
67
68
  return childrenIds;
@@ -74,7 +75,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
74
75
  if (!node.children || !node.children.length) {
75
76
  leavesById[node.id] = [node.id];
76
77
  } else {
77
- node.children.forEach(child => {
78
+ node.children.forEach((child) => {
78
79
  leavesById[node.id] = getDescendantLeafIds(node);
79
80
  leavesById = { ...leavesById, ...getLeavesById(child) };
80
81
  });
@@ -87,7 +88,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
87
88
  let leavesById = {};
88
89
  let allLeaves: string[] = [];
89
90
  let nodeTexts = {};
90
- data.forEach(foodNode => {
91
+ data.forEach((foodNode) => {
91
92
  nodeTexts = { ...nodeTexts, ...buildTextById(foodNode) };
92
93
  leavesById = { ...leavesById, ...getLeavesById(foodNode) };
93
94
  allLeaves = [...allLeaves, ...getDescendantLeafIds(foodNode)];
@@ -101,17 +102,17 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
101
102
 
102
103
  const moveChecked = (toChosen: boolean) => {
103
104
  setChosenLeafIds(
104
- prevChosenIds =>
105
+ (prevChosenIds) =>
105
106
  toChosen
106
107
  ? [...prevChosenIds, ...checkedLeafIds] // add checked ids to chosen list
107
- : [...prevChosenIds.filter(x => !checkedLeafIds.includes(x))] // remove checked ids from chosen list
108
+ : [...prevChosenIds.filter((x) => !checkedLeafIds.includes(x))] // remove checked ids from chosen list
108
109
  );
109
110
 
110
111
  // uncheck checked ids that just moved
111
- setCheckedLeafIds(prevChecked =>
112
+ setCheckedLeafIds((prevChecked) =>
112
113
  toChosen
113
- ? [...prevChecked.filter(x => chosenLeafIds.includes(x))]
114
- : [...prevChecked.filter(x => !chosenLeafIds.includes(x))]
114
+ ? [...prevChecked.filter((x) => chosenLeafIds.includes(x))]
115
+ : [...prevChecked.filter((x) => !chosenLeafIds.includes(x))]
115
116
  );
116
117
  };
117
118
 
@@ -125,11 +126,11 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
125
126
 
126
127
  const areAllDescendantsSelected = (node: FoodNode, isChosen: boolean) =>
127
128
  memoizedLeavesById[node.id].every(
128
- id => checkedLeafIds.includes(id) && (isChosen ? chosenLeafIds.includes(id) : !chosenLeafIds.includes(id))
129
+ (id) => checkedLeafIds.includes(id) && (isChosen ? chosenLeafIds.includes(id) : !chosenLeafIds.includes(id))
129
130
  );
130
131
  const areSomeDescendantsSelected = (node: FoodNode, isChosen: boolean) =>
131
132
  memoizedLeavesById[node.id].some(
132
- id => checkedLeafIds.includes(id) && (isChosen ? chosenLeafIds.includes(id) : !chosenLeafIds.includes(id))
133
+ (id) => checkedLeafIds.includes(id) && (isChosen ? chosenLeafIds.includes(id) : !chosenLeafIds.includes(id))
133
134
  );
134
135
 
135
136
  const isNodeChecked = (node: FoodNode, isChosen: boolean) => {
@@ -148,7 +149,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
148
149
  node: DualListSelectorTreeItemData,
149
150
  isChosen: boolean
150
151
  ) => {
151
- const nodeIdsToCheck = memoizedLeavesById[node.id].filter(id =>
152
+ const nodeIdsToCheck = memoizedLeavesById[node.id].filter((id) =>
152
153
  isChosen
153
154
  ? chosenLeafIds.includes(id) && !hiddenChosen.includes(id)
154
155
  : !chosenLeafIds.includes(id) && !hiddenAvailable.includes(id)
@@ -158,15 +159,15 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
158
159
  } else {
159
160
  hiddenAvailable = [];
160
161
  }
161
- setCheckedLeafIds(prevChecked => {
162
- const otherCheckedNodeNames = prevChecked.filter(id => !nodeIdsToCheck.includes(id));
162
+ setCheckedLeafIds((prevChecked) => {
163
+ const otherCheckedNodeNames = prevChecked.filter((id) => !nodeIdsToCheck.includes(id));
163
164
  return !isChecked ? otherCheckedNodeNames : [...otherCheckedNodeNames, ...nodeIdsToCheck];
164
165
  });
165
166
  };
166
167
 
167
168
  // builds a search input - used in each dual list selector pane
168
169
  const buildSearchInput = (isChosen: boolean) => {
169
- const onChange = value => (isChosen ? setChosenFilter(value) : setAvailableFilter(value));
170
+ const onChange = (value) => (isChosen ? setChosenFilter(value) : setAvailableFilter(value));
170
171
 
171
172
  return (
172
173
  <SearchInput
@@ -192,11 +193,11 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
192
193
  const filterValue = isChosen ? chosenFilter : availableFilter;
193
194
  const descendentLeafIds = memoizedLeavesById[node.id];
194
195
  const descendentsOnThisPane = isChosen
195
- ? descendentLeafIds.filter(id => chosenLeafIds.includes(id))
196
- : descendentLeafIds.filter(id => !chosenLeafIds.includes(id));
196
+ ? descendentLeafIds.filter((id) => chosenLeafIds.includes(id))
197
+ : descendentLeafIds.filter((id) => !chosenLeafIds.includes(id));
197
198
 
198
199
  const hasMatchingChildren =
199
- filterValue && descendentsOnThisPane.some(id => memoizedNodeText[id].includes(filterValue));
200
+ filterValue && descendentsOnThisPane.some((id) => memoizedNodeText[id].includes(filterValue));
200
201
  const isFilterMatch = filterValue && node.text.includes(filterValue) && descendentsOnThisPane.length > 0;
201
202
 
202
203
  // A node is displayed if either of the following is true:
@@ -243,7 +244,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
243
244
  const buildPane = (isChosen: boolean): React.ReactNode => {
244
245
  const options: DualListSelectorTreeItemData[] = buildOptions(isChosen, data, false);
245
246
  const numOptions = isChosen ? chosenLeafIds.length : memoizedAllLeaves.length - chosenLeafIds.length;
246
- const numSelected = checkedLeafIds.filter(id =>
247
+ const numSelected = checkedLeafIds.filter((id) =>
247
248
  isChosen ? chosenLeafIds.includes(id) : !chosenLeafIds.includes(id)
248
249
  ).length;
249
250
  const status = `${numSelected} of ${numOptions} options selected`;
@@ -257,17 +258,20 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
257
258
  listMinHeight="300px"
258
259
  >
259
260
  {filterApplied && options.length === 0 && (
260
- <EmptyState variant={EmptyStateVariant.small}>
261
- <EmptyStateIcon icon={SearchIcon} />
262
- <Title headingLevel="h4" size="md">
263
- No results found
264
- </Title>
261
+ <EmptyState variant={EmptyStateVariant.sm}>
262
+ <EmptyStateHeader
263
+ headingLevel="h4"
264
+ titleText="No results found"
265
+ icon={<EmptyStateIcon icon={SearchIcon} />}
266
+ />
265
267
  <EmptyStateBody>No results match the filter criteria. Clear all filters and try again.</EmptyStateBody>
266
- <EmptyStatePrimary>
267
- <Button variant="link" onClick={() => (isChosen ? setChosenFilter('') : setAvailableFilter(''))}>
268
- Clear all filters
269
- </Button>
270
- </EmptyStatePrimary>
268
+ <EmptyStateFooter>
269
+ <EmptyStateActions>
270
+ <Button variant="link" onClick={() => (isChosen ? setChosenFilter('') : setAvailableFilter(''))}>
271
+ Clear all filters
272
+ </Button>
273
+ </EmptyStateActions>
274
+ </EmptyStateFooter>
271
275
  </EmptyState>
272
276
  )}
273
277
  {options.length > 0 && (
@@ -287,7 +291,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
287
291
  {buildPane(false)}
288
292
  <DualListSelectorControlsWrapper>
289
293
  <DualListSelectorControl
290
- isDisabled={!checkedLeafIds.filter(x => !chosenLeafIds.includes(x)).length}
294
+ isDisabled={!checkedLeafIds.filter((x) => !chosenLeafIds.includes(x)).length}
291
295
  onClick={() => moveChecked(true)}
292
296
  aria-label="Add selected"
293
297
  >
@@ -309,7 +313,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
309
313
  </DualListSelectorControl>
310
314
  <DualListSelectorControl
311
315
  onClick={() => moveChecked(false)}
312
- isDisabled={!checkedLeafIds.filter(x => !!chosenLeafIds.includes(x)).length}
316
+ isDisabled={!checkedLeafIds.filter((x) => !!chosenLeafIds.includes(x)).length}
313
317
  aria-label="Remove selected"
314
318
  >
315
319
  <AngleLeftIcon />
@@ -4,26 +4,26 @@ import styles from '@patternfly/react-styles/css/components/EmptyState/empty-sta
4
4
 
5
5
  export enum EmptyStateVariant {
6
6
  'xs' = 'xs',
7
- small = 'small',
8
- large = 'large',
7
+ sm = 'sm',
8
+ lg = 'lg',
9
9
  'xl' = 'xl',
10
10
  full = 'full'
11
11
  }
12
12
 
13
13
  export interface EmptyStateProps extends React.HTMLProps<HTMLDivElement> {
14
- /** Additional classes added to the EmptyState */
14
+ /** Additional classes added to the empty state */
15
15
  className?: string;
16
- /** Content rendered inside the EmptyState */
16
+ /** Content rendered inside the empty state */
17
17
  children: React.ReactNode;
18
- /** Modifies EmptyState max-width */
19
- variant?: 'xs' | 'small' | 'large' | 'xl' | 'full';
18
+ /** Modifies empty state max-width and sizes of icon, title and body */
19
+ variant?: 'xs' | 'sm' | 'lg' | 'xl' | 'full';
20
20
  /** Cause component to consume the available height of its container */
21
21
  isFullHeight?: boolean;
22
22
  }
23
23
 
24
24
  export const EmptyState: React.FunctionComponent<EmptyStateProps> = ({
25
25
  children,
26
- className = '',
26
+ className,
27
27
  variant = EmptyStateVariant.full,
28
28
  isFullHeight,
29
29
  ...props
@@ -32,8 +32,8 @@ export const EmptyState: React.FunctionComponent<EmptyStateProps> = ({
32
32
  className={css(
33
33
  styles.emptyState,
34
34
  variant === 'xs' && styles.modifiers.xs,
35
- variant === 'small' && styles.modifiers.sm,
36
- variant === 'large' && styles.modifiers.lg,
35
+ variant === 'sm' && styles.modifiers.sm,
36
+ variant === 'lg' && styles.modifiers.lg,
37
37
  variant === 'xl' && styles.modifiers.xl,
38
38
  isFullHeight && styles.modifiers.fullHeight,
39
39
  className
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import { css } from '@patternfly/react-styles';
3
+ import styles from "@patternfly/react-styles/css/components/EmptyState/empty-state";
4
+
5
+ export interface EmptyStateActionsProps extends React.HTMLProps<HTMLDivElement> {
6
+ /** Content rendered inside the empty state actions */
7
+ children?: React.ReactNode;
8
+ /** Additional classes added to the empty state actions */
9
+ className?: string;
10
+ }
11
+
12
+ export const EmptyStateActions: React.FunctionComponent<EmptyStateActionsProps> = ({
13
+ children,
14
+ className,
15
+ ...props
16
+ }: EmptyStateActionsProps) => (
17
+ <div className={css(styles.emptyStateActions, className)} {...props}>
18
+ {children}
19
+ </div>
20
+ );
21
+ EmptyStateActions.displayName = 'EmptyStateActions';
@@ -3,15 +3,15 @@ import { css } from '@patternfly/react-styles';
3
3
  import styles from '@patternfly/react-styles/css/components/EmptyState/empty-state';
4
4
 
5
5
  export interface EmptyStateBodyProps extends React.HTMLProps<HTMLDivElement> {
6
- /** Content rendered inside the EmptyState */
6
+ /** Content rendered inside the empty state body */
7
7
  children?: React.ReactNode;
8
- /** Additional classes added to the EmptyState */
8
+ /** Additional classes added to the empty state body */
9
9
  className?: string;
10
10
  }
11
11
 
12
12
  export const EmptyStateBody: React.FunctionComponent<EmptyStateBodyProps> = ({
13
13
  children,
14
- className = '',
14
+ className,
15
15
  ...props
16
16
  }: EmptyStateBodyProps) => (
17
17
  <div className={css(styles.emptyStateBody, className)} {...props}>
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import { css } from '@patternfly/react-styles';
3
+ import styles from '@patternfly/react-styles/css/components/EmptyState/empty-state';
4
+
5
+ export interface EmptyStateFooterProps extends React.HTMLProps<HTMLDivElement> {
6
+ /** Content rendered inside the empty state footer */
7
+ children?: React.ReactNode;
8
+ /** Additional classes added to the empty state footer */
9
+ className?: string;
10
+ }
11
+
12
+ export const EmptyStateFooter: React.FunctionComponent<EmptyStateFooterProps> = ({
13
+ children,
14
+ className,
15
+ ...props
16
+ }: EmptyStateFooterProps) => (
17
+ <div className={css(styles.emptyStateFooter, className)} {...props}>
18
+ {children}
19
+ </div>
20
+ );
21
+ EmptyStateFooter.displayName = 'EmptyStateFooter';
@@ -0,0 +1,42 @@
1
+ import * as React from 'react';
2
+ import { css } from '@patternfly/react-styles';
3
+ import styles from '@patternfly/react-styles/css/components/EmptyState/empty-state';
4
+ import { EmptyStateIconProps } from './EmptyStateIcon';
5
+
6
+ export interface EmptyStateHeaderProps extends React.HTMLProps<HTMLDivElement> {
7
+ /** Content rendered inside the empty state header, either in addition to or instead of the titleText prop */
8
+ children?: React.ReactNode;
9
+ /** Additional classes added to the empty state header */
10
+ className?: string;
11
+ /** Additional classes added to the title inside empty state header */
12
+ titleClassName?: string;
13
+ /** Text of the title inside empty state header, will be wrapped in headingLevel */
14
+ titleText?: React.ReactNode;
15
+ /** Empty state icon element to be rendered */
16
+ icon?: React.ReactElement<EmptyStateIconProps>;
17
+ /** The heading level to use, default is h1 */
18
+ headingLevel?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
19
+ }
20
+
21
+ export const EmptyStateHeader: React.FunctionComponent<EmptyStateHeaderProps> = ({
22
+ children,
23
+ className,
24
+ titleClassName,
25
+ titleText,
26
+ headingLevel: HeadingLevel = 'h1',
27
+ icon,
28
+ ...props
29
+ }: EmptyStateHeaderProps) => (
30
+ <div className={css('pf-c-empty-state__header', className)} {...props}>
31
+ {icon}
32
+ {(titleText || children) && (
33
+ <div className={css('pf-c-empty-state__title')}>
34
+ {titleText && (
35
+ <HeadingLevel className={css(styles.emptyStateTitleText, titleClassName)}>{titleText}</HeadingLevel>
36
+ )}
37
+ {children}
38
+ </div>
39
+ )}
40
+ </div>
41
+ );
42
+ EmptyStateHeader.displayName = 'EmptyStateHeader';
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { css } from '@patternfly/react-styles';
3
3
  import styles from '@patternfly/react-styles/css/components/EmptyState/empty-state';
4
+ import { Spinner } from '../Spinner';
4
5
 
5
6
  export interface IconProps extends Omit<React.HTMLProps<SVGElement>, 'size'> {
6
7
  /** Changes the color of the icon. */
@@ -8,31 +9,27 @@ export interface IconProps extends Omit<React.HTMLProps<SVGElement>, 'size'> {
8
9
  }
9
10
 
10
11
  export interface EmptyStateIconProps extends IconProps {
11
- /** Additional classes added to the EmptyState */
12
+ /** Additional classes added to the empty state icon */
12
13
  className?: string;
13
- /** Icon component to be rendered inside the EmptyState on icon variant
14
- * Usually a CheckCircleIcon, ExclamationCircleIcon, LockIcon, PlusCircleIcon, RocketIcon
15
- * SearchIcon, or WrenchIcon */
16
- icon?: React.ComponentType<any>;
17
- /** Component to be rendered inside the EmptyState on container variant */
18
- component?: React.ComponentType<any>;
19
- /** Adds empty state icon variant styles */
20
- variant?: 'icon' | 'container';
14
+ /** Icon component to be rendered. Can also be a spinner component */
15
+ icon: React.ComponentType<any>;
21
16
  }
22
17
 
18
+ const isSpinner = (icon: React.ReactElement<any>) => icon.type === Spinner;
19
+
23
20
  export const EmptyStateIcon: React.FunctionComponent<EmptyStateIconProps> = ({
24
- className = '',
21
+ className,
25
22
  icon: IconComponent,
26
- component: AnyComponent,
27
- variant = 'icon',
23
+ color,
28
24
  ...props
29
25
  }: EmptyStateIconProps) => {
30
- const classNames = css(styles.emptyStateIcon, className);
31
- return variant === 'icon' ? (
32
- <IconComponent className={classNames} {...props} aria-hidden="true" />
33
- ) : (
34
- <div className={classNames}>
35
- <AnyComponent />
26
+ const iconIsSpinner = isSpinner(<IconComponent />);
27
+ return (
28
+ <div
29
+ className={css(styles.emptyStateIcon)}
30
+ {...(color && !iconIsSpinner && { style: { ['--pf-c-empty-state__icon--Color']: color } as React.CSSProperties })}
31
+ >
32
+ <IconComponent className={className} aria-hidden={!iconIsSpinner} {...props} />
36
33
  </div>
37
34
  );
38
35
  };