draft-components 1.8.0 → 1.9.0
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.
|
@@ -14,14 +14,22 @@ const keyboardKeys = require('../../lib/keyboard-keys.cjs');
|
|
|
14
14
|
const helpers = require('../../lib/helpers.cjs');
|
|
15
15
|
const reactHelpers = require('../../lib/react-helpers.cjs');
|
|
16
16
|
|
|
17
|
-
function FilteredSearch({ className, placeholder = 'Search and filter', applyButtonLabel = 'Apply', cancelButtonLabel = 'Cancel', clearButtonAccessibleName = 'Clear', removeFilterButtonAccessibleName = 'Remove filter', filtersConfig,
|
|
17
|
+
function FilteredSearch({ filters: appliedFilters, className, placeholder = 'Search and filter', applyButtonLabel = 'Apply', cancelButtonLabel = 'Cancel', clearButtonAccessibleName = 'Clear', removeFilterButtonAccessibleName = 'Remove filter', filtersConfig, onChangeFilters, onMouseDown, ...props }) {
|
|
18
18
|
const containerRef = react.useRef(null);
|
|
19
|
+
const [newFilter, setNewFilter] = react.useState(null);
|
|
19
20
|
const [query, setQuery] = react.useState('');
|
|
20
21
|
const [hasFocus, setHasFocus] = react.useState(false);
|
|
21
22
|
const [expanded, setExpanded] = react.useState(false);
|
|
22
23
|
const [selectedId, setSelectedId] = react.useState('');
|
|
23
24
|
const [activeField, setActiveField] = react.useState('');
|
|
24
25
|
const { textBoxId, listBoxId, getOptionId } = useComboboxIds.useComboboxIds();
|
|
26
|
+
let filters;
|
|
27
|
+
if (newFilter) {
|
|
28
|
+
filters = [...appliedFilters, newFilter];
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
filters = appliedFilters;
|
|
32
|
+
}
|
|
25
33
|
const filtersConfigMap = react.useMemo(() => {
|
|
26
34
|
const map = new Map();
|
|
27
35
|
for (const config of filtersConfig) {
|
|
@@ -36,20 +44,16 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
36
44
|
}
|
|
37
45
|
return textBox;
|
|
38
46
|
};
|
|
39
|
-
const addFilter = (
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
onChangeFilters([...filters, filter]);
|
|
43
|
-
textBoxElement.blur();
|
|
44
|
-
setQuery('');
|
|
45
|
-
setActiveField(filter.field);
|
|
47
|
+
const addFilter = (filter) => {
|
|
48
|
+
const newFilters = [...appliedFilters, filter];
|
|
49
|
+
onChangeFilters(newFilters);
|
|
46
50
|
};
|
|
47
|
-
const
|
|
48
|
-
const newFilters =
|
|
51
|
+
const updateFilter = (updatedFilter) => {
|
|
52
|
+
const newFilters = appliedFilters.map((filter) => (filter.field === updatedFilter.field ? updatedFilter : filter));
|
|
49
53
|
onChangeFilters(newFilters);
|
|
50
54
|
};
|
|
51
|
-
const removeFilter = (
|
|
52
|
-
const newFilters =
|
|
55
|
+
const removeFilter = (removedFilter) => {
|
|
56
|
+
const newFilters = appliedFilters.filter((filter) => (filter.field !== removedFilter.field));
|
|
53
57
|
onChangeFilters(newFilters);
|
|
54
58
|
};
|
|
55
59
|
const onFilterEditStarted = (filter) => {
|
|
@@ -58,12 +62,23 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
58
62
|
const onFilterEditCanceled = (filter) => {
|
|
59
63
|
setActiveField('');
|
|
60
64
|
if (filter.isEmpty()) {
|
|
61
|
-
|
|
65
|
+
if (newFilter && filter.field === newFilter.field) {
|
|
66
|
+
setNewFilter(null);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
removeFilter(filter);
|
|
70
|
+
}
|
|
62
71
|
getTextBoxElement().focus();
|
|
63
72
|
}
|
|
64
73
|
};
|
|
65
74
|
const onFilterChanged = (filter) => {
|
|
66
|
-
|
|
75
|
+
if (newFilter && filter.field === newFilter.field) {
|
|
76
|
+
addFilter(filter);
|
|
77
|
+
setNewFilter(null);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
updateFilter(filter);
|
|
81
|
+
}
|
|
67
82
|
setActiveField('');
|
|
68
83
|
};
|
|
69
84
|
const renderedFilters = [];
|
|
@@ -73,6 +88,14 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
73
88
|
fieldsWithAppliedFilters.add(field);
|
|
74
89
|
renderedFilters.push(jsxRuntime.jsx(filterItem.FilterItem, { filter: filter, isEditing: activeField === field, onEditStart: onFilterEditStarted, onEditCancel: onFilterEditCanceled, onChange: onFilterChanged, onRemove: removeFilter }, field));
|
|
75
90
|
}
|
|
91
|
+
const onOptionSelected = (config) => {
|
|
92
|
+
const filter = createFilter(config);
|
|
93
|
+
const textBoxElement = getTextBoxElement();
|
|
94
|
+
setQuery('');
|
|
95
|
+
setNewFilter(filter);
|
|
96
|
+
setActiveField(filter.field);
|
|
97
|
+
textBoxElement.blur();
|
|
98
|
+
};
|
|
76
99
|
const onOptionHovered = (event) => {
|
|
77
100
|
const listItemElement = event.currentTarget;
|
|
78
101
|
setSelectedId(listItemElement.id);
|
|
@@ -83,7 +106,7 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
83
106
|
const listItemElement = event.currentTarget;
|
|
84
107
|
const config = filtersConfigMap.get(listItemElement.id);
|
|
85
108
|
if (config) {
|
|
86
|
-
|
|
109
|
+
onOptionSelected(config);
|
|
87
110
|
}
|
|
88
111
|
};
|
|
89
112
|
const renderedOptions = [];
|
|
@@ -127,7 +150,7 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
127
150
|
else if (key === keyboardKeys.KeyboardKeys.Enter) {
|
|
128
151
|
const config = filtersConfigMap.get(selectedId);
|
|
129
152
|
if (config) {
|
|
130
|
-
|
|
153
|
+
onOptionSelected(config);
|
|
131
154
|
isHandled = true;
|
|
132
155
|
}
|
|
133
156
|
}
|
|
@@ -12,14 +12,22 @@ import { KeyboardKeys } from '../../lib/keyboard-keys.js';
|
|
|
12
12
|
import { exhaustiveCheck } from '../../lib/helpers.js';
|
|
13
13
|
import { classNames } from '../../lib/react-helpers.js';
|
|
14
14
|
|
|
15
|
-
function FilteredSearch({ className, placeholder = 'Search and filter', applyButtonLabel = 'Apply', cancelButtonLabel = 'Cancel', clearButtonAccessibleName = 'Clear', removeFilterButtonAccessibleName = 'Remove filter', filtersConfig,
|
|
15
|
+
function FilteredSearch({ filters: appliedFilters, className, placeholder = 'Search and filter', applyButtonLabel = 'Apply', cancelButtonLabel = 'Cancel', clearButtonAccessibleName = 'Clear', removeFilterButtonAccessibleName = 'Remove filter', filtersConfig, onChangeFilters, onMouseDown, ...props }) {
|
|
16
16
|
const containerRef = useRef(null);
|
|
17
|
+
const [newFilter, setNewFilter] = useState(null);
|
|
17
18
|
const [query, setQuery] = useState('');
|
|
18
19
|
const [hasFocus, setHasFocus] = useState(false);
|
|
19
20
|
const [expanded, setExpanded] = useState(false);
|
|
20
21
|
const [selectedId, setSelectedId] = useState('');
|
|
21
22
|
const [activeField, setActiveField] = useState('');
|
|
22
23
|
const { textBoxId, listBoxId, getOptionId } = useComboboxIds();
|
|
24
|
+
let filters;
|
|
25
|
+
if (newFilter) {
|
|
26
|
+
filters = [...appliedFilters, newFilter];
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
filters = appliedFilters;
|
|
30
|
+
}
|
|
23
31
|
const filtersConfigMap = useMemo(() => {
|
|
24
32
|
const map = new Map();
|
|
25
33
|
for (const config of filtersConfig) {
|
|
@@ -34,20 +42,16 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
34
42
|
}
|
|
35
43
|
return textBox;
|
|
36
44
|
};
|
|
37
|
-
const addFilter = (
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
onChangeFilters([...filters, filter]);
|
|
41
|
-
textBoxElement.blur();
|
|
42
|
-
setQuery('');
|
|
43
|
-
setActiveField(filter.field);
|
|
45
|
+
const addFilter = (filter) => {
|
|
46
|
+
const newFilters = [...appliedFilters, filter];
|
|
47
|
+
onChangeFilters(newFilters);
|
|
44
48
|
};
|
|
45
|
-
const
|
|
46
|
-
const newFilters =
|
|
49
|
+
const updateFilter = (updatedFilter) => {
|
|
50
|
+
const newFilters = appliedFilters.map((filter) => (filter.field === updatedFilter.field ? updatedFilter : filter));
|
|
47
51
|
onChangeFilters(newFilters);
|
|
48
52
|
};
|
|
49
|
-
const removeFilter = (
|
|
50
|
-
const newFilters =
|
|
53
|
+
const removeFilter = (removedFilter) => {
|
|
54
|
+
const newFilters = appliedFilters.filter((filter) => (filter.field !== removedFilter.field));
|
|
51
55
|
onChangeFilters(newFilters);
|
|
52
56
|
};
|
|
53
57
|
const onFilterEditStarted = (filter) => {
|
|
@@ -56,12 +60,23 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
56
60
|
const onFilterEditCanceled = (filter) => {
|
|
57
61
|
setActiveField('');
|
|
58
62
|
if (filter.isEmpty()) {
|
|
59
|
-
|
|
63
|
+
if (newFilter && filter.field === newFilter.field) {
|
|
64
|
+
setNewFilter(null);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
removeFilter(filter);
|
|
68
|
+
}
|
|
60
69
|
getTextBoxElement().focus();
|
|
61
70
|
}
|
|
62
71
|
};
|
|
63
72
|
const onFilterChanged = (filter) => {
|
|
64
|
-
|
|
73
|
+
if (newFilter && filter.field === newFilter.field) {
|
|
74
|
+
addFilter(filter);
|
|
75
|
+
setNewFilter(null);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
updateFilter(filter);
|
|
79
|
+
}
|
|
65
80
|
setActiveField('');
|
|
66
81
|
};
|
|
67
82
|
const renderedFilters = [];
|
|
@@ -71,6 +86,14 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
71
86
|
fieldsWithAppliedFilters.add(field);
|
|
72
87
|
renderedFilters.push(jsx(FilterItem, { filter: filter, isEditing: activeField === field, onEditStart: onFilterEditStarted, onEditCancel: onFilterEditCanceled, onChange: onFilterChanged, onRemove: removeFilter }, field));
|
|
73
88
|
}
|
|
89
|
+
const onOptionSelected = (config) => {
|
|
90
|
+
const filter = createFilter(config);
|
|
91
|
+
const textBoxElement = getTextBoxElement();
|
|
92
|
+
setQuery('');
|
|
93
|
+
setNewFilter(filter);
|
|
94
|
+
setActiveField(filter.field);
|
|
95
|
+
textBoxElement.blur();
|
|
96
|
+
};
|
|
74
97
|
const onOptionHovered = (event) => {
|
|
75
98
|
const listItemElement = event.currentTarget;
|
|
76
99
|
setSelectedId(listItemElement.id);
|
|
@@ -81,7 +104,7 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
81
104
|
const listItemElement = event.currentTarget;
|
|
82
105
|
const config = filtersConfigMap.get(listItemElement.id);
|
|
83
106
|
if (config) {
|
|
84
|
-
|
|
107
|
+
onOptionSelected(config);
|
|
85
108
|
}
|
|
86
109
|
};
|
|
87
110
|
const renderedOptions = [];
|
|
@@ -125,7 +148,7 @@ function FilteredSearch({ className, placeholder = 'Search and filter', applyBut
|
|
|
125
148
|
else if (key === KeyboardKeys.Enter) {
|
|
126
149
|
const config = filtersConfigMap.get(selectedId);
|
|
127
150
|
if (config) {
|
|
128
|
-
|
|
151
|
+
onOptionSelected(config);
|
|
129
152
|
isHandled = true;
|
|
130
153
|
}
|
|
131
154
|
}
|
package/package.json
CHANGED
|
@@ -12,4 +12,4 @@ export type FilteredSearchProps = FilteredSearchBaseProps & {
|
|
|
12
12
|
filters: Filter[];
|
|
13
13
|
onChangeFilters: (filters: Filter[]) => void;
|
|
14
14
|
};
|
|
15
|
-
export declare function FilteredSearch({ className, placeholder, applyButtonLabel, cancelButtonLabel, clearButtonAccessibleName, removeFilterButtonAccessibleName, filtersConfig,
|
|
15
|
+
export declare function FilteredSearch({ filters: appliedFilters, className, placeholder, applyButtonLabel, cancelButtonLabel, clearButtonAccessibleName, removeFilterButtonAccessibleName, filtersConfig, onChangeFilters, onMouseDown, ...props }: FilteredSearchProps): import("react/jsx-runtime").JSX.Element;
|