Skip to content

Commit f7f54cb

Browse files
committed
fix(pf4): Added load options to downshift select
1 parent 6f04e6c commit f7f54cb

File tree

5 files changed

+69
-9
lines changed

5 files changed

+69
-9
lines changed

packages/pf4-component-mapper/demo/demo-schemas/select-schema.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,47 @@ const options = [
2323
}
2424
];
2525

26+
const loadOptions = (inputValue = '') => {
27+
return new Promise((res) =>
28+
setTimeout(() => {
29+
if (inputValue.length === 0) {
30+
return res(options.slice(0, 3));
31+
}
32+
33+
return res(options.filter(({ label }) => label.toLocaleLowerCase().includes(inputValue.toLocaleLowerCase())));
34+
}, 1500)
35+
);
36+
};
37+
2638
const selectSchema = {
2739
fields: [
40+
{
41+
component: componentTypes.SELECT,
42+
name: 'simple-async-select',
43+
label: 'Simple async select',
44+
loadOptions
45+
},
46+
{
47+
component: componentTypes.SELECT,
48+
name: 'simple-searchable-async-select',
49+
label: 'Simple searchable async select',
50+
loadOptions,
51+
isSearchable: true
52+
},
53+
{
54+
component: componentTypes.SELECT,
55+
name: 'multi-async-select',
56+
label: 'multi async select',
57+
loadOptions,
58+
isMulti: true
59+
},
60+
{
61+
component: componentTypes.SELECT,
62+
name: 'searchable-multi-async-select',
63+
label: 'Multi searchable async select',
64+
loadOptions,
65+
isSearchable: true
66+
},
2867
{
2968
component: componentTypes.SELECT,
3069
name: 'multi-simple-select',
@@ -79,4 +118,6 @@ const selectSchema = {
79118
]
80119
};
81120

82-
export default selectSchema;
121+
export default {
122+
...selectSchema
123+
};
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4-
const EmptyOptions = ({ noOptionsMessage, noResultsMessage, getInputProps, isSearchable }) => {
4+
const EmptyOptions = ({ noOptionsMessage, noResultsMessage, getInputProps, isSearchable, isFetching }) => {
55
const { value } = getInputProps();
6-
const message = isSearchable && value ? noResultsMessage : noOptionsMessage();
6+
const message = isFetching ? noOptionsMessage() : isSearchable && value ? noResultsMessage : noOptionsMessage();
77
return <div className="pf-c-select__menu-item pf-m-disabled">{message}</div>;
88
};
99

1010
EmptyOptions.propTypes = {
1111
noOptionsMessage: PropTypes.func.isRequired,
1212
noResultsMessage: PropTypes.node.isRequired,
1313
getInputProps: PropTypes.func.isRequired,
14-
isSearchable: PropTypes.bool
14+
isSearchable: PropTypes.bool,
15+
isFetching: PropTypes.bool
1516
};
1617

1718
export default EmptyOptions;

packages/pf4-component-mapper/src/common/select/menu.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ const Menu = ({
1515
getInputProps,
1616
highlightedIndex,
1717
selectedItem,
18-
isMulti
18+
isMulti,
19+
isFetching
1920
}) => {
2021
const filteredOptions = isSearchable ? filterOptions(options, filterValue) : options;
2122
return (
@@ -27,6 +28,7 @@ const Menu = ({
2728
noOptionsMessage={noOptionsMessage}
2829
noResultsMessage={noResultsMessage}
2930
getInputProps={getInputProps}
31+
isFetching={isFetching}
3032
/>
3133
)}
3234
{filteredOptions.map((item, index) => {

packages/pf4-component-mapper/src/common/select/select-styles.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
100% { transform: rotate(360deg); }
44
}
55

6+
.ddorg__pf4-component-mapper__select-loading-icon {
7+
animation: spin 2s linear infinite;
8+
}
9+
610
.ddorg__pf4-component-mapper__select {
711
&.single-select {
812
.ddorg__pf4-component-mapper__select__placeholder {

packages/pf4-component-mapper/src/common/select/select.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
44
import DataDrivenSelect from '@data-driven-forms/common/src/select';
55
import parseInternalValue from '@data-driven-forms/common/src/select/parse-internal-value';
66
import Downshift from 'downshift';
7-
import { CaretDownIcon, CloseIcon } from '@patternfly/react-icons';
7+
import { CaretDownIcon, CloseIcon, CircleNotchIcon } from '@patternfly/react-icons';
88
import '@patternfly/react-styles/css/components/Select/select.css';
99
import '@patternfly/react-styles/css/components/Chip/chip.css';
1010
import '@patternfly/react-styles/css/components/ChipGroup/chip-group.css';
@@ -109,6 +109,9 @@ const InternalSelect = ({
109109
isDisabled,
110110
isClearable,
111111
isMulti,
112+
isFetching,
113+
onInputChange,
114+
loadingMessage,
112115
...props
113116
}) => {
114117
const [showMore, setShowMore] = useState(false);
@@ -121,8 +124,13 @@ const InternalSelect = ({
121124
id={props.id || props.name}
122125
onChange={handleChange}
123126
itemToString={(value) => itemToString(value, isMulti, showMore, handleShowMore, handleChange)}
124-
selectedItem={value}
127+
selectedItem={value || ''}
125128
stateReducer={(state, changes) => stateReducer(state, changes, isMulti)}
129+
onInputValueChange={(inputValue) => {
130+
if (onInputChange && typeof inputValue === 'string') {
131+
onInputChange(inputValue);
132+
}
133+
}}
126134
>
127135
{({ isOpen, inputValue, itemToString, selectedItem, clearSelection, getInputProps, getToggleButtonProps, getItemProps, highlightedIndex }) => {
128136
const toggleButtonProps = getToggleButtonProps();
@@ -134,13 +142,14 @@ const InternalSelect = ({
134142
</div>
135143
{isClearable && parsedValue && <ClearIndicator clearSelection={clearSelection} />}
136144
<span className="pf-c-select__toggle-arrow">
137-
<CaretDownIcon />
145+
{isFetching ? <CircleNotchIcon className="ddorg__pf4-component-mapper__select-loading-icon" /> : <CaretDownIcon />}
138146
</span>
139147
</div>
140148
{isOpen && (
141149
<Menu
142150
noResultsMessage={noResultsMessage}
143151
noOptionsMessage={noOptionsMessage}
152+
isFetching={isFetching}
144153
inputRef={inputRef}
145154
isDisabled={isDisabled}
146155
placeholder={placeholder}
@@ -180,7 +189,10 @@ InternalSelect.propTypes = {
180189
isClearable: PropTypes.bool,
181190
noResultsMessage: PropTypes.node,
182191
noOptionsMessage: PropTypes.func,
183-
isMulti: PropTypes.bool
192+
isMulti: PropTypes.bool,
193+
isFetching: PropTypes.bool,
194+
onInputChange: PropTypes.func,
195+
loadingMessage: PropTypes.node
184196
};
185197

186198
const Select = ({ selectVariant, menuIsPortal, ...props }) => {

0 commit comments

Comments
 (0)