@patternfly/react-core 4.202.17 → 4.202.20

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 (95) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/esm/components/CalendarMonth/CalendarMonth.d.ts.map +1 -1
  3. package/dist/esm/components/CalendarMonth/CalendarMonth.js +12 -4
  4. package/dist/esm/components/CalendarMonth/CalendarMonth.js.map +1 -1
  5. package/dist/esm/components/NumberInput/NumberInput.d.ts +2 -0
  6. package/dist/esm/components/NumberInput/NumberInput.d.ts.map +1 -1
  7. package/dist/esm/components/NumberInput/NumberInput.js +2 -2
  8. package/dist/esm/components/NumberInput/NumberInput.js.map +1 -1
  9. package/dist/js/components/CalendarMonth/CalendarMonth.d.ts.map +1 -1
  10. package/dist/js/components/CalendarMonth/CalendarMonth.js +12 -4
  11. package/dist/js/components/CalendarMonth/CalendarMonth.js.map +1 -1
  12. package/dist/js/components/NumberInput/NumberInput.d.ts +2 -0
  13. package/dist/js/components/NumberInput/NumberInput.d.ts.map +1 -1
  14. package/dist/js/components/NumberInput/NumberInput.js +2 -2
  15. package/dist/js/components/NumberInput/NumberInput.js.map +1 -1
  16. package/dist/umd/react-core.js +14 -6
  17. package/dist/umd/react-core.min.js +2 -2
  18. package/package.json +5 -5
  19. package/src/components/CalendarMonth/CalendarMonth.tsx +10 -4
  20. package/src/components/CalendarMonth/examples/CalendarMonth.md +9 -0
  21. package/src/components/CalendarMonth/examples/CalendarMonthDateRange.tsx +10 -0
  22. package/src/components/ContextSelector/examples/ContextSelector.md +3 -279
  23. package/src/components/ContextSelector/examples/ContextSelectorBasic.tsx +84 -0
  24. package/src/components/ContextSelector/examples/ContextSelectorPlainText.tsx +85 -0
  25. package/src/components/ContextSelector/examples/ContextSelectorWithFooter.tsx +91 -0
  26. package/src/components/DescriptionList/examples/DescriptionList.md +22 -930
  27. package/src/components/DescriptionList/examples/DescriptionListAutoFitBasic.tsx +40 -0
  28. package/src/components/DescriptionList/examples/DescriptionListAutoFitMinWidthModified.tsx +40 -0
  29. package/src/components/DescriptionList/examples/DescriptionListAutoFitMinWidthResponsive.tsx +40 -0
  30. package/src/components/DescriptionList/examples/DescriptionListBasic.tsx +40 -0
  31. package/src/components/DescriptionList/examples/DescriptionListColumnFill.tsx +42 -0
  32. package/src/components/DescriptionList/examples/DescriptionListCompact.tsx +40 -0
  33. package/src/components/DescriptionList/examples/DescriptionListCompactHorizontal.tsx +40 -0
  34. package/src/components/DescriptionList/examples/DescriptionListDefaultAutoColumn.tsx +40 -0
  35. package/src/components/DescriptionList/examples/DescriptionListDefaultInlineGrid.tsx +40 -0
  36. package/src/components/DescriptionList/examples/DescriptionListDefaultResponsiveColumns.tsx +40 -0
  37. package/src/components/DescriptionList/examples/DescriptionListDefaultThreeColLg.tsx +40 -0
  38. package/src/components/DescriptionList/examples/DescriptionListDefaultTwoCol.tsx +44 -0
  39. package/src/components/DescriptionList/examples/DescriptionListFluidHorizontal.tsx +40 -0
  40. package/src/components/DescriptionList/examples/DescriptionListHorizontal.tsx +40 -0
  41. package/src/components/DescriptionList/examples/DescriptionListHorizontalAutoColumn.tsx +40 -0
  42. package/src/components/DescriptionList/examples/DescriptionListHorizontalCustomTermWidth.tsx +50 -0
  43. package/src/components/DescriptionList/examples/DescriptionListHorizontalResponsiveColumns.tsx +40 -0
  44. package/src/components/DescriptionList/examples/DescriptionListHorizontalThreeColLg.tsx +40 -0
  45. package/src/components/DescriptionList/examples/DescriptionListHorizontalTwoCol.tsx +40 -0
  46. package/src/components/DescriptionList/examples/DescriptionListIconsOnTerms.tsx +45 -0
  47. package/src/components/DescriptionList/examples/DescriptionListResponsiveHoriVertGroup.tsx +48 -0
  48. package/src/components/DescriptionList/examples/DescriptionListWithTermHelpText.tsx +62 -0
  49. package/src/components/Divider/examples/Divider.md +15 -68
  50. package/src/components/Divider/examples/DividerInsetMedium.tsx +4 -0
  51. package/src/components/Divider/examples/DividerInsetVariousBreakpoints.tsx +13 -0
  52. package/src/components/Divider/examples/DividerUsingDiv.tsx +4 -0
  53. package/src/components/Divider/examples/DividerUsingHr.tsx +4 -0
  54. package/src/components/Divider/examples/DividerUsingLi.tsx +10 -0
  55. package/src/components/Divider/examples/DividerVerticalFlex.tsx +10 -0
  56. package/src/components/Divider/examples/DividerVerticalFlexInsetMedium.tsx +10 -0
  57. package/src/components/Divider/examples/DividerVerticalFlexInsetVariousBreakpoints.tsx +18 -0
  58. package/src/components/FormSelect/__tests__/FormSelect.test.tsx +0 -1
  59. package/src/components/List/__tests__/List.test.tsx +33 -33
  60. package/src/components/List/__tests__/__snapshots__/List.test.tsx.snap +33 -64
  61. package/src/components/Menu/__tests__/Menu.test.tsx +37 -33
  62. package/src/components/Menu/__tests__/__snapshots__/Menu.test.tsx.snap +3 -36
  63. package/src/components/Modal/__tests__/Modal.test.tsx +65 -67
  64. package/src/components/Modal/__tests__/ModalBoxCloseButton.test.tsx +13 -10
  65. package/src/components/Nav/__tests__/Nav.test.tsx +185 -214
  66. package/src/components/Nav/__tests__/__snapshots__/Nav.test.tsx.snap +877 -1729
  67. package/src/components/NotificationDrawer/__tests__/NotificationDrawer.test.tsx +13 -15
  68. package/src/components/NotificationDrawer/__tests__/NotificationDrawerBody.test.tsx +13 -15
  69. package/src/components/NotificationDrawer/__tests__/NotificationDrawerGroup.test.tsx +21 -27
  70. package/src/components/NotificationDrawer/__tests__/NotificationDrawerGroupList.test.tsx +13 -15
  71. package/src/components/NotificationDrawer/__tests__/NotificationDrawerHeader.test.tsx +25 -27
  72. package/src/components/NotificationDrawer/__tests__/NotificationDrawerList.test.tsx +17 -19
  73. package/src/components/NotificationDrawer/__tests__/NotificationDrawerListItem.test.tsx +20 -27
  74. package/src/components/NotificationDrawer/__tests__/NotificationDrawerListItemBody.test.tsx +17 -13
  75. package/src/components/NotificationDrawer/__tests__/NotificationDrawerListItemHeader.test.tsx +30 -25
  76. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawer.test.tsx.snap +3 -5
  77. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerBody.test.tsx.snap +3 -5
  78. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerGroup.test.tsx.snap +9 -11
  79. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerGroupList.test.tsx.snap +3 -5
  80. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerHeader.test.tsx.snap +16 -18
  81. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerList.test.tsx.snap +7 -8
  82. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItem.test.tsx.snap +3 -5
  83. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItemBody.test.tsx.snap +6 -8
  84. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItemHeader.test.tsx.snap +12 -14
  85. package/src/components/NumberInput/NumberInput.tsx +4 -0
  86. package/src/components/NumberInput/examples/NumberInput.md +8 -0
  87. package/src/components/OverflowMenu/__tests__/OverflowMenu.test.tsx +15 -12
  88. package/src/components/OverflowMenu/__tests__/OverflowMenuControl.test.tsx +9 -8
  89. package/src/components/OverflowMenu/__tests__/OverflowMenuGroup.test.tsx +17 -18
  90. package/src/components/OverflowMenu/__tests__/OverflowMenuItem.test.tsx +10 -9
  91. package/src/components/OverflowMenu/__tests__/__snapshots__/OverflowMenu.test.tsx.snap +6 -16
  92. package/src/components/OverflowMenu/__tests__/__snapshots__/OverflowMenuControl.test.tsx.snap +3 -15
  93. package/src/components/OverflowMenu/__tests__/__snapshots__/OverflowMenuItem.test.tsx.snap +3 -17
  94. package/src/components/Modal/__tests__/__snapshots__/ModalBoxCloseButton.test.tsx.snap +0 -16
  95. 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.17",
3
+ "version": "4.202.20",
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.17",
38
- "@patternfly/react-styles": "^4.52.17",
39
- "@patternfly/react-tokens": "^4.54.17",
37
+ "@patternfly/react-icons": "^4.53.20",
38
+ "@patternfly/react-styles": "^4.52.20",
39
+ "@patternfly/react-tokens": "^4.54.20",
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": "5b271e203e018bbeb24b5a854f155e06062c446b"
63
+ "gitHead": "d42bba5cd0c58e77d18fa60638804f9c6b21de94"
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
- focusedDate = today;
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) && isHoveredDateValid) {
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
- ```js
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
- ```js
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
+ };