@patternfly/react-core 5.0.0-alpha.31 → 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.
- package/CHANGELOG.md +18 -0
- package/components/Alert/Alert.d.ts +0 -2
- package/components/Alert/Alert.d.ts.map +1 -1
- package/components/Alert/Alert.js +2 -6
- package/components/Alert/Alert.js.map +1 -1
- package/components/EmptyState/EmptyState.d.ts +6 -6
- package/components/EmptyState/EmptyState.d.ts.map +1 -1
- package/components/EmptyState/EmptyState.js +4 -4
- package/components/EmptyState/EmptyState.js.map +1 -1
- package/components/EmptyState/EmptyStateActions.d.ts +9 -0
- package/components/EmptyState/EmptyStateActions.d.ts.map +1 -0
- package/components/EmptyState/EmptyStateActions.js +10 -0
- package/components/EmptyState/EmptyStateActions.js.map +1 -0
- package/components/EmptyState/EmptyStateBody.d.ts +2 -2
- package/components/EmptyState/EmptyStateBody.d.ts.map +1 -1
- package/components/EmptyState/EmptyStateBody.js +1 -1
- package/components/EmptyState/EmptyStateBody.js.map +1 -1
- package/components/EmptyState/EmptyStateFooter.d.ts +9 -0
- package/components/EmptyState/EmptyStateFooter.d.ts.map +1 -0
- package/components/EmptyState/EmptyStateFooter.js +10 -0
- package/components/EmptyState/EmptyStateFooter.js.map +1 -0
- package/components/EmptyState/EmptyStateHeader.d.ts +18 -0
- package/components/EmptyState/EmptyStateHeader.d.ts.map +1 -0
- package/components/EmptyState/EmptyStateHeader.js +14 -0
- package/components/EmptyState/EmptyStateHeader.js.map +1 -0
- package/components/EmptyState/EmptyStateIcon.d.ts +3 -9
- package/components/EmptyState/EmptyStateIcon.d.ts.map +1 -1
- package/components/EmptyState/EmptyStateIcon.js +6 -4
- package/components/EmptyState/EmptyStateIcon.js.map +1 -1
- package/components/EmptyState/index.d.ts +4 -3
- package/components/EmptyState/index.d.ts.map +1 -1
- package/components/EmptyState/index.js +4 -3
- package/components/EmptyState/index.js.map +1 -1
- package/dist/esm/components/Alert/Alert.d.ts +0 -2
- package/dist/esm/components/Alert/Alert.d.ts.map +1 -1
- package/dist/esm/components/Alert/Alert.js +2 -6
- package/dist/esm/components/Alert/Alert.js.map +1 -1
- package/dist/esm/components/EmptyState/EmptyState.d.ts +6 -6
- package/dist/esm/components/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/esm/components/EmptyState/EmptyState.js +4 -4
- package/dist/esm/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/esm/components/EmptyState/EmptyStateActions.d.ts +9 -0
- package/dist/esm/components/EmptyState/EmptyStateActions.d.ts.map +1 -0
- package/dist/esm/components/EmptyState/EmptyStateActions.js +10 -0
- package/dist/esm/components/EmptyState/EmptyStateActions.js.map +1 -0
- package/dist/esm/components/EmptyState/EmptyStateBody.d.ts +2 -2
- package/dist/esm/components/EmptyState/EmptyStateBody.d.ts.map +1 -1
- package/dist/esm/components/EmptyState/EmptyStateBody.js +1 -1
- package/dist/esm/components/EmptyState/EmptyStateBody.js.map +1 -1
- package/dist/esm/components/EmptyState/EmptyStateFooter.d.ts +9 -0
- package/dist/esm/components/EmptyState/EmptyStateFooter.d.ts.map +1 -0
- package/dist/esm/components/EmptyState/EmptyStateFooter.js +10 -0
- package/dist/esm/components/EmptyState/EmptyStateFooter.js.map +1 -0
- package/dist/esm/components/EmptyState/EmptyStateHeader.d.ts +18 -0
- package/dist/esm/components/EmptyState/EmptyStateHeader.d.ts.map +1 -0
- package/dist/esm/components/EmptyState/EmptyStateHeader.js +14 -0
- package/dist/esm/components/EmptyState/EmptyStateHeader.js.map +1 -0
- package/dist/esm/components/EmptyState/EmptyStateIcon.d.ts +3 -9
- package/dist/esm/components/EmptyState/EmptyStateIcon.d.ts.map +1 -1
- package/dist/esm/components/EmptyState/EmptyStateIcon.js +6 -4
- package/dist/esm/components/EmptyState/EmptyStateIcon.js.map +1 -1
- package/dist/esm/components/EmptyState/index.d.ts +4 -3
- package/dist/esm/components/EmptyState/index.d.ts.map +1 -1
- package/dist/esm/components/EmptyState/index.js +4 -3
- package/dist/esm/components/EmptyState/index.js.map +1 -1
- package/dist/js/components/Alert/Alert.d.ts +0 -2
- package/dist/js/components/Alert/Alert.d.ts.map +1 -1
- package/dist/js/components/Alert/Alert.js +2 -6
- package/dist/js/components/Alert/Alert.js.map +1 -1
- package/dist/js/components/EmptyState/EmptyState.d.ts +6 -6
- package/dist/js/components/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/js/components/EmptyState/EmptyState.js +4 -4
- package/dist/js/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/js/components/EmptyState/EmptyStateActions.d.ts +9 -0
- package/dist/js/components/EmptyState/EmptyStateActions.d.ts.map +1 -0
- package/dist/js/components/EmptyState/EmptyStateActions.js +14 -0
- package/dist/js/components/EmptyState/EmptyStateActions.js.map +1 -0
- package/dist/js/components/EmptyState/EmptyStateBody.d.ts +2 -2
- package/dist/js/components/EmptyState/EmptyStateBody.d.ts.map +1 -1
- package/dist/js/components/EmptyState/EmptyStateBody.js +1 -1
- package/dist/js/components/EmptyState/EmptyStateBody.js.map +1 -1
- package/dist/js/components/EmptyState/EmptyStateFooter.d.ts +9 -0
- package/dist/js/components/EmptyState/EmptyStateFooter.d.ts.map +1 -0
- package/dist/js/components/EmptyState/EmptyStateFooter.js +14 -0
- package/dist/js/components/EmptyState/EmptyStateFooter.js.map +1 -0
- package/dist/js/components/EmptyState/EmptyStateHeader.d.ts +18 -0
- package/dist/js/components/EmptyState/EmptyStateHeader.d.ts.map +1 -0
- package/dist/js/components/EmptyState/EmptyStateHeader.js +18 -0
- package/dist/js/components/EmptyState/EmptyStateHeader.js.map +1 -0
- package/dist/js/components/EmptyState/EmptyStateIcon.d.ts +3 -9
- package/dist/js/components/EmptyState/EmptyStateIcon.d.ts.map +1 -1
- package/dist/js/components/EmptyState/EmptyStateIcon.js +6 -4
- package/dist/js/components/EmptyState/EmptyStateIcon.js.map +1 -1
- package/dist/js/components/EmptyState/index.d.ts +4 -3
- package/dist/js/components/EmptyState/index.d.ts.map +1 -1
- package/dist/js/components/EmptyState/index.js +4 -3
- package/dist/js/components/EmptyState/index.js.map +1 -1
- package/dist/umd/react-core.min.js +1 -1
- package/package.json +2 -2
- package/src/components/Alert/Alert.tsx +1 -10
- package/src/components/Alert/__tests__/Alert.test.tsx +2 -2
- package/src/components/DualListSelector/examples/DualListSelectorComposable.tsx +32 -30
- package/src/components/DualListSelector/examples/DualListSelectorComposableTree.tsx +38 -34
- package/src/components/EmptyState/EmptyState.tsx +9 -9
- package/src/components/EmptyState/EmptyStateActions.tsx +21 -0
- package/src/components/EmptyState/EmptyStateBody.tsx +3 -3
- package/src/components/EmptyState/EmptyStateFooter.tsx +21 -0
- package/src/components/EmptyState/EmptyStateHeader.tsx +42 -0
- package/src/components/EmptyState/EmptyStateIcon.tsx +15 -18
- package/src/components/EmptyState/__tests__/EmptyState.test.tsx +53 -60
- package/src/components/EmptyState/__tests__/Generated/{EmptyStatePrimary.test.tsx → EmptyStateActions.test.tsx} +3 -3
- package/src/components/EmptyState/__tests__/Generated/EmptyStateIcon.test.tsx +3 -6
- package/src/components/EmptyState/__tests__/Generated/__snapshots__/{EmptyStateSecondaryActions.test.tsx.snap → EmptyStateActions.test.tsx.snap} +2 -2
- package/src/components/EmptyState/__tests__/Generated/__snapshots__/EmptyStateIcon.test.tsx.snap +41 -22
- package/src/components/EmptyState/__tests__/__snapshots__/EmptyState.test.tsx.snap +115 -56
- package/src/components/EmptyState/examples/EmptyState.md +7 -3
- package/src/components/EmptyState/examples/EmptyStateBasic.tsx +20 -18
- package/src/components/EmptyState/examples/EmptyStateCustomIconColor.tsx +17 -0
- package/src/components/EmptyState/examples/EmptyStateExtraLarge.tsx +20 -18
- package/src/components/EmptyState/examples/EmptyStateExtraSmall.tsx +16 -15
- package/src/components/EmptyState/examples/EmptyStateLarge.tsx +21 -19
- package/src/components/EmptyState/examples/EmptyStateNoMatchFound.tsx +15 -8
- package/src/components/EmptyState/examples/EmptyStateSmall.tsx +21 -19
- package/src/components/EmptyState/examples/EmptyStateSpinner.tsx +2 -5
- package/src/components/EmptyState/index.ts +4 -3
- package/src/components/NotificationDrawer/examples/NotificationDrawerGroups.tsx +15 -11
- package/src/components/NotificationDrawer/examples/NotificationDrawerLightweight.tsx +14 -10
- package/src/components/Wizard/examples/Wizard.md +1 -1
- package/src/components/Wizard/examples/WizardFinished.tsx +18 -14
- package/src/components/Wizard/examples/WizardValidateOnButtonPress.tsx +20 -16
- package/src/demos/Card/Card.md +13 -8
- package/src/demos/Filters/FilterDemos.md +4 -2
- package/src/demos/Filters/examples/FilterAttributeSearch.tsx +20 -20
- package/src/demos/Filters/examples/FilterFaceted.tsx +19 -19
- package/src/demos/Filters/examples/FilterMixedSelectGroup.tsx +19 -19
- package/src/demos/Filters/examples/FilterSameSelectGroup.tsx +19 -19
- package/src/demos/Filters/examples/FilterSearchInput.tsx +18 -18
- package/src/demos/NotificationDrawer/NotificationDrawer.md +52 -39
- package/src/demos/examples/AlertGroup/AlertGroupToastWithNotificationDrawer.tsx +19 -17
- package/src/next/components/Wizard/examples/WizardValidateOnButtonPress.tsx +19 -15
- package/src/next/components/Wizard/examples/WizardWithSubmitProgress.tsx +18 -14
- package/components/EmptyState/EmptyStatePrimary.d.ts +0 -9
- package/components/EmptyState/EmptyStatePrimary.d.ts.map +0 -1
- package/components/EmptyState/EmptyStatePrimary.js +0 -9
- package/components/EmptyState/EmptyStatePrimary.js.map +0 -1
- package/components/EmptyState/EmptyStateSecondaryActions.d.ts +0 -9
- package/components/EmptyState/EmptyStateSecondaryActions.d.ts.map +0 -1
- package/components/EmptyState/EmptyStateSecondaryActions.js +0 -9
- package/components/EmptyState/EmptyStateSecondaryActions.js.map +0 -1
- package/dist/esm/components/EmptyState/EmptyStatePrimary.d.ts +0 -9
- package/dist/esm/components/EmptyState/EmptyStatePrimary.d.ts.map +0 -1
- package/dist/esm/components/EmptyState/EmptyStatePrimary.js +0 -9
- package/dist/esm/components/EmptyState/EmptyStatePrimary.js.map +0 -1
- package/dist/esm/components/EmptyState/EmptyStateSecondaryActions.d.ts +0 -9
- package/dist/esm/components/EmptyState/EmptyStateSecondaryActions.d.ts.map +0 -1
- package/dist/esm/components/EmptyState/EmptyStateSecondaryActions.js +0 -9
- package/dist/esm/components/EmptyState/EmptyStateSecondaryActions.js.map +0 -1
- package/dist/js/components/EmptyState/EmptyStatePrimary.d.ts +0 -9
- package/dist/js/components/EmptyState/EmptyStatePrimary.d.ts.map +0 -1
- package/dist/js/components/EmptyState/EmptyStatePrimary.js +0 -13
- package/dist/js/components/EmptyState/EmptyStatePrimary.js.map +0 -1
- package/dist/js/components/EmptyState/EmptyStateSecondaryActions.d.ts +0 -9
- package/dist/js/components/EmptyState/EmptyStateSecondaryActions.d.ts.map +0 -1
- package/dist/js/components/EmptyState/EmptyStateSecondaryActions.js +0 -13
- package/dist/js/components/EmptyState/EmptyStateSecondaryActions.js.map +0 -1
- package/src/components/EmptyState/EmptyStatePrimary.tsx +0 -20
- package/src/components/EmptyState/EmptyStateSecondaryActions.tsx +0 -18
- package/src/components/EmptyState/__tests__/Generated/EmptyStateSecondaryActions.test.tsx +0 -13
- 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.
|
|
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": "
|
|
73
|
+
"gitHead": "5d285a4ff66639a3bd8fcc4ecb1677c3847985a6"
|
|
74
74
|
}
|
|
@@ -55,8 +55,6 @@ export interface AlertProps extends Omit<React.HTMLProps<HTMLDivElement>, 'actio
|
|
|
55
55
|
timeoutAnimation?: number;
|
|
56
56
|
/** Title of the alert. */
|
|
57
57
|
title: React.ReactNode;
|
|
58
|
-
/** @deprecated Sets the heading level to use for the alert title. Default is h4. */
|
|
59
|
-
titleHeadingLevel?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
60
58
|
/** Sets the element to use as the alert title. Default is h4. */
|
|
61
59
|
component?: keyof JSX.IntrinsicElements;
|
|
62
60
|
/** Adds accessible text to the alert toggle. */
|
|
@@ -98,7 +96,6 @@ export const Alert: React.FunctionComponent<AlertProps> = ({
|
|
|
98
96
|
actionClose,
|
|
99
97
|
actionLinks,
|
|
100
98
|
title,
|
|
101
|
-
titleHeadingLevel,
|
|
102
99
|
component = 'h4',
|
|
103
100
|
children = '',
|
|
104
101
|
className = '',
|
|
@@ -126,13 +123,7 @@ export const Alert: React.FunctionComponent<AlertProps> = ({
|
|
|
126
123
|
);
|
|
127
124
|
|
|
128
125
|
const titleRef = React.useRef(null);
|
|
129
|
-
const TitleComponent =
|
|
130
|
-
if (titleHeadingLevel !== undefined) {
|
|
131
|
-
// eslint-disable-next-line no-console
|
|
132
|
-
console.warn(
|
|
133
|
-
'Alert: titleHeadingLevel is deprecated, please use the newer component prop instead to set the alert title element.'
|
|
134
|
-
);
|
|
135
|
-
}
|
|
126
|
+
const TitleComponent = component as any;
|
|
136
127
|
|
|
137
128
|
const divRef = React.useRef<HTMLDivElement>();
|
|
138
129
|
const [isTooltipVisible, setIsTooltipVisible] = useState(false);
|
|
@@ -179,9 +179,9 @@ test('Renders the title as an h4 by default', () => {
|
|
|
179
179
|
expect(screen.getByRole('heading', { level: 4, name: 'Default alert: Some title' })).toBeVisible();
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
-
test('Renders the title as other heading levels when one is passed using
|
|
182
|
+
test('Renders the title as other heading levels when one is passed using component', () => {
|
|
183
183
|
render(
|
|
184
|
-
<Alert title="Some title"
|
|
184
|
+
<Alert title="Some title" component="h1">
|
|
185
185
|
Some alert
|
|
186
186
|
</Alert>
|
|
187
187
|
);
|
|
@@ -9,12 +9,13 @@ import {
|
|
|
9
9
|
DualListSelectorControlsWrapper,
|
|
10
10
|
DualListSelectorControl,
|
|
11
11
|
SearchInput,
|
|
12
|
-
Title,
|
|
13
12
|
EmptyState,
|
|
14
13
|
EmptyStateVariant,
|
|
15
|
-
|
|
14
|
+
EmptyStateHeader,
|
|
15
|
+
EmptyStateFooter,
|
|
16
16
|
EmptyStateBody,
|
|
17
|
-
|
|
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.
|
|
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
|
-
<
|
|
148
|
-
<
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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 !== '' &&
|
|
231
|
-
|
|
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
|
-
|
|
14
|
+
EmptyStateHeader,
|
|
15
|
+
EmptyStateFooter,
|
|
16
16
|
EmptyStateBody,
|
|
17
|
-
|
|
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.
|
|
261
|
-
<
|
|
262
|
-
|
|
263
|
-
No results found
|
|
264
|
-
|
|
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
|
-
<
|
|
267
|
-
<
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
-
|
|
8
|
-
|
|
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
|
|
14
|
+
/** Additional classes added to the empty state */
|
|
15
15
|
className?: string;
|
|
16
|
-
/** Content rendered inside the
|
|
16
|
+
/** Content rendered inside the empty state */
|
|
17
17
|
children: React.ReactNode;
|
|
18
|
-
/** Modifies
|
|
19
|
-
variant?: 'xs' | '
|
|
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 === '
|
|
36
|
-
variant === '
|
|
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
|
|
6
|
+
/** Content rendered inside the empty state body */
|
|
7
7
|
children?: React.ReactNode;
|
|
8
|
-
/** Additional classes added to the
|
|
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
|
|
12
|
+
/** Additional classes added to the empty state icon */
|
|
12
13
|
className?: string;
|
|
13
|
-
/** Icon component to be rendered
|
|
14
|
-
|
|
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
|
-
|
|
27
|
-
variant = 'icon',
|
|
23
|
+
color,
|
|
28
24
|
...props
|
|
29
25
|
}: EmptyStateIconProps) => {
|
|
30
|
-
const
|
|
31
|
-
return
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
};
|