@patternfly/react-core 4.250.3 → 4.250.5

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 (28) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/esm/components/Select/Select.d.ts +2 -0
  3. package/dist/esm/components/Select/Select.d.ts.map +1 -1
  4. package/dist/esm/components/Select/Select.js +10 -3
  5. package/dist/esm/components/Select/Select.js.map +1 -1
  6. package/dist/esm/next/components/Dropdown/Dropdown.d.ts +3 -1
  7. package/dist/esm/next/components/Dropdown/Dropdown.d.ts.map +1 -1
  8. package/dist/esm/next/components/Dropdown/Dropdown.js +4 -3
  9. package/dist/esm/next/components/Dropdown/Dropdown.js.map +1 -1
  10. package/dist/js/components/Select/Select.d.ts +2 -0
  11. package/dist/js/components/Select/Select.d.ts.map +1 -1
  12. package/dist/js/components/Select/Select.js +10 -3
  13. package/dist/js/components/Select/Select.js.map +1 -1
  14. package/dist/js/next/components/Dropdown/Dropdown.d.ts +3 -1
  15. package/dist/js/next/components/Dropdown/Dropdown.d.ts.map +1 -1
  16. package/dist/js/next/components/Dropdown/Dropdown.js +4 -4
  17. package/dist/js/next/components/Dropdown/Dropdown.js.map +1 -1
  18. package/dist/umd/react-core.min.css +359 -359
  19. package/dist/umd/react-core.min.js +1 -1
  20. package/package.json +2 -2
  21. package/src/components/Select/Select.tsx +12 -1
  22. package/src/components/Select/__tests__/Select.test.tsx +32 -0
  23. package/src/components/Select/examples/Select.md +17 -0
  24. package/src/next/components/Dropdown/Dropdown.tsx +9 -2
  25. package/src/next/components/Dropdown/examples/DropdownBasic.tsx +0 -2
  26. package/src/next/components/Dropdown/examples/DropdownWithDescriptions.tsx +0 -2
  27. package/src/next/components/Dropdown/examples/DropdownWithGroups.tsx +0 -2
  28. package/src/next/components/Dropdown/examples/DropdownWithKebabToggle.tsx +0 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.250.3",
3
+ "version": "4.250.5",
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": "5daeed558b92f13887c4ae278c2356abe2d22bae"
73
+ "gitHead": "8cea2e5427953062a640877854086934b93ce1f7"
74
74
  }
@@ -69,6 +69,8 @@ export interface SelectProps
69
69
  isDisabled?: boolean;
70
70
  /** Flag to indicate if the typeahead select allows new items */
71
71
  isCreatable?: boolean;
72
+ /** Flag to indicate if create option should be at top of typeahead */
73
+ isCreateOptionOnTop?: boolean;
72
74
  /** Flag indicating if placeholder styles should be applied */
73
75
  hasPlaceholderStyle?: boolean;
74
76
  /** @beta Flag indicating if the creatable option should set its value as a SelectOptionObject */
@@ -226,6 +228,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
226
228
  isDisabled: false,
227
229
  hasPlaceholderStyle: false,
228
230
  isCreatable: false,
231
+ isCreateOptionOnTop: false,
229
232
  validated: 'default',
230
233
  'aria-label': '',
231
234
  'aria-labelledby': '',
@@ -433,6 +436,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
433
436
  const {
434
437
  onFilter,
435
438
  isCreatable,
439
+ isCreateOptionOnTop,
436
440
  onCreateOption,
437
441
  createText,
438
442
  noResultsFoundText,
@@ -542,7 +546,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
542
546
  } as SelectOptionObject)
543
547
  : newValue;
544
548
 
545
- typeaheadFilteredChildren.push(
549
+ const createSelectOption = (
546
550
  <SelectOption
547
551
  key={`create ${newValue}`}
548
552
  value={newOptionValue}
@@ -551,6 +555,12 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
551
555
  {createText} "{newValue}"
552
556
  </SelectOption>
553
557
  );
558
+
559
+ if (isCreateOptionOnTop) {
560
+ typeaheadFilteredChildren.unshift(createSelectOption);
561
+ } else {
562
+ typeaheadFilteredChildren.push(createSelectOption);
563
+ }
554
564
  }
555
565
  }
556
566
 
@@ -1020,6 +1030,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
1020
1030
  footer,
1021
1031
  loadingVariant,
1022
1032
  isCreateSelectOptionObject,
1033
+ isCreateOptionOnTop,
1023
1034
  shouldResetOnSelect,
