From ecbd5b507675ab6d91dc4c59c86e326734989368 Mon Sep 17 00:00:00 2001 From: Dane Pilcher Date: Wed, 9 Feb 2022 22:47:45 +0000 Subject: [PATCH 1/2] feat: add default initial value for form component state --- .../studio-ui-codegen-react.test.ts.snap | 22 ++++++------ packages/codegen-ui-react/lib/primitive.ts | 27 +++++++++++++++ .../codegen-ui-react/lib/workflow/mutation.ts | 34 ++++++++++++++++++- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap b/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap index 68ae1eb87..0af3b2d3b 100644 --- a/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap +++ b/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap @@ -5223,7 +5223,7 @@ export default function InputMutationOnClick( props: InputMutationOnClickProps ): React.ReactElement { const { overrides, ...rest } = props; - const [myInputValue, setMyInputValue] = useStateMutationAction(undefined); + const [myInputValue, setMyInputValue] = useStateMutationAction(\\"\\"); const setInputButtonClick = () => { setMyInputValue(\\"Razor Crest\\"); }; @@ -5376,7 +5376,7 @@ export default function TwoWayBindings( ): React.ReactElement { const { overrides, ...rest } = props; const [textFieldInputValue, setTextFieldInputValue] = - useStateMutationAction(undefined); + useStateMutationAction(\\"\\"); return ( /* @ts-ignore: TS2322 */ @@ -5815,15 +5815,15 @@ export default function TwoWayBindings( ): React.ReactElement { const { overrides, ...rest } = props; const [checkboxFieldInputChecked, setCheckboxFieldInputChecked] = - useStateMutationAction(undefined); + useStateMutationAction(false); const [passwordFieldInputValue, setPasswordFieldInputValue] = - useStateMutationAction(undefined); + useStateMutationAction(\\"\\"); const [phoneNumberFieldInputValue, setPhoneNumberFieldInputValue] = - useStateMutationAction(undefined); + useStateMutationAction(\\"\\"); const [radioGroupFieldInputValue, setRadioGroupFieldInputValue] = - useStateMutationAction(undefined); + useStateMutationAction(\\"html\\"); const [searchFieldInputValue, setSearchFieldInputValue] = - useStateMutationAction(undefined); + useStateMutationAction(\\"\\"); const [selectFieldInputValue, setSelectFieldInputValue] = useStateMutationAction(undefined); const [sliderFieldInputValue, setSliderFieldInputValue] = @@ -5831,9 +5831,9 @@ export default function TwoWayBindings( const [stepperFieldInputValue, setStepperFieldInputValue] = useStateMutationAction(undefined); const [switchFieldInputIsChecked, setSwitchFieldInputIsChecked] = - useStateMutationAction(undefined); + useStateMutationAction(false); const [textFieldInputValue, setTextFieldInputValue] = - useStateMutationAction(undefined); + useStateMutationAction(\\"\\"); const setCheckboxFieldValueClick = () => { setCheckboxFieldInputChecked(false); }; diff --git a/packages/codegen-ui-react/lib/primitive.ts b/packages/codegen-ui-react/lib/primitive.ts index 1421fa4b5..e11ebf389 100644 --- a/packages/codegen-ui-react/lib/primitive.ts +++ b/packages/codegen-ui-react/lib/primitive.ts @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { FixedStudioComponentProperty } from '@aws-amplify/codegen-ui'; import { factory, SyntaxKind, TypeParameterDeclaration, TypeNode } from 'typescript'; import iconset from './iconset'; @@ -128,3 +129,29 @@ export const PrimitivesWithChangeEvent: Set = new Set([ Primitive.SwitchField, Primitive.TextField, ]); + +export const PrimitiveDefaultPropertyValue: Partial< + Record +> = { + [Primitive.CheckboxField]: { + checked: { value: false, type: 'boolean' }, + }, + [Primitive.PasswordField]: { + value: { value: '', type: 'string' }, + }, + [Primitive.PhoneNumberField]: { + value: { value: '', type: 'string' }, + }, + [Primitive.RadioGroupField]: { + value: { value: '', type: 'string' }, + }, + [Primitive.SearchField]: { + value: { value: '', type: 'string' }, + }, + [Primitive.SwitchField]: { + isChecked: { value: false, type: 'boolean' }, + }, + [Primitive.TextField]: { + value: { value: '', type: 'string' }, + }, +}; diff --git a/packages/codegen-ui-react/lib/workflow/mutation.ts b/packages/codegen-ui-react/lib/workflow/mutation.ts index fc2aab45f..afc1d7c1c 100644 --- a/packages/codegen-ui-react/lib/workflow/mutation.ts +++ b/packages/codegen-ui-react/lib/workflow/mutation.ts @@ -22,6 +22,7 @@ import { StateReference, StudioGenericEvent, buildComponentNameToTypeMap, + StudioComponentProperty, } from '@aws-amplify/codegen-ui'; import { isActionEvent, @@ -32,9 +33,13 @@ import { getSetStateName, } from '../react-component-render-helper'; import { ImportCollection, ImportValue } from '../imports'; -import Primitive, { PrimitivesWithChangeEvent, PrimitiveLevelPropConfiguration } from '../primitive'; import { mapGenericEventToReact } from './events'; import { getChildPropMappingForComponentName } from './utils'; +import Primitive, { + PrimitivesWithChangeEvent, + PrimitiveLevelPropConfiguration, + PrimitiveDefaultPropertyValue, +} from '../primitive'; type EventHandlerBuilder = (setStateName: string, stateName: string) => JsxExpression; @@ -273,6 +278,14 @@ export function getStateDefaultValue(component: StudioComponent, stateReference: const { componentName, property } = stateReference; const referencedComponent = getComponentFromComponentTree(component, componentName); const componentProperty = referencedComponent.properties[property]; + + // does not work for custom components wrapping form components + if ( + componentProperty === undefined && + PrimitiveDefaultPropertyValue[referencedComponent.componentType as Primitive] + ) { + return propertyToExpression(getDefaultForComponentAndProperty(referencedComponent, property)); + } return propertyToExpression(componentProperty); } @@ -303,6 +316,25 @@ export function getComponentFromComponentTree( return res; } +export function getDefaultForComponentAndProperty( + component: StudioComponent | StudioComponentChild, + property: string, +): StudioComponentProperty { + const { componentType } = component; + const componentDefault = PrimitiveDefaultPropertyValue[componentType as Primitive]; + if (componentDefault && property in componentDefault) { + // if component has defaultValue use defaultValue as initial state value + if (property === 'value' && component.properties.defaultValue) { + // TODO: remove defaultValue becuase coponents canot have value and defaultValue + return component.properties.defaultValue; + } + return componentDefault[property]; + } + + // use empty string a fallback default + return { value: '', type: 'string' }; +} + export type MutationReferences = { [property: string]: { addControlEvent: boolean }[]; }; From c9e6cbca86969df8e274f096ed7938f89fe8b053 Mon Sep 17 00:00:00 2001 From: Dane Pilcher Date: Thu, 10 Feb 2022 17:30:28 +0000 Subject: [PATCH 2/2] style: use PrimitiveLevelPropConfiguration --- packages/codegen-ui-react/lib/primitive.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/codegen-ui-react/lib/primitive.ts b/packages/codegen-ui-react/lib/primitive.ts index e11ebf389..88f041365 100644 --- a/packages/codegen-ui-react/lib/primitive.ts +++ b/packages/codegen-ui-react/lib/primitive.ts @@ -130,9 +130,7 @@ export const PrimitivesWithChangeEvent: Set = new Set([ Primitive.TextField, ]); -export const PrimitiveDefaultPropertyValue: Partial< - Record -> = { +export const PrimitiveDefaultPropertyValue: PrimitiveLevelPropConfiguration = { [Primitive.CheckboxField]: { checked: { value: false, type: 'boolean' }, },