Skip to content

Commit db47e57

Browse files
Merge pull request #749 from gadget-inc/mill/fixAutoInputWrapperGivingSelectPathsToBadInputs
Separated `autoInput` and new `autoRelationshipForm` to prevent contribution of `selectPaths` to all input props
2 parents 6ff6af3 + 3e1e857 commit db47e57

File tree

5 files changed

+41
-18
lines changed

5 files changed

+41
-18
lines changed

packages/react/src/auto/AutoInput.tsx

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export interface AutoInputComponent<P> extends React.FC<P> {
66
__autoInput: true;
77
}
88

9-
export function autoInput<P extends { field: string }>(Component: React.FC<P>): AutoInputComponent<P & { selectPaths?: string[] }> {
9+
export function autoInput<P extends { field: string }>(Component: React.FC<P>): AutoInputComponent<P> {
1010
const WrappedComponent: React.FC<P> = (props) => {
1111
const { hasCustomFormChildren, registerFields, fieldSet } = useFieldsFromChildComponents();
1212
const relationshipContext = useRelationshipContext();
@@ -22,20 +22,43 @@ export function autoInput<P extends { field: string }>(Component: React.FC<P>):
2222
return props.field;
2323
}, [relationshipContext, props.field]);
2424

25+
useEffect(() => {
26+
registerFields([fieldSetPath]);
27+
}, [registerFields, fieldSetPath]);
28+
29+
if (hasCustomFormChildren && !fieldSet.has(fieldSetPath)) {
30+
// Do not render before registration
31+
return null;
32+
}
33+
34+
return <Component {...props} />;
35+
};
36+
37+
(WrappedComponent as AutoInputComponent<P>).__autoInput = true;
38+
39+
return WrappedComponent as AutoInputComponent<P>;
40+
}
41+
42+
export function autoRelationshipForm<P extends { field: string }>(
43+
Component: React.FC<P>
44+
): AutoInputComponent<P & { selectPaths?: string[] }> {
45+
const WrappedComponent: React.FC<P> = (props) => {
46+
const { hasCustomFormChildren, registerFields, fieldSet } = useFieldsFromChildComponents();
47+
2548
const hasSelectPaths = "selectPaths" in props && props.selectPaths;
26-
const selectPaths = useMemo(() => (hasSelectPaths && Array.isArray(props.selectPaths) ? props.selectPaths : []), [hasSelectPaths]);
49+
const selectPathsToRegister = useMemo(
50+
() =>
51+
hasSelectPaths && Array.isArray(props.selectPaths) ? props.selectPaths.map((selectPath) => `${props.field}.${selectPath}`) : [],
52+
[hasSelectPaths, props.field]
53+
);
2754

2855
useEffect(() => {
29-
const fieldsToRegister = [fieldSetPath];
30-
3156
if (hasSelectPaths) {
32-
fieldsToRegister.push(...selectPaths.map((selectPath) => `${props.field}.${selectPath}`));
57+
registerFields(selectPathsToRegister);
3358
}
59+
}, [hasSelectPaths, registerFields, selectPathsToRegister]);
3460

35-
registerFields(fieldsToRegister);
36-
}, [registerFields, fieldSetPath, selectPaths]);
37-
38-
if (hasCustomFormChildren && !fieldSet.has(fieldSetPath)) {
61+
if (hasCustomFormChildren && !selectPathsToRegister.every((field) => fieldSet.has(field))) {
3962
// Do not render before registration
4063
return null;
4164
}
@@ -45,7 +68,7 @@ export function autoInput<P extends { field: string }>(Component: React.FC<P>):
4568

4669
(WrappedComponent as AutoInputComponent<P>).__autoInput = true;
4770

48-
return WrappedComponent as AutoInputComponent<P>;
71+
return autoInput(WrappedComponent as AutoInputComponent<P>);
4972
}
5073

5174
export function isAutoInput(component: React.ReactElement): component is React.ReactElement<any, AutoInputComponent<any>> {

packages/react/src/auto/polaris/inputs/relationships/PolarisAutoBelongsToForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ import { MenuHorizontalIcon, PlusCircleIcon } from "@shopify/polaris-icons";
1616
import React, { useEffect, useState } from "react";
1717
import { useFormContext } from "../../../../useActionForm.js";
1818
import { get } from "../../../../utils.js";
19-
import { autoInput } from "../../../AutoInput.js";
19+
import { autoRelationshipForm } from "../../../AutoInput.js";
2020
import { RelationshipContext, useAutoRelationship, useRelationshipContext } from "../../../hooks/useAutoRelationship.js";
2121
import { useBelongsToController } from "../../../hooks/useBelongsToController.js";
2222
import { getRecordAsOption, useOptionLabelForField } from "../../../hooks/useRelatedModel.js";
2323
import type { OptionLabel } from "../../../interfaces/AutoRelationshipInputProps.js";
2424
import { RelatedModelOptionsPopover, RelatedModelOptionsSearch } from "./RelatedModelOptions.js";
2525
import { renderOptionLabel } from "./utils.js";
2626

27-
export const PolarisAutoBelongsToForm = autoInput(
27+
export const PolarisAutoBelongsToForm = autoRelationshipForm(
2828
(props: {
2929
field: string;
3030
children: React.ReactNode;

packages/react/src/auto/polaris/inputs/relationships/PolarisAutoHasManyForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { BlockStack, Box, Button, Icon, InlineStack, ResourceItem, Text } from "
22
import { PlusCircleIcon } from "@shopify/polaris-icons";
33
import React, { useState } from "react";
44
import { useFormContext } from "../../../../useActionForm.js";
5-
import { autoInput } from "../../../AutoInput.js";
5+
import { autoRelationshipForm } from "../../../AutoInput.js";
66
import { RelationshipContext, useAutoRelationship, useRelationshipContext } from "../../../hooks/useAutoRelationship.js";
77
import { useHasManyController } from "../../../hooks/useHasManyController.js";
88
import { getRecordAsOption, useOptionLabelForField } from "../../../hooks/useRelatedModel.js";
99
import type { OptionLabel } from "../../../interfaces/AutoRelationshipInputProps.js";
1010
import { renderOptionLabel } from "./utils.js";
1111

12-
export const PolarisAutoHasManyForm = autoInput(
12+
export const PolarisAutoHasManyForm = autoRelationshipForm(
1313
(props: {
1414
field: string;
1515
children: React.ReactNode;

packages/react/src/auto/polaris/inputs/relationships/PolarisAutoHasManyThroughForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import { PlusCircleIcon, XCircleIcon } from "@shopify/polaris-icons";
33
import React, { useEffect, useMemo, useState } from "react";
44
import { useFormContext } from "../../../../useActionForm.js";
55
import { extractPathsFromChildren } from "../../..//AutoForm.js";
6-
import { autoInput } from "../../../AutoInput.js";
6+
import { autoRelationshipForm } from "../../../AutoInput.js";
77
import { RelationshipContext, useAutoRelationship, useRelationshipContext } from "../../../hooks/useAutoRelationship.js";
88
import { useHasManyThroughController } from "../../../hooks/useHasManyThroughController.js";
99
import { getRecordAsOption, useOptionLabelForField } from "../../../hooks/useRelatedModel.js";
1010
import type { OptionLabel } from "../../../interfaces/AutoRelationshipInputProps.js";
1111
import { RelatedModelOptionsPopover, RelatedModelOptionsSearch } from "./RelatedModelOptions.js";
1212
import { renderOptionLabel } from "./utils.js";
1313

14-
export const PolarisAutoHasManyThroughForm = autoInput(
14+
export const PolarisAutoHasManyThroughForm = autoRelationshipForm(
1515
(props: {
1616
field: string;
1717
children: React.ReactNode;

packages/react/src/auto/polaris/inputs/relationships/PolarisAutoHasOneForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ import { MenuHorizontalIcon, PlusCircleIcon } from "@shopify/polaris-icons";
1616
import React, { useEffect, useState } from "react";
1717
import { useFormContext } from "../../../../useActionForm.js";
1818
import { get } from "../../../../utils.js";
19-
import { autoInput } from "../../../AutoInput.js";
19+
import { autoRelationshipForm } from "../../../AutoInput.js";
2020
import { RelationshipContext, useAutoRelationship, useRelationshipContext } from "../../../hooks/useAutoRelationship.js";
2121
import { useHasOneController } from "../../../hooks/useHasOneController.js";
2222
import { getRecordAsOption, useOptionLabelForField } from "../../../hooks/useRelatedModel.js";
2323
import type { OptionLabel } from "../../../interfaces/AutoRelationshipInputProps.js";
2424
import { RelatedModelOptionsPopover, RelatedModelOptionsSearch } from "./RelatedModelOptions.js";
2525
import { renderOptionLabel } from "./utils.js";
2626

27-
export const PolarisAutoHasOneForm = autoInput(
27+
export const PolarisAutoHasOneForm = autoRelationshipForm(
2828
(props: {
2929
field: string;
3030
children: React.ReactNode;

0 commit comments

Comments
 (0)