@linzjs/step-ag-grid 17.0.7 → 17.1.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.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@linzjs/step-ag-grid",
3
3
  "repository": "github:linz/step-ag-grid.git",
4
4
  "license": "MIT",
5
- "version": "17.0.7",
5
+ "version": "17.1.0",
6
6
  "keywords": [
7
7
  "aggrid",
8
8
  "ag-grid",
@@ -1,6 +1,7 @@
1
- import { fromPairs, groupBy, isEmpty, pick, toPairs } from "lodash-es";
2
- import {
1
+ import { defer, fromPairs, groupBy, isEmpty, pick, toPairs } from "lodash-es";
2
+ import React, {
3
3
  Dispatch,
4
+ ForwardedRef,
4
5
  Fragment,
5
6
  KeyboardEvent,
6
7
  ReactElement,
@@ -73,6 +74,7 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
73
74
 
74
75
  const subComponentIsValidRef = useRef<Record<string, boolean>>({});
75
76
  const optionsInitialising = useRef(false);
77
+ const firstInputSubComponent = useRef<HTMLInputElement | null>(null);
76
78
 
77
79
  const [filter, setFilter] = useState("");
78
80
  const [initialValues, setInitialValues] = useState("");
@@ -191,11 +193,21 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
191
193
  <MenuDivider key={`div_${index}`} />
192
194
  ) : (
193
195
  <Fragment key={`val_${item.value}`}>
194
- <MenuRadioItem item={item} options={options} setOptions={setOptions} />
195
-
196
+ <MenuRadioItem
197
+ item={item}
198
+ options={options}
199
+ setOptions={setOptions}
200
+ onChecked={() => {
201
+ // Default to focus on first input in subComponent
202
+ defer(() => {
203
+ firstInputSubComponent.current?.focus();
204
+ });
205
+ }}
206
+ />
196
207
  {item.checked && item.subComponent && (
197
208
  <MenuSubComponent
198
209
  {...{ item, options, setOptions, data, triggerSave }}
210
+ ref={firstInputSubComponent}
199
211
  subComponentIsValid={subComponentIsValidRef.current}
200
212
  />
201
213
  )}
@@ -350,6 +362,7 @@ const MenuRadioItem = (props: {
350
362
  item: MultiSelectOption;
351
363
  options: MultiSelectOption[];
352
364
  setOptions: (options: MultiSelectOption[]) => void;
365
+ onChecked?: () => void;
353
366
  }) => {
354
367
  const { item, options, setOptions } = props;
355
368
 
@@ -369,6 +382,7 @@ const MenuRadioItem = (props: {
369
382
  e.keepOpen = true;
370
383
  toggleValue(item);
371
384
  }
385
+ item.checked && props.onChecked && props.onChecked();
372
386
  }}
373
387
  >
374
388
  <LuiCheckboxInput
@@ -395,17 +409,35 @@ const MenuRadioItem = (props: {
395
409
  );
396
410
  };
397
411
 
398
- const MenuSubComponent = (props: {
399
- data: any;
400
- item: MultiSelectOption;
401
- options: MultiSelectOption[];
402
- setOptions: (options: MultiSelectOption[]) => void;
403
- subComponentIsValid: Record<string, boolean>;
404
- triggerSave: () => Promise<void>;
405
- }) => {
412
+ const MenuSubComponent = React.forwardRef(MenuSubComponentFr);
413
+
414
+ function MenuSubComponentFr(
415
+ props: {
416
+ data: any;
417
+ item: MultiSelectOption;
418
+ options: MultiSelectOption[];
419
+ setOptions: (options: MultiSelectOption[]) => void;
420
+ subComponentIsValid: Record<string, boolean>;
421
+ triggerSave: () => Promise<void>;
422
+ },
423
+ ref: ForwardedRef<HTMLInputElement>,
424
+ ) {
406
425
  const { data, item, options, setOptions, subComponentIsValid, triggerSave } = props;
426
+ const focusableRef = React.useRef<HTMLElement | null>(null);
427
+
428
+ useEffect(() => {
429
+ if (focusableRef.current) {
430
+ const firstInputElement = focusableRef.current.querySelectorAll("input")[0] ?? null;
431
+ if (typeof ref === "function") {
432
+ ref(firstInputElement);
433
+ } else if (ref) {
434
+ ref.current = firstInputElement;
435
+ }
436
+ }
437
+ }, [ref]);
438
+
407
439
  return (
408
- <FocusableItem className={"LuiDeprecatedForms"} key={`${item.value}_subcomponent`}>
440
+ <FocusableItem className={"LuiDeprecatedForms"} key={`${item.value}_subcomponent`} ref={focusableRef}>
409
441
  {() => (
410
442
  <GridSubComponentContext.Provider
411
443
  value={{
@@ -427,4 +459,4 @@ const MenuSubComponent = (props: {
427
459
  )}
428
460
  </FocusableItem>
429
461
  );
430
- };
462
+ }
@@ -111,7 +111,7 @@ GridFormMultiSelectInteractions_.play = async ({ canvasElement }) => {
111
111
  expect(textInput).toBeInTheDocument();
112
112
  expect(await canvas.findByText("Must not be empty")).toBeInTheDocument();
113
113
 
114
- await userEvent.click(textInput);
114
+ // textInput should be autofocus
115
115
  await userEvent.type(textInput, "Hello");
116
116
  expect(await canvas.findByText("Press enter or tab to save")).toBeInTheDocument();
117
117