1024
1035
  isFlipEnabled,
1025
1036
  removeFindDomNode,
@@ -560,3 +560,35 @@ test('applies focus styling to the create option when reached via keyboard navig
560
560
 
561
561
  expect(createOption.parentElement).toHaveClass('pf-m-focus');
562
562
  });
563
+
564
+ test('appends create option to list of options', async () => {
565
+ const user = userEvent.setup();
566
+
567
+ render(
568
+ <Select variant={SelectVariant.typeahead} onToggle={() => {}} isOpen isCreatable>
569
+ {selectOptions}
570
+ </Select>
571
+ );
572
+
573
+ const input = screen.getByRole('textbox');
574
+ await user.type(input, `m`);
575
+
576
+ const createOption = screen.getAllByRole('option')[3];
577
+ expect(createOption).toHaveTextContent('Create "m"');
578
+ });
579
+
580
+ test('prepends create option to list of options if isCreateOptionOnTop flag is set', async () => {
581
+ const user = userEvent.setup();
582
+
583
+ render(
584
+ <Select variant={SelectVariant.typeahead} onToggle={() => {}} isOpen isCreateOptionOnTop isCreatable>
585
+ {selectOptions}
586
+ </Select>
587
+ );
588
+
589
+ const input = screen.getByRole('textbox');
590
+ await user.type(input, `m`);
591
+
592
+ const createOption = screen.getAllByRole('option')[0];
593
+ expect(createOption).toHaveTextContent('Create "m"');
594
+ });
@@ -1209,6 +1209,7 @@ class TypeaheadSelectInput extends React.Component {
1209
1209
  selected: null,
1210
1210
  isDisabled: false,
1211
1211
  isCreatable: false,
1212
+ isCreateOptionOnTop: false,
1212
1213
  isInputValuePersisted: false,
1213
1214
  isInputFilterPersisted: false,
1214
1215
  hasOnCreateOption: false,
@@ -1258,6 +1259,12 @@ class TypeaheadSelectInput extends React.Component {
1258
1259
  });
1259
1260
  };
1260
1261
 
