@linzjs/step-ag-grid 7.0.2 → 7.0.3
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/dist/index.js +67 -52
- package/dist/index.js.map +1 -1
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +1 -0
- package/dist/step-ag-grid.esm.js +67 -52
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/gridForm/GridFormDropDown.tsx +51 -28
- package/src/stories/grid/GridPopoutEditDropDown.stories.tsx +5 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "../../styles/GridFormDropDown.scss";
|
|
2
2
|
|
|
3
3
|
import { FocusableItem, MenuDivider, MenuHeader, MenuItem } from "../../react-menu3";
|
|
4
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
import { KeyboardEvent, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
5
5
|
import { GridBaseRow } from "../Grid";
|
|
6
6
|
import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
|
|
7
7
|
import { delay } from "lodash-es";
|
|
@@ -12,6 +12,9 @@ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
|
|
|
12
12
|
import { GridSubComponentContext } from "contexts/GridSubComponentContext";
|
|
13
13
|
import { ClickEvent, MenuInstance } from "../../react-menu3/types";
|
|
14
14
|
import { CloseReason } from "../../react-menu3/utils";
|
|
15
|
+
import { GridContext } from "../../contexts/GridContext";
|
|
16
|
+
import { FormError } from "../../lui/FormError";
|
|
17
|
+
import { isNotEmpty } from "../../utils/util";
|
|
15
18
|
|
|
16
19
|
export interface GridPopoutEditDropDownSelectedItem<RowType> {
|
|
17
20
|
// Note the row that was clicked on will be first
|
|
@@ -49,6 +52,7 @@ export interface GridFormPopoutDropDownProps<RowType extends GridBaseRow> extend
|
|
|
49
52
|
// local means the filter won't change if it's reloaded, reload means it does change
|
|
50
53
|
filtered?: "local" | "reload";
|
|
51
54
|
filterPlaceholder?: string;
|
|
55
|
+
filterHelpText?: string;
|
|
52
56
|
onSelectedItem?: (props: GridPopoutEditDropDownSelectedItem<RowType>) => Promise<void>;
|
|
53
57
|
onSelectFilter?: (props: GridPopoutEditDropDownSelectedItem<RowType>) => Promise<void>;
|
|
54
58
|
options: SelectOption[] | ((selectedRows: RowType[], filter?: string) => Promise<SelectOption[]> | SelectOption[]);
|
|
@@ -60,6 +64,7 @@ const fieldToString = (field: any) => {
|
|
|
60
64
|
};
|
|
61
65
|
|
|
62
66
|
export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPopoutDropDownProps<RowType>) => {
|
|
67
|
+
const { stopEditing } = useContext(GridContext);
|
|
63
68
|
const { selectedRows, field, updateValue, data } = useGridPopoverContext<RowType>();
|
|
64
69
|
|
|
65
70
|
// Save triggers during async action processing which triggers another selectItem(), this ref blocks that
|
|
@@ -103,11 +108,12 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
103
108
|
);
|
|
104
109
|
|
|
105
110
|
const selectFilterHandler = useCallback(
|
|
106
|
-
async (value: string) =>
|
|
107
|
-
updateValue(async (selectedRows) => {
|
|
111
|
+
async (value: string) => {
|
|
112
|
+
await updateValue(async (selectedRows) => {
|
|
108
113
|
props.onSelectFilter && (await props.onSelectFilter({ selectedRows, value }));
|
|
109
114
|
return true;
|
|
110
|
-
}, 0)
|
|
115
|
+
}, 0);
|
|
116
|
+
},
|
|
111
117
|
[props, updateValue],
|
|
112
118
|
);
|
|
113
119
|
|
|
@@ -155,7 +161,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
155
161
|
return undefined;
|
|
156
162
|
}
|
|
157
163
|
const str = (option.label as string) || "";
|
|
158
|
-
return str.toLowerCase().indexOf(filter) === -1 ? option.value : undefined;
|
|
164
|
+
return str.toLowerCase().indexOf(filter.toLowerCase()) === -1 ? option.value : undefined;
|
|
159
165
|
})
|
|
160
166
|
.filter((r) => r !== undefined),
|
|
161
167
|
);
|
|
@@ -186,28 +192,13 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
186
192
|
const save = useCallback(async () => {
|
|
187
193
|
if (!options) return true;
|
|
188
194
|
|
|
189
|
-
|
|
190
|
-
if (
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
} else {
|
|
195
|
-
// Handler for sub-selected value
|
|
196
|
-
if (!selectedSubComponent) return true;
|
|
197
|
-
if (selectedSubComponent.subComponent && !subComponentIsValid.current) return false;
|
|
198
|
-
await selectItemHandler(selectedSubComponent.value, subSelectedValue);
|
|
199
|
-
}
|
|
195
|
+
// Handler for sub-selected value
|
|
196
|
+
if (!selectedSubComponent) return true;
|
|
197
|
+
if (selectedSubComponent.subComponent && !subComponentIsValid.current) return false;
|
|
198
|
+
await selectItemHandler(selectedSubComponent.value, subSelectedValue);
|
|
199
|
+
|
|
200
200
|
return true;
|
|
201
|
-
}, [
|
|
202
|
-
filter,
|
|
203
|
-
filteredValues,
|
|
204
|
-
options,
|
|
205
|
-
props.onSelectFilter,
|
|
206
|
-
selectFilterHandler,
|
|
207
|
-
selectItemHandler,
|
|
208
|
-
selectedSubComponent,
|
|
209
|
-
subSelectedValue,
|
|
210
|
-
]);
|
|
201
|
+
}, [options, selectItemHandler, selectedSubComponent, subSelectedValue]);
|
|
211
202
|
|
|
212
203
|
const { popoverWrapper } = useGridPopoverHook({
|
|
213
204
|
className: props.className,
|
|
@@ -215,13 +206,38 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
215
206
|
save,
|
|
216
207
|
});
|
|
217
208
|
|
|
209
|
+
const enterKeyPressedRef = useRef(false);
|
|
210
|
+
const handleKeyDown = useCallback((e: KeyboardEvent) => {
|
|
211
|
+
if (e.key === "Enter") {
|
|
212
|
+
e.stopPropagation();
|
|
213
|
+
e.preventDefault();
|
|
214
|
+
enterKeyPressedRef.current = true;
|
|
215
|
+
}
|
|
216
|
+
}, []);
|
|
217
|
+
|
|
218
|
+
const handleKeyUp = useCallback(
|
|
219
|
+
async (e: KeyboardEvent) => {
|
|
220
|
+
if (!options) return;
|
|
221
|
+
|
|
222
|
+
if (e.key === "Enter") {
|
|
223
|
+
e.stopPropagation();
|
|
224
|
+
e.preventDefault();
|
|
225
|
+
if (!enterKeyPressedRef.current) return;
|
|
226
|
+
|
|
227
|
+
props.onSelectFilter && (await selectFilterHandler(filter));
|
|
228
|
+
stopEditing();
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
[filter, options, props.onSelectFilter, selectFilterHandler, stopEditing],
|
|
232
|
+
);
|
|
233
|
+
|
|
218
234
|
return popoverWrapper(
|
|
219
235
|
<>
|
|
220
236
|
{props.filtered && (
|
|
221
237
|
<div className={"GridFormDropDown-filter"}>
|
|
222
238
|
<FocusableItem className={"filter-item"}>
|
|
223
239
|
{({ ref }: any) => (
|
|
224
|
-
<div style={{ display: "flex", width: "100%" }}>
|
|
240
|
+
<div style={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
|
225
241
|
<input
|
|
226
242
|
autoFocus
|
|
227
243
|
className={"LuiTextInput-input"}
|
|
@@ -230,8 +246,15 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
230
246
|
placeholder={props.filterPlaceholder ?? "Placeholder"}
|
|
231
247
|
data-testid={"filteredMenu-free-text-input"}
|
|
232
248
|
defaultValue={filter}
|
|
233
|
-
|
|
249
|
+
data-disableenterautosave={true}
|
|
250
|
+
data-allowtabtoSave={true}
|
|
251
|
+
onChange={(e) => setFilter(e.target.value)}
|
|
252
|
+
onKeyDown={handleKeyDown}
|
|
253
|
+
onKeyUp={handleKeyUp}
|
|
234
254
|
/>
|
|
255
|
+
{props.filterHelpText && isNotEmpty(filter) && (
|
|
256
|
+
<FormError error={null} helpText={props.filterHelpText} />
|
|
257
|
+
)}
|
|
235
258
|
</div>
|
|
236
259
|
)}
|
|
237
260
|
</FocusableItem>
|
|
@@ -199,13 +199,18 @@ const GridEditDropDownTemplate: ComponentStory<typeof Grid> = (props: GridProps)
|
|
|
199
199
|
editorParams: {
|
|
200
200
|
filtered: "local",
|
|
201
201
|
filterPlaceholder: "Filter this",
|
|
202
|
+
filterHelpText: "Press enter to save custom value",
|
|
202
203
|
options: optionsObjects.map((o) => {
|
|
203
204
|
return { value: o, label: o.desc, disabled: false };
|
|
204
205
|
}),
|
|
205
206
|
onSelectedItem: async (selected) => {
|
|
207
|
+
// eslint-disable-next-line no-console
|
|
208
|
+
console.log("onSelectedItem selected", selected);
|
|
206
209
|
selected.selectedRows.forEach((row) => (row.code = selected.value.code));
|
|
207
210
|
},
|
|
208
211
|
onSelectFilter: async (selected) => {
|
|
212
|
+
// eslint-disable-next-line no-console
|
|
213
|
+
console.log("onSelectFilter selected", selected);
|
|
209
214
|
selected.selectedRows.forEach((row) => (row.code = selected.value));
|
|
210
215
|
},
|
|
211
216
|
},
|