Skip to content

Conversation

@serikjensen
Copy link
Member

This builds on version 1 but looks to provide an easier way for partners to build forms.

Basically this proposes passing on component instances that can then be used by the partner. Within these components, we can prepopulate them with things like name, required status, etc. according to the API needs. We can then expose props like label and validation messaging for partners to set on their end (in order to avoid needing to manage translations)

In a more complex component with conditional validation, we would provide different field objects depending on the form state. That's why we provide these fields dynamically via the hook instead of simply exporting them. We still need to stress test with an example like that.

Other open questions

  • How we go about surfacing options in a way that allows them to provide translations?
  • Is it sufficient for partners to use component adapters with this pattern? Thinking we will likely want to expose a render prop for each of these field components. That way the partner can eject from our UX for these fields if needed (ex. they could use a radio if desired instead of a select, they would just need to hook the props up)

Comment on lines +64 to +100
// TODO: This is not super elegant, we need to return the API responses from the onSubmit
// so that we can use those in the onEvent for the parent component but hook form does not
// allow doing that through the submit handler. This provides a workaround.
const onSubmit = async () => {
return new Promise<{
updatedContractorAddressResponse: PutV1ContractorsContractorUuidAddressResponse | undefined
}>((resolve, reject) => {
formMethods
.handleSubmit(
async (data: ContractorAddressFormValues) => {
let response: PutV1ContractorsContractorUuidAddressResponse | undefined

await baseSubmitHandler(data, async payload => {
response = await updateAddress({
request: {
contractorUuid: contractorId,
requestBody: {
version: address?.version as string,
street1: payload.street1,
street2: payload.street2,
city: payload.city,
state: payload.state,
zip: payload.zip,
},
},
})
})

resolve({ updatedContractorAddressResponse: response })
},
() => {
resolve({ updatedContractorAddressResponse: undefined })
},
)()
.catch(reject)
})
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love thoughts on a better way to navigate this!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could a rewrite of our base submit handler here help us make the code more clear and readable?

</header>

<Grid gridTemplateColumns={{ base: '1fr', small: ['1fr', '1fr'] }} gap={20}>
<Fields.Street1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah i'm a fan of this. I think it looks solid.


export type Street1FieldProps = FieldPropsWithValidations<typeof RequiredValidationKey>

export function Street1({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if because this looks so boilerplate we might be able to find a way to reduce code here. If not totally fine just thinking out loud

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah i think this is getting at some sort of common Field abstraction intended for this. I think these would also have render props available on them as an alternative for what gets rendered

  • you don't necessarily have to use component adapters
  • you have the option to one off an input with a different UI component if desired (ex. use a radio instead of a select etc)

Comment on lines +64 to +100
// TODO: This is not super elegant, we need to return the API responses from the onSubmit
// so that we can use those in the onEvent for the parent component but hook form does not
// allow doing that through the submit handler. This provides a workaround.
const onSubmit = async () => {
return new Promise<{
updatedContractorAddressResponse: PutV1ContractorsContractorUuidAddressResponse | undefined
}>((resolve, reject) => {
formMethods
.handleSubmit(
async (data: ContractorAddressFormValues) => {
let response: PutV1ContractorsContractorUuidAddressResponse | undefined

await baseSubmitHandler(data, async payload => {
response = await updateAddress({
request: {
contractorUuid: contractorId,
requestBody: {
version: address?.version as string,
street1: payload.street1,
street2: payload.street2,
city: payload.city,
state: payload.state,
zip: payload.zip,
},
},
})
})

resolve({ updatedContractorAddressResponse: response })
},
() => {
resolve({ updatedContractorAddressResponse: undefined })
},
)()
.catch(reject)
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could a rewrite of our base submit handler here help us make the code more clear and readable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants