From 208bbf6dcd12c2504a7799879712e54c172f2ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Jourdin?= Date: Fri, 12 May 2023 10:37:05 +0200 Subject: [PATCH] fix(codegen-ui-react): prevent useless props forward to custom components --- .../lib/react-component-renderer.ts | 78 ++++++++++++------- ...collectionWithBindingWithoutPredicate.json | 12 ++- .../example-schemas/complexTest3.json | 6 +- .../example-schemas/customChild.json | 6 +- .../customChildMalformedProperty.json | 3 +- .../example-schemas/parsedFixedValues.json | 66 ++++++++++------ .../example-schemas/sampleCodeSnippet.json | 9 ++- 7 files changed, 117 insertions(+), 63 deletions(-) diff --git a/packages/codegen-ui-react/lib/react-component-renderer.ts b/packages/codegen-ui-react/lib/react-component-renderer.ts index 530fc0a5e..ddb7331ba 100644 --- a/packages/codegen-ui-react/lib/react-component-renderer.ts +++ b/packages/codegen-ui-react/lib/react-component-renderer.ts @@ -20,6 +20,7 @@ import { StudioComponentChild, ComponentMetadata, StudioGenericEvent, + StudioComponentProperty, } from '@aws-amplify/codegen-ui'; import { JsxAttributeLike, @@ -47,6 +48,7 @@ import { addFormAttributes } from './forms'; import { shouldWrapInArrayField, renderArrayFieldComponent, getDecoratedLabel } from './forms/form-renderer-helper'; import { getIsRequiredValue } from './forms/form-renderer-helper/label-decorator'; import { renderStorageFieldComponent } from './utils/forms/storage-field-component'; +import { Primitive } from './primitive'; export class ReactComponentRenderer extends ComponentRendererBase< TPropIn, @@ -123,38 +125,56 @@ export class ReactComponentRenderer extends ComponentRendererBase< this.componentMetadata.stateReferences, ); - const propertyAttributes = Object.entries(this.component.properties).map(([key, value]) => { - if (key in localStateReferences) { - const stateName = getStateName({ componentName: this.component.name, property: key }); - return buildOpeningElementProperties( - this.componentMetadata, - { bindingProperties: { property: stateName } }, - key, - ); - } - if ( - this.componentMetadata.formMetadata && - this.componentMetadata.formMetadata.fieldConfigs[this.component.name] - ) { - const { - labelDecorator, - fieldConfigs: { - [this.component.name]: { isArray }, - }, - } = this.componentMetadata.formMetadata; - const isRequired = getIsRequiredValue(this.component.properties.isRequired); + const primitivesTypes = Object.values(Primitive); + + const isPrimitive = primitivesTypes.includes(this.component.componentType as Primitive); + const isHTML = this.component.componentType[0].match(/[a-z]/); + + const shouldForwardProperty = ([key, value]: [string, StudioComponentProperty]) => { + return ( + isPrimitive || + isHTML || + key in localStateReferences || + 'collectionBindingProperties' in value || + 'concat' in value || + value.configured + ); + }; + + const propertyAttributes = Object.entries(this.component.properties) + .filter(shouldForwardProperty) + .map(([key, value]) => { + if (key in localStateReferences) { + const stateName = getStateName({ componentName: this.component.name, property: key }); + return buildOpeningElementProperties( + this.componentMetadata, + { bindingProperties: { property: stateName } }, + key, + ); + } if ( - ((key === 'children' && this.component.componentType === 'ToggleButton') || key === 'label') && - ((labelDecorator && labelDecorator === 'required' && isRequired) || - (labelDecorator === 'optional' && !isRequired)) && - 'value' in value && - !isArray + this.componentMetadata.formMetadata && + this.componentMetadata.formMetadata.fieldConfigs[this.component.name] ) { - return getDecoratedLabel(key, value.value.toString(), labelDecorator); + const { + labelDecorator, + fieldConfigs: { + [this.component.name]: { isArray }, + }, + } = this.componentMetadata.formMetadata; + const isRequired = getIsRequiredValue(this.component.properties.isRequired); + if ( + ((key === 'children' && this.component.componentType === 'ToggleButton') || key === 'label') && + ((labelDecorator && labelDecorator === 'required' && isRequired) || + (labelDecorator === 'optional' && !isRequired)) && + 'value' in value && + !isArray + ) { + return getDecoratedLabel(key, value.value.toString(), labelDecorator); + } } - } - return buildOpeningElementProperties(this.componentMetadata, value, key); - }); + return buildOpeningElementProperties(this.componentMetadata, value, key); + }); // Reverse, and create element properties for localStateReferences which are not yet defined props const unmodeledPropertyAttributes = Object.entries(localStateReferences) diff --git a/packages/codegen-ui/example-schemas/collectionWithBindingWithoutPredicate.json b/packages/codegen-ui/example-schemas/collectionWithBindingWithoutPredicate.json index ad640d1ba..deb13d629 100644 --- a/packages/codegen-ui/example-schemas/collectionWithBindingWithoutPredicate.json +++ b/packages/codegen-ui/example-schemas/collectionWithBindingWithoutPredicate.json @@ -7,16 +7,20 @@ "componentType": "ListingCard", "properties": { "marginRight": { - "value": "0" + "value": "0", + "configured": true }, "marginBottom": { - "value": "0" + "value": "0", + "configured": true }, "marginTop": { - "value": "0" + "value": "0", + "configured": true }, "marginLeft": { - "value": "0" + "value": "0", + "configured": true } }, "overrides": {}, diff --git a/packages/codegen-ui/example-schemas/complexTest3.json b/packages/codegen-ui/example-schemas/complexTest3.json index ffabf0d6b..7f06c907b 100644 --- a/packages/codegen-ui/example-schemas/complexTest3.json +++ b/packages/codegen-ui/example-schemas/complexTest3.json @@ -73,10 +73,12 @@ "name": "ReneButton", "properties": { "width": { - "value": "293px" + "value": "293px", + "configured": true }, "height": { - "value": "45px" + "value": "45px", + "configured": true } } }, diff --git a/packages/codegen-ui/example-schemas/customChild.json b/packages/codegen-ui/example-schemas/customChild.json index 18b5a8370..b35fa778f 100644 --- a/packages/codegen-ui/example-schemas/customChild.json +++ b/packages/codegen-ui/example-schemas/customChild.json @@ -10,10 +10,12 @@ "name": "MyCustomButton", "properties": { "color": { - "value": "#ff0000" + "value": "#ff0000", + "configured": true }, "width": { - "value": "20px" + "value": "20px", + "configured": true } } } diff --git a/packages/codegen-ui/example-schemas/customChildMalformedProperty.json b/packages/codegen-ui/example-schemas/customChildMalformedProperty.json index 315e208ea..0e3e8058d 100644 --- a/packages/codegen-ui/example-schemas/customChildMalformedProperty.json +++ b/packages/codegen-ui/example-schemas/customChildMalformedProperty.json @@ -18,7 +18,8 @@ { "value": "Value!" } - ] + ], + "configured": true } } } diff --git a/packages/codegen-ui/example-schemas/parsedFixedValues.json b/packages/codegen-ui/example-schemas/parsedFixedValues.json index 5d33f5f9e..9bc83d3c3 100644 --- a/packages/codegen-ui/example-schemas/parsedFixedValues.json +++ b/packages/codegen-ui/example-schemas/parsedFixedValues.json @@ -13,10 +13,12 @@ "name": "MyInputString", "properties": { "id": { - "value": "string-value" + "value": "string-value", + "configured": true }, "value": { - "value": "raw string value" + "value": "raw string value", + "configured": true } } }, @@ -25,10 +27,12 @@ "name": "MyInputNumber", "properties": { "id": { - "value": "number-value" + "value": "number-value", + "configured": true }, "value": { - "value": "67548" + "value": "67548", + "configured": true } } }, @@ -37,11 +41,13 @@ "name": "MyInputParsedNumber", "properties": { "id": { - "value": "parsed-number-value" + "value": "parsed-number-value", + "configured": true }, "value": { "value": "67548", - "type": "Number" + "type": "Number", + "configured": true } } }, @@ -50,10 +56,12 @@ "name": "MyInputBoolean", "properties": { "id": { - "value": "boolean-value" + "value": "boolean-value", + "configured": true }, "value": { - "value": "true" + "value": "true", + "configured": true } } }, @@ -62,11 +70,13 @@ "name": "MyInputPrasedBoolean", "properties": { "id": { - "value": "parsed-boolean-value" + "value": "parsed-boolean-value", + "configured": true }, "value": { "value": "true", - "type": "Boolean" + "type": "Boolean", + "configured": true } } }, @@ -75,10 +85,12 @@ "name": "MyInputJson", "properties": { "id": { - "value": "json-value" + "value": "json-value", + "configured": true }, "value": { - "value": "{\"foo\": \"bar\"}" + "value": "{\"foo\": \"bar\"}", + "configured": true } } }, @@ -87,11 +99,13 @@ "name": "MyInputParsedJson", "properties": { "id": { - "value": "parsed-json-value" + "value": "parsed-json-value", + "configured": true }, "value": { "value": "{\"foo\": \"bar\"}", - "type": "Object" + "type": "Object", + "configured": true } } }, @@ -100,10 +114,12 @@ "name": "MyInputArray", "properties": { "id": { - "value": "array-value" + "value": "array-value", + "configured": true }, "value": { - "value": "[1,2,3]" + "value": "[1,2,3]", + "configured": true } } }, @@ -112,11 +128,13 @@ "name": "MyInputParsedArray", "properties": { "id": { - "value": "parsed-array-value" + "value": "parsed-array-value", + "configured": true }, "value": { "value": "[1,2,3]", - "type": "Object" + "type": "Object", + "configured": true } } }, @@ -125,10 +143,12 @@ "name": "MyInputNull", "properties": { "id": { - "value": "null-value" + "value": "null-value", + "configured": true }, "value": { - "value": "null" + "value": "null", + "configured": true } } }, @@ -137,11 +157,13 @@ "name": "MyInputParsedNull", "properties": { "id": { - "value": "parsed-null-value" + "value": "parsed-null-value", + "configured": true }, "value": { "value": "null", - "type": "Object" + "type": "Object", + "configured": true } } } diff --git a/packages/codegen-ui/example-schemas/sampleCodeSnippet.json b/packages/codegen-ui/example-schemas/sampleCodeSnippet.json index 872e12517..1d4e9bdaf 100644 --- a/packages/codegen-ui/example-schemas/sampleCodeSnippet.json +++ b/packages/codegen-ui/example-schemas/sampleCodeSnippet.json @@ -14,14 +14,17 @@ "name": "MyCustomButton", "properties": { "color": { - "value": "#ff0000" + "value": "#ff0000", + "configured": true }, "width": { - "value": "20px" + "value": "20px", + "configured": true }, "buttonText": { "exposedAs": "buttonText", - "value": "Click Me" + "value": "Click Me", + "configured": true } } }