@patternfly/react-core 4.202.16 → 4.202.19
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 +24 -0
- package/dist/esm/components/CalendarMonth/CalendarMonth.d.ts.map +1 -1
- package/dist/esm/components/CalendarMonth/CalendarMonth.js +12 -4
- package/dist/esm/components/CalendarMonth/CalendarMonth.js.map +1 -1
- package/dist/js/components/CalendarMonth/CalendarMonth.d.ts.map +1 -1
- package/dist/js/components/CalendarMonth/CalendarMonth.js +12 -4
- package/dist/js/components/CalendarMonth/CalendarMonth.js.map +1 -1
- package/dist/umd/react-core.js +12 -4
- package/dist/umd/react-core.min.css +460 -460
- package/dist/umd/react-core.min.js +1 -1
- package/package.json +5 -5
- package/src/components/CalendarMonth/CalendarMonth.tsx +10 -4
- package/src/components/CalendarMonth/examples/CalendarMonth.md +9 -0
- package/src/components/CalendarMonth/examples/CalendarMonthDateRange.tsx +10 -0
- package/src/components/ContextSelector/examples/ContextSelector.md +3 -279
- package/src/components/ContextSelector/examples/ContextSelectorBasic.tsx +84 -0
- package/src/components/ContextSelector/examples/ContextSelectorPlainText.tsx +85 -0
- package/src/components/ContextSelector/examples/ContextSelectorWithFooter.tsx +91 -0
- package/src/components/DescriptionList/examples/DescriptionList.md +22 -930
- package/src/components/DescriptionList/examples/DescriptionListAutoFitBasic.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListAutoFitMinWidthModified.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListAutoFitMinWidthResponsive.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListBasic.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListColumnFill.tsx +42 -0
- package/src/components/DescriptionList/examples/DescriptionListCompact.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListCompactHorizontal.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListDefaultAutoColumn.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListDefaultInlineGrid.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListDefaultResponsiveColumns.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListDefaultThreeColLg.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListDefaultTwoCol.tsx +44 -0
- package/src/components/DescriptionList/examples/DescriptionListFluidHorizontal.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListHorizontal.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListHorizontalAutoColumn.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListHorizontalCustomTermWidth.tsx +50 -0
- package/src/components/DescriptionList/examples/DescriptionListHorizontalResponsiveColumns.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListHorizontalThreeColLg.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListHorizontalTwoCol.tsx +40 -0
- package/src/components/DescriptionList/examples/DescriptionListIconsOnTerms.tsx +45 -0
- package/src/components/DescriptionList/examples/DescriptionListResponsiveHoriVertGroup.tsx +48 -0
- package/src/components/DescriptionList/examples/DescriptionListWithTermHelpText.tsx +62 -0
- package/src/components/Divider/examples/Divider.md +15 -68
- package/src/components/Divider/examples/DividerInsetMedium.tsx +4 -0
- package/src/components/Divider/examples/DividerInsetVariousBreakpoints.tsx +13 -0
- package/src/components/Divider/examples/DividerUsingDiv.tsx +4 -0
- package/src/components/Divider/examples/DividerUsingHr.tsx +4 -0
- package/src/components/Divider/examples/DividerUsingLi.tsx +10 -0
- package/src/components/Divider/examples/DividerVerticalFlex.tsx +10 -0
- package/src/components/Divider/examples/DividerVerticalFlexInsetMedium.tsx +10 -0
- package/src/components/Divider/examples/DividerVerticalFlexInsetVariousBreakpoints.tsx +18 -0
- package/src/components/FormSelect/__tests__/FormSelect.test.tsx +0 -1
- package/src/components/List/__tests__/List.test.tsx +33 -33
- package/src/components/List/__tests__/__snapshots__/List.test.tsx.snap +33 -64
- package/src/components/Menu/__tests__/Menu.test.tsx +37 -33
- package/src/components/Menu/__tests__/__snapshots__/Menu.test.tsx.snap +3 -36
- package/src/components/Modal/__tests__/Modal.test.tsx +65 -67
- package/src/components/Modal/__tests__/ModalBoxCloseButton.test.tsx +13 -10
- package/src/components/Nav/__tests__/Nav.test.tsx +185 -214
- package/src/components/Nav/__tests__/__snapshots__/Nav.test.tsx.snap +877 -1729
- package/src/components/NotificationDrawer/__tests__/NotificationDrawer.test.tsx +13 -15
- package/src/components/NotificationDrawer/__tests__/NotificationDrawerBody.test.tsx +13 -15
- package/src/components/NotificationDrawer/__tests__/NotificationDrawerGroup.test.tsx +21 -27
- package/src/components/NotificationDrawer/__tests__/NotificationDrawerGroupList.test.tsx +13 -15
- package/src/components/NotificationDrawer/__tests__/NotificationDrawerHeader.test.tsx +25 -27
- package/src/components/NotificationDrawer/__tests__/NotificationDrawerList.test.tsx +17 -19
- package/src/components/NotificationDrawer/__tests__/NotificationDrawerListItem.test.tsx +20 -27
- package/src/components/NotificationDrawer/__tests__/NotificationDrawerListItemBody.test.tsx +17 -13
- package/src/components/NotificationDrawer/__tests__/NotificationDrawerListItemHeader.test.tsx +30 -25
- package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawer.test.tsx.snap +3 -5
- package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerBody.test.tsx.snap +3 -5
- package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerGroup.test.tsx.snap +9 -11
- package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerGroupList.test.tsx.snap +3 -5
- package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerHeader.test.tsx.snap +16 -18
- package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerList.test.tsx.snap +7 -8
- package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItem.test.tsx.snap +3 -5
- package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItemBody.test.tsx.snap +6 -8
- package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItemHeader.test.tsx.snap +12 -14
- package/src/components/OverflowMenu/__tests__/OverflowMenu.test.tsx +15 -12
- package/src/components/OverflowMenu/__tests__/OverflowMenuControl.test.tsx +9 -8
- package/src/components/OverflowMenu/__tests__/OverflowMenuGroup.test.tsx +17 -18
- package/src/components/OverflowMenu/__tests__/OverflowMenuItem.test.tsx +10 -9
- package/src/components/OverflowMenu/__tests__/__snapshots__/OverflowMenu.test.tsx.snap +6 -16
- package/src/components/OverflowMenu/__tests__/__snapshots__/OverflowMenuControl.test.tsx.snap +3 -15
- package/src/components/OverflowMenu/__tests__/__snapshots__/OverflowMenuItem.test.tsx.snap +3 -17
- package/src/components/Modal/__tests__/__snapshots__/ModalBoxCloseButton.test.tsx.snap +0 -16
- package/src/components/OverflowMenu/__tests__/__snapshots__/OverflowMenuGroup.test.tsx.snap +0 -33
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "4.202.
|
|
3
|
+
"version": "4.202.19",
|
|
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",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"generate": "node scripts/copyStyles.js"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@patternfly/react-icons": "^4.53.
|
|
38
|
-
"@patternfly/react-styles": "^4.52.
|
|
39
|
-
"@patternfly/react-tokens": "^4.54.
|
|
37
|
+
"@patternfly/react-icons": "^4.53.19",
|
|
38
|
+
"@patternfly/react-styles": "^4.52.19",
|
|
39
|
+
"@patternfly/react-tokens": "^4.54.19",
|
|
40
40
|
"focus-trap": "6.2.2",
|
|
41
41
|
"react-dropzone": "9.0.0",
|
|
42
42
|
"tippy.js": "5.1.2",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"react": "^16.8.0 || ^17.0.0",
|
|
61
61
|
"react-dom": "^16.8.0 || ^17.0.0"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "9e9d16ac392a83a7141cd1720079d46bc6bd796b"
|
|
64
64
|
}
|
|
@@ -113,7 +113,11 @@ export const CalendarMonth = ({
|
|
|
113
113
|
// eslint-disable-next-line prefer-const
|
|
114
114
|
let [focusedDate, setFocusedDate] = React.useState(new Date(dateProp));
|
|
115
115
|
if (!isValidDate(focusedDate)) {
|
|
116
|
-
|
|
116
|
+
if (isValidDate(rangeStart)) {
|
|
117
|
+
focusedDate = rangeStart;
|
|
118
|
+
} else {
|
|
119
|
+
focusedDate = today;
|
|
120
|
+
}
|
|
117
121
|
}
|
|
118
122
|
const [hoveredDate, setHoveredDate] = React.useState(new Date(focusedDate));
|
|
119
123
|
const focusRef = React.useRef<HTMLButtonElement>();
|
|
@@ -279,13 +283,15 @@ export const CalendarMonth = ({
|
|
|
279
283
|
const isSelected = isValidDate(dateProp) && isSameDate(date, dateProp);
|
|
280
284
|
const isFocused = isSameDate(date, focusedDate);
|
|
281
285
|
const isAdjacentMonth = date.getMonth() !== focusedDate.getMonth();
|
|
286
|
+
const isRangeStart = isValidDate(rangeStart) && isSameDate(date, rangeStart);
|
|
282
287
|
let isInRange = false;
|
|
283
|
-
let isRangeStart = false;
|
|
284
288
|
let isRangeEnd = false;
|
|
285
|
-
if (isValidDate(rangeStart) &&
|
|
289
|
+
if (isValidDate(rangeStart) && isValidDate(dateProp)) {
|
|
290
|
+
isInRange = date > rangeStart && date < dateProp;
|
|
291
|
+
isRangeEnd = isSameDate(date, dateProp);
|
|
292
|
+
} else if (isValidDate(rangeStart) && isHoveredDateValid) {
|
|
286
293
|
if (hoveredDate > rangeStart || isSameDate(hoveredDate, rangeStart)) {
|
|
287
294
|
isInRange = date > rangeStart && date < hoveredDate;
|
|
288
|
-
isRangeStart = isSameDate(date, rangeStart);
|
|
289
295
|
isRangeEnd = isSameDate(date, hoveredDate);
|
|
290
296
|
}
|
|
291
297
|
// Don't handle focused dates before start dates for now.
|
|
@@ -17,3 +17,12 @@ beta: true
|
|
|
17
17
|
|
|
18
18
|
```ts file="./CalendarMonthSelectableDate.tsx"
|
|
19
19
|
```
|
|
20
|
+
|
|
21
|
+
### Date range
|
|
22
|
+
|
|
23
|
+
In this example, there are 2 dates selected: a range start date (via the `rangeStart` prop) and a range end date (via the `date` prop). Additionally, any dates prior to the range start date are disabled by passing in an array of functions to the `validators` prop. In this case a single function is passed in, which checks whether a date is greater than or equal to the range start date.
|
|
24
|
+
|
|
25
|
+
For this example, these dates are static and cannot be updated. For an interactive demo, see our [Date picker demos](https://www.patternfly.org/v4/components/date-picker/react-demos).
|
|
26
|
+
|
|
27
|
+
```ts file="./CalendarMonthDateRange.tsx"
|
|
28
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CalendarMonth } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const CalendarMonthDateRange: React.FunctionComponent = () => {
|
|
5
|
+
const startDate = new Date(2020, 10, 11);
|
|
6
|
+
const endDate = new Date(2020, 10, 24);
|
|
7
|
+
const disablePreStartDates = (date: Date) => date >= startDate;
|
|
8
|
+
|
|
9
|
+
return <CalendarMonth validators={[disablePreStartDates]} date={endDate} rangeStart={startDate} />;
|
|
10
|
+
};
|
|
@@ -10,291 +10,15 @@ ouia: true
|
|
|
10
10
|
|
|
11
11
|
### Basic
|
|
12
12
|
|
|
13
|
-
```
|
|
14
|
-
import React from 'react';
|
|
15
|
-
import { Button, ContextSelector, ContextSelectorItem, ContextSelectorFooter } from '@patternfly/react-core';
|
|
16
|
-
|
|
17
|
-
class SimpleContextSelector extends React.Component {
|
|
18
|
-
constructor(props) {
|
|
19
|
-
super(props);
|
|
20
|
-
this.items = [
|
|
21
|
-
{
|
|
22
|
-
text: 'Link',
|
|
23
|
-
href: '#'
|
|
24
|
-
},
|
|
25
|
-
'Action',
|
|
26
|
-
{
|
|
27
|
-
text: 'Disabled link',
|
|
28
|
-
href: '#',
|
|
29
|
-
isDisabled: true
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
text: 'Disabled action',
|
|
33
|
-
isDisabled: true
|
|
34
|
-
},
|
|
35
|
-
'My project',
|
|
36
|
-
'OpenShift cluster',
|
|
37
|
-
'Production Ansible',
|
|
38
|
-
'AWS',
|
|
39
|
-
'Azure',
|
|
40
|
-
'My project 2',
|
|
41
|
-
'OpenShift cluster ',
|
|
42
|
-
'Production Ansible 2 ',
|
|
43
|
-
'AWS 2',
|
|
44
|
-
'Azure 2'
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
this.state = {
|
|
48
|
-
isOpen: false,
|
|
49
|
-
selected: this.items[0].text || this.items[0],
|
|
50
|
-
searchValue: '',
|
|
51
|
-
filteredItems: this.items
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
this.onToggle = (event, isOpen) => {
|
|
55
|
-
this.setState({
|
|
56
|
-
isOpen
|
|
57
|
-
});
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
this.onSelect = (event, value) => {
|
|
61
|
-
this.setState({
|
|
62
|
-
selected: value,
|
|
63
|
-
isOpen: !this.state.isOpen
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
this.onSearchInputChange = value => {
|
|
68
|
-
this.setState({ searchValue: value });
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
this.onSearchButtonClick = event => {
|
|
72
|
-
const filtered =
|
|
73
|
-
this.state.searchValue === ''
|
|
74
|
-
? this.items
|
|
75
|
-
: this.items.filter(item => {
|
|
76
|
-
const str = item.text ? item.text : item;
|
|
77
|
-
return str.toLowerCase().indexOf(this.state.searchValue.toLowerCase()) !== -1;
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
this.setState({ filteredItems: filtered || [] });
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
render() {
|
|
85
|
-
const { isOpen, selected, searchValue, filteredItems } = this.state;
|
|
86
|
-
return (
|
|
87
|
-
<ContextSelector
|
|
88
|
-
toggleText={selected}
|
|
89
|
-
onSearchInputChange={this.onSearchInputChange}
|
|
90
|
-
isOpen={isOpen}
|
|
91
|
-
searchInputValue={searchValue}
|
|
92
|
-
onToggle={this.onToggle}
|
|
93
|
-
onSelect={this.onSelect}
|
|
94
|
-
onSearchButtonClick={this.onSearchButtonClick}
|
|
95
|
-
screenReaderLabel="Selected Project:"
|
|
96
|
-
>
|
|
97
|
-
{filteredItems.map((item, index) => {
|
|
98
|
-
const { text = null, href = null, isDisabled } = item;
|
|
99
|
-
return (<ContextSelectorItem key={index} href={href} isDisabled={isDisabled}>{text || item}</ContextSelectorItem>);
|
|
100
|
-
})}
|
|
101
|
-
</ContextSelector>
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
13
|
+
```ts file="./ContextSelectorBasic.tsx"
|
|
105
14
|
```
|
|
106
15
|
|
|
107
16
|
### Plain with text
|
|
108
17
|
|
|
109
|
-
```ts
|
|
110
|
-
import React from 'react';
|
|
111
|
-
import { ContextSelector, ContextSelectorItem } from '@patternfly/react-core';
|
|
112
|
-
|
|
113
|
-
interface Item {
|
|
114
|
-
text: string;
|
|
115
|
-
href?: string;
|
|
116
|
-
isDisabled?: boolean;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const items = [
|
|
120
|
-
{
|
|
121
|
-
text: 'Link',
|
|
122
|
-
href: '#'
|
|
123
|
-
},
|
|
124
|
-
'Action',
|
|
125
|
-
{
|
|
126
|
-
text: 'Disabled link',
|
|
127
|
-
href: '#',
|
|
128
|
-
isDisabled: true
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
text: 'Disabled action',
|
|
132
|
-
isDisabled: true
|
|
133
|
-
},
|
|
134
|
-
'My Project',
|
|
135
|
-
'OpenShift Cluster',
|
|
136
|
-
'Production Ansible',
|
|
137
|
-
'AWS',
|
|
138
|
-
'Azure',
|
|
139
|
-
'My Project 2',
|
|
140
|
-
'OpenShift Cluster ',
|
|
141
|
-
'Production Ansible 2 ',
|
|
142
|
-
'AWS 2',
|
|
143
|
-
'Azure 2'
|
|
144
|
-
];
|
|
145
|
-
|
|
146
|
-
const PlainTextContextSelector: React.FunctionComponent = () => {
|
|
147
|
-
const firstItemText = typeof items[0] === 'string' ? items[0] : items[0].text;
|
|
148
|
-
const [isOpen, setOpen] = React.useState(false);
|
|
149
|
-
const [selected, setSelected] = React.useState(firstItemText);
|
|
150
|
-
const [searchValue, setSearchValue] = React.useState('');
|
|
151
|
-
const [filteredItems, setFilteredItems] = React.useState(items);
|
|
152
|
-
|
|
153
|
-
function onToggle(event: any, isOpen: boolean) {
|
|
154
|
-
setOpen(isOpen);
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
function onSelect(event: any, value: string) {
|
|
158
|
-
setSelected(value);
|
|
159
|
-
setOpen(!isOpen);
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
function onSearchInputChange(value: string) {
|
|
163
|
-
setSearchValue(value);
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
function onSearchButtonClick(event: React.SyntheticEvent<HTMLButtonElement>) {
|
|
167
|
-
const filtered =
|
|
168
|
-
searchValue === ''
|
|
169
|
-
? items
|
|
170
|
-
: items.filter(item => {
|
|
171
|
-
const str = (typeof item === 'string') ? item : item.text;
|
|
172
|
-
return str.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1;
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
setFilteredItems(filtered || []);
|
|
176
|
-
};
|
|
177
|
-
return (
|
|
178
|
-
<ContextSelector
|
|
179
|
-
toggleText={selected}
|
|
180
|
-
onSearchInputChange={onSearchInputChange}
|
|
181
|
-
isOpen={isOpen}
|
|
182
|
-
searchInputValue={searchValue}
|
|
183
|
-
onToggle={onToggle}
|
|
184
|
-
onSelect={onSelect}
|
|
185
|
-
onSearchButtonClick={onSearchButtonClick}
|
|
186
|
-
screenReaderLabel="Selected Project:"
|
|
187
|
-
isPlain
|
|
188
|
-
isText
|
|
189
|
-
>
|
|
190
|
-
{filteredItems.map((item, index) => {
|
|
191
|
-
const [text, href = null, isDisabled = false] = (typeof item === 'string')
|
|
192
|
-
? [item, null, false]
|
|
193
|
-
: [item.text, item.href, item.isDisabled];
|
|
194
|
-
return <ContextSelectorItem key={index} href={href} isDisabled={isDisabled}>{text}</ContextSelectorItem>;
|
|
195
|
-
})}
|
|
196
|
-
</ContextSelector>
|
|
197
|
-
);
|
|
198
|
-
};
|
|
18
|
+
```ts file="./ContextSelectorPlainText.tsx"
|
|
199
19
|
```
|
|
200
20
|
|
|
201
21
|
### With footer
|
|
202
22
|
|
|
203
|
-
```
|
|
204
|
-
import React from 'react';
|
|
205
|
-
import { Button, ContextSelector, ContextSelectorItem, ContextSelectorFooter } from '@patternfly/react-core';
|
|
206
|
-
|
|
207
|
-
class FooterContextSelector extends React.Component {
|
|
208
|
-
constructor(props) {
|
|
209
|
-
super(props);
|
|
210
|
-
this.items = [
|
|
211
|
-
{
|
|
212
|
-
text: 'Link',
|
|
213
|
-
href: '#'
|
|
214
|
-
},
|
|
215
|
-
'Action',
|
|
216
|
-
{
|
|
217
|
-
text: 'Disabled link',
|
|
218
|
-
href: '#',
|
|
219
|
-
isDisabled: true
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
text: 'Disabled action',
|
|
223
|
-
isDisabled: true
|
|
224
|
-
},
|
|
225
|
-
'My project',
|
|
226
|
-
'OpenShift cluster',
|
|
227
|
-
'Production Ansible',
|
|
228
|
-
'AWS',
|
|
229
|
-
'Azure',
|
|
230
|
-
'My project 2',
|
|
231
|
-
'OpenShift cluster ',
|
|
232
|
-
'Production Ansible 2 ',
|
|
233
|
-
'AWS 2',
|
|
234
|
-
'Azure 2'
|
|
235
|
-
];
|
|
236
|
-
|
|
237
|
-
this.state = {
|
|
238
|
-
isOpen: false,
|
|
239
|
-
selected: this.items[0].text || this.items[0],
|
|
240
|
-
searchValue: '',
|
|
241
|
-
filteredItems: this.items
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
this.onToggle = (event, isOpen) => {
|
|
245
|
-
this.setState({
|
|
246
|
-
isOpen
|
|
247
|
-
});
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
this.onSelect = (event, value) => {
|
|
251
|
-
this.setState({
|
|
252
|
-
selected: value,
|
|
253
|
-
isOpen: !this.state.isOpen
|
|
254
|
-
});
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
this.onSearchInputChange = value => {
|
|
258
|
-
this.setState({ searchValue: value });
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
this.onSearchButtonClick = event => {
|
|
262
|
-
const filtered =
|
|
263
|
-
this.state.searchValue === ''
|
|
264
|
-
? this.items
|
|
265
|
-
: this.items.filter(item => {
|
|
266
|
-
const str = item.text ? item.text : item;
|
|
267
|
-
return str.toLowerCase().indexOf(this.state.searchValue.toLowerCase()) !== -1;
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
this.setState({ filteredItems: filtered || [] });
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
render() {
|
|
275
|
-
const { isOpen, selected, searchValue, filteredItems } = this.state;
|
|
276
|
-
return (
|
|
277
|
-
<ContextSelector
|
|
278
|
-
toggleText={selected}
|
|
279
|
-
onSearchInputChange={this.onSearchInputChange}
|
|
280
|
-
isOpen={isOpen}
|
|
281
|
-
searchInputValue={searchValue}
|
|
282
|
-
onToggle={this.onToggle}
|
|
283
|
-
onSelect={this.onSelect}
|
|
284
|
-
onSearchButtonClick={this.onSearchButtonClick}
|
|
285
|
-
screenReaderLabel="Selected Project:"
|
|
286
|
-
footer={
|
|
287
|
-
<ContextSelectorFooter>
|
|
288
|
-
<Button variant="link" isInline>Footer action</Button>
|
|
289
|
-
</ContextSelectorFooter>
|
|
290
|
-
}
|
|
291
|
-
>
|
|
292
|
-
{filteredItems.map((item, index) => {
|
|
293
|
-
const { text = null, href = null, isDisabled } = item;
|
|
294
|
-
return (<ContextSelectorItem key={index} href={href} isDisabled={isDisabled}>{text || item}</ContextSelectorItem>);
|
|
295
|
-
})}
|
|
296
|
-
</ContextSelector>
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
23
|
+
```ts file="./ContextSelectorWithFooter.tsx"
|
|
300
24
|
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ContextSelector, ContextSelectorItem } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const ContextSelectorBasic: React.FunctionComponent = () => {
|
|
5
|
+
const items = [
|
|
6
|
+
{
|
|
7
|
+
text: 'Link',
|
|
8
|
+
href: '#'
|
|
9
|
+
},
|
|
10
|
+
'Action',
|
|
11
|
+
{
|
|
12
|
+
text: 'Disabled link',
|
|
13
|
+
href: '#',
|
|
14
|
+
isDisabled: true
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
text: 'Disabled action',
|
|
18
|
+
isDisabled: true
|
|
19
|
+
},
|
|
20
|
+
'My project',
|
|
21
|
+
'OpenShift cluster',
|
|
22
|
+
'Production Ansible',
|
|
23
|
+
'AWS',
|
|
24
|
+
'Azure',
|
|
25
|
+
'My project 2',
|
|
26
|
+
'OpenShift cluster ',
|
|
27
|
+
'Production Ansible 2 ',
|
|
28
|
+
'AWS 2',
|
|
29
|
+
'Azure 2'
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const firstItemText = typeof items[0] === 'string' ? items[0] : items[0].text;
|
|
33
|
+
const [isOpen, setOpen] = React.useState(false);
|
|
34
|
+
const [selected, setSelected] = React.useState(firstItemText);
|
|
35
|
+
const [searchValue, setSearchValue] = React.useState('');
|
|
36
|
+
const [filteredItems, setFilteredItems] = React.useState(items);
|
|
37
|
+
|
|
38
|
+
const onToggle = (event: any, isOpen: boolean) => {
|
|
39
|
+
setOpen(isOpen);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const onSelect = (event: any, value: React.ReactNode) => {
|
|
43
|
+
setSelected(value as string);
|
|
44
|
+
setOpen(!isOpen);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const onSearchInputChange = (value: string) => {
|
|
48
|
+
setSearchValue(value);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const onSearchButtonClick = (_event: React.SyntheticEvent<HTMLButtonElement>) => {
|
|
52
|
+
const filtered =
|
|
53
|
+
searchValue === ''
|
|
54
|
+
? items
|
|
55
|
+
: items.filter(item => {
|
|
56
|
+
const str = typeof item === 'string' ? item : item.text;
|
|
57
|
+
return str.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1;
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
setFilteredItems(filtered || []);
|
|
61
|
+
};
|
|
62
|
+
return (
|
|
63
|
+
<ContextSelector
|
|
64
|
+
toggleText={selected}
|
|
65
|
+
onSearchInputChange={onSearchInputChange}
|
|
66
|
+
isOpen={isOpen}
|
|
67
|
+
searchInputValue={searchValue}
|
|
68
|
+
onToggle={onToggle}
|
|
69
|
+
onSelect={onSelect}
|
|
70
|
+
onSearchButtonClick={onSearchButtonClick}
|
|
71
|
+
screenReaderLabel="Selected Project:"
|
|
72
|
+
>
|
|
73
|
+
{filteredItems.map((item, index) => {
|
|
74
|
+
const [text = null, href = null, isDisabled] =
|
|
75
|
+
typeof item === 'string' ? [item, null, false] : [item.text, item.href, item.isDisabled];
|
|
76
|
+
return (
|
|
77
|
+
<ContextSelectorItem key={index} href={href} isDisabled={isDisabled}>
|
|
78
|
+
{text || item}
|
|
79
|
+
</ContextSelectorItem>
|
|
80
|
+
);
|
|
81
|
+
})}
|
|
82
|
+
</ContextSelector>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ContextSelector, ContextSelectorItem } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
const items = [
|
|
5
|
+
{
|
|
6
|
+
text: 'Link',
|
|
7
|
+
href: '#'
|
|
8
|
+
},
|
|
9
|
+
'Action',
|
|
10
|
+
{
|
|
11
|
+
text: 'Disabled link',
|
|
12
|
+
href: '#',
|
|
13
|
+
isDisabled: true
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
text: 'Disabled action',
|
|
17
|
+
isDisabled: true
|
|
18
|
+
},
|
|
19
|
+
'My Project',
|
|
20
|
+
'OpenShift Cluster',
|
|
21
|
+
'Production Ansible',
|
|
22
|
+
'AWS',
|
|
23
|
+
'Azure',
|
|
24
|
+
'My Project 2',
|
|
25
|
+
'OpenShift Cluster ',
|
|
26
|
+
'Production Ansible 2 ',
|
|
27
|
+
'AWS 2',
|
|
28
|
+
'Azure 2'
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
export const ContextSelectorPlainText: React.FunctionComponent = () => {
|
|
32
|
+
const firstItemText = typeof items[0] === 'string' ? items[0] : items[0].text;
|
|
33
|
+
const [isOpen, setOpen] = React.useState(false);
|
|
34
|
+
const [selected, setSelected] = React.useState(firstItemText);
|
|
35
|
+
const [searchValue, setSearchValue] = React.useState('');
|
|
36
|
+
const [filteredItems, setFilteredItems] = React.useState(items);
|
|
37
|
+
const onToggle = (event: any, isOpen: boolean) => {
|
|
38
|
+
setOpen(isOpen);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const onSelect = (event: any, value: React.ReactNode) => {
|
|
42
|
+
setSelected(value as string);
|
|
43
|
+
setOpen(!isOpen);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const onSearchInputChange = (value: string) => {
|
|
47
|
+
setSearchValue(value);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const onSearchButtonClick = (_event: React.SyntheticEvent<HTMLButtonElement>) => {
|
|
51
|
+
const filtered =
|
|
52
|
+
searchValue === ''
|
|
53
|
+
? items
|
|
54
|
+
: items.filter(item => {
|
|
55
|
+
const str = typeof item === 'string' ? item : item.text;
|
|
56
|
+
return str.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
setFilteredItems(filtered || []);
|
|
60
|
+
};
|
|
61
|
+
return (
|
|
62
|
+
<ContextSelector
|
|
63
|
+
toggleText={selected}
|
|
64
|
+
onSearchInputChange={onSearchInputChange}
|
|
65
|
+
isOpen={isOpen}
|
|
66
|
+
searchInputValue={searchValue}
|
|
67
|
+
onToggle={onToggle}
|
|
68
|
+
onSelect={onSelect}
|
|
69
|
+
onSearchButtonClick={onSearchButtonClick}
|
|
70
|
+
screenReaderLabel="Selected Project:"
|
|
71
|
+
isPlain
|
|
72
|
+
isText
|
|
73
|
+
>
|
|
74
|
+
{filteredItems.map((item, index) => {
|
|
75
|
+
const [text, href = null, isDisabled = false] =
|
|
76
|
+
typeof item === 'string' ? [item, null, false] : [item.text, item.href, item.isDisabled];
|
|
77
|
+
return (
|
|
78
|
+
<ContextSelectorItem key={index} href={href} isDisabled={isDisabled}>
|
|
79
|
+
{text}
|
|
80
|
+
</ContextSelectorItem>
|
|
81
|
+
);
|
|
82
|
+
})}
|
|
83
|
+
</ContextSelector>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button, ContextSelector, ContextSelectorItem, ContextSelectorFooter } from '@patternfly/react-core';
|
|
3
|
+
|
|
4
|
+
export const ContextSelectorWithFooter: React.FunctionComponent = () => {
|
|
5
|
+
const items = [
|
|
6
|
+
{
|
|
7
|
+
text: 'Link',
|
|
8
|
+
href: '#'
|
|
9
|
+
},
|
|
10
|
+
'Action',
|
|
11
|
+
{
|
|
12
|
+
text: 'Disabled link',
|
|
13
|
+
href: '#',
|
|
14
|
+
isDisabled: true
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
text: 'Disabled action',
|
|
18
|
+
isDisabled: true
|
|
19
|
+
},
|
|
20
|
+
'My project',
|
|
21
|
+
'OpenShift cluster',
|
|
22
|
+
'Production Ansible',
|
|
23
|
+
'AWS',
|
|
24
|
+
'Azure',
|
|
25
|
+
'My project 2',
|
|
26
|
+
'OpenShift cluster ',
|
|
27
|
+
'Production Ansible 2 ',
|
|
28
|
+
'AWS 2',
|
|
29
|
+
'Azure 2'
|
|
30
|
+
];
|
|
31
|
+
const firstItemText = typeof items[0] === 'string' ? items[0] : items[0].text;
|
|
32
|
+
const [isOpen, setOpen] = React.useState(false);
|
|
33
|
+
const [selected, setSelected] = React.useState(firstItemText);
|
|
34
|
+
const [searchValue, setSearchValue] = React.useState('');
|
|
35
|
+
const [filteredItems, setFilteredItems] = React.useState(items);
|
|
36
|
+
|
|
37
|
+
const onToggle = (event: any, isOpen: boolean) => {
|
|
38
|
+
setOpen(isOpen);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const onSelect = (event: any, value: React.ReactNode) => {
|
|
42
|
+
setSelected(value as string);
|
|
43
|
+
setOpen(!isOpen);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const onSearchInputChange = (value: string) => {
|
|
47
|
+
setSearchValue(value);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const onSearchButtonClick = (_event: React.SyntheticEvent<HTMLButtonElement>) => {
|
|
51
|
+
const filtered =
|
|
52
|
+
searchValue === ''
|
|
53
|
+
? items
|
|
54
|
+
: items.filter(item => {
|
|
55
|
+
const str = typeof item === 'string' ? item : item.text;
|
|
56
|
+
return str.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
setFilteredItems(filtered || []);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<ContextSelector
|
|
64
|
+
toggleText={selected}
|
|
65
|
+
onSearchInputChange={onSearchInputChange}
|
|
66
|
+
isOpen={isOpen}
|
|
67
|
+
searchInputValue={searchValue}
|
|
68
|
+
onToggle={onToggle}
|
|
69
|
+
onSelect={onSelect}
|
|
70
|
+
onSearchButtonClick={onSearchButtonClick}
|
|
71
|
+
screenReaderLabel="Selected Project:"
|
|
72
|
+
footer={
|
|
73
|
+
<ContextSelectorFooter>
|
|
74
|
+
<Button variant="link" isInline>
|
|
75
|
+
Footer action
|
|
76
|
+
</Button>
|
|
77
|
+
</ContextSelectorFooter>
|
|
78
|
+
}
|
|
79
|
+
>
|
|
80
|
+
{filteredItems.map((item, index) => {
|
|
81
|
+
const [text = null, href = null, isDisabled] =
|
|
82
|
+
typeof item === 'string' ? [item, null, false] : [item.text, item.href, item.isDisabled];
|
|
83
|
+
return (
|
|
84
|
+
<ContextSelectorItem key={index} href={href} isDisabled={isDisabled}>
|
|
85
|
+
{text || item}
|
|
86
|
+
</ContextSelectorItem>
|
|
87
|
+
);
|
|
88
|
+
})}
|
|
89
|
+
</ContextSelector>
|
|
90
|
+
);
|
|
91
|
+
};
|