1262
+ this.toggleCreateOptionOnTop = checked => {
1263
+ this.setState({
1264
+ isCreateOptionOnTop: checked
1265
+ });
1266
+ };
1267
+
1261
1268
  this.toggleCreateNew = checked => {
1262
1269
  this.setState({
1263
1270
  hasOnCreateOption: checked
@@ -1289,6 +1296,7 @@ class TypeaheadSelectInput extends React.Component {
1289
1296
  selected,
1290
1297
  isDisabled,
1291
1298
  isCreatable,
1299
+ isCreateOptionOnTop,
1292
1300
  hasOnCreateOption,
1293
1301
  isInputValuePersisted,
1294
1302
  isInputFilterPersisted,
@@ -1315,6 +1323,7 @@ class TypeaheadSelectInput extends React.Component {
1315
1323
  placeholderText="Select a state"
1316
1324
  isDisabled={isDisabled}
1317
1325
  isCreatable={isCreatable}
1326
+ isCreateOptionOnTop={isCreateOptionOnTop}
1318
1327
  onCreateOption={(hasOnCreateOption && this.onCreateOption) || undefined}
1319
1328
  shouldResetOnSelect={resetOnSelect}
1320
1329
  >
@@ -1343,6 +1352,14 @@ class TypeaheadSelectInput extends React.Component {
1343
1352
  id="toggle-creatable-typeahead"
1344
1353
  name="toggle-creatable-typeahead"
1345
1354
  />
1355
+ <Checkbox
1356
+ label="isCreateOptionOnTop"
1357
+ isChecked={this.state.isCreateOptionOnTop}
1358
+ onChange={this.toggleCreateOptionOnTop}
1359
+ aria-label="toggle createOptionOnTop checkbox"
1360
+ id="toggle-create-option-on-top-typeahead"
1361
+ name="toggle-create-option-on-top-typeahead"
1362
+ />
1346
1363
  <Checkbox
1347
1364
  label="onCreateOption"
1348
1365
  isChecked={this.state.hasOnCreateOption}
@@ -23,9 +23,11 @@ export interface DropdownProps extends MenuProps {
23
23
  isScrollable?: boolean;
24
24
  /** Min width of the menu. */
25
25
  minWidth?: string;
26
+ /** @hide Forwarded ref */
27
+ innerRef?: React.Ref<any>;
26
28
  }
27
29
 
28
- export const Dropdown: React.FunctionComponent<DropdownProps> = ({
30
+ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
29
31
  children,
30
32
  className,
31
33
  onSelect,
@@ -35,13 +37,14 @@ export const Dropdown: React.FunctionComponent<DropdownProps> = ({
35
37
  isPlain,
36
38
  isScrollable,
37
39
  minWidth,
40
+ innerRef,
38
41
  ...props
39
42
  }: DropdownProps) => {
40
43
  const localMenuRef = React.useRef<HTMLDivElement>();
41
44
  const toggleRef = React.useRef<HTMLButtonElement>();
42
45
  const containerRef = React.useRef<HTMLDivElement>();
43
46
 
44
- const menuRef = (props.innerRef as React.RefObject<HTMLDivElement>) || localMenuRef;
47
+ const menuRef = (innerRef as React.RefObject<HTMLDivElement>) || localMenuRef;
45
48
  React.useEffect(() => {
46
49
  const handleMenuKeys = (event: KeyboardEvent) => {
47
50
  if (!isOpen && toggleRef.current?.contains(event.target as Node)) {
@@ -112,4 +115,8 @@ export const Dropdown: React.FunctionComponent<DropdownProps> = ({
112
115
  </div>
113
116
  );
114
117
  };
118
+
119
+ export const Dropdown = React.forwardRef((props: DropdownProps, ref: React.Ref<any>) => (
120
+ <DropdownBase innerRef={ref} {...props} />
121
+ ));
115
122
  Dropdown.displayName = 'Dropdown';
@@ -4,7 +4,6 @@ import { Divider, MenuToggle } from '@patternfly/react-core';
4
4
 
5
5
  export const DropdownBasic: React.FunctionComponent = () => {
6
6
  const [isOpen, setIsOpen] = React.useState(false);
7
- const menuRef = React.useRef<HTMLDivElement>(null);
8
7
 
9
8
  const onToggleClick = () => {
10
9
  setIsOpen(!isOpen);
@@ -18,7 +17,6 @@ export const DropdownBasic: React.FunctionComponent = () => {
18
17
 
19
18
  return (
20
19
  <Dropdown
21
- innerRef={menuRef}
22
20
  isOpen={isOpen}
23
21
  onSelect={onSelect}
24
22
  onOpenChange={isOpen => setIsOpen(isOpen)}
@@ -4,7 +4,6 @@ import { MenuToggle } from '@patternfly/react-core';
4
4
 
5
5
  export const DropdownWithDescriptions: React.FunctionComponent = () => {
6
6
  const [isOpen, setIsOpen] = React.useState(false);
7
- const menuRef = React.useRef<HTMLDivElement>(null);
8
7
 
9
8
  const onToggleClick = () => {
10
9
  setIsOpen(!isOpen);
@@ -18,7 +17,6 @@ export const DropdownWithDescriptions: React.FunctionComponent = () => {
18
17
 
19
18
  return (
20
19
  <Dropdown
21
- innerRef={menuRef}
22
20
  isOpen={isOpen}
23
21
  onSelect={onSelect}
24
22
  minWidth="150px"
@@ -4,7 +4,6 @@ import { MenuToggle, Divider } from '@patternfly/react-core';
4
4
 
5
5
  export const DropdownWithGroups: React.FunctionComponent = () => {
6
6
  const [isOpen, setIsOpen] = React.useState(false);
7
- const menuRef = React.useRef<HTMLDivElement>(null);
8
7
 
9
8
  const onToggleClick = () => {
10
9
  setIsOpen(!isOpen);
@@ -18,7 +17,6 @@ export const DropdownWithGroups: React.FunctionComponent = () => {
18
17
 
19
18
  return (
20
19
  <Dropdown
21
- innerRef={menuRef}
22
20
  isOpen={isOpen}
23
21
  onSelect={onSelect}
24
22
  onOpenChange={isOpen => setIsOpen(isOpen)}
@@ -5,7 +5,6 @@ import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-ico
5
5
 
6
6
  export const DropdownWithKebab: React.FunctionComponent = () => {
7
7
  const [isOpen, setIsOpen] = React.useState(false);
8
- const menuRef = React.useRef<HTMLDivElement>(null);
9
8
 
10
9
  const onToggleClick = () => {
11
10
  setIsOpen(!isOpen);
@@ -19,7 +18,6 @@ export const DropdownWithKebab: React.FunctionComponent = () => {
19
18
 
20
19
  return (
21
20
  <Dropdown
22
- innerRef={menuRef}
23
21
  isOpen={isOpen}
24
22
  onSelect={onSelect}
25
23
  minWidth="150px"