Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Docs] Add a guide on how to use a block in a Final Form #2619

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions docs/docs/blocks/blocks-in-forms.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
title: Blocks in forms
sidebar_position: 6
---

# Using blocks in forms

This guide describes how to use a block in a Final Form.
We use a product form with a `DamImageBlock` as an example.
The product has the following schema in GraphQL:

```graphql
type Product {
id: ID!
title: String!
// highlight-next-line
image: DamImageBlockData!
}
```

The following steps are necessary to add the `image` field to the form:

1. Create a Final Form component for the block
2. Create the block state when initializing the form
3. Create the block output when submitting the form

:::info

The block transitions between the various states when being used in a form.
The states and transitions can be viewed [here](lifecycle#the-block-in-the-admin).
johnnyomair marked this conversation as resolved.
Show resolved Hide resolved

:::

## Create a Final Form component for the block

The block's `AdminComponent` API (`state`, `updateState`) must be converted to the `Field` API (`input.value`, `input.onChange`).
Use the [createFinalFormBlock](https://github.com/vivid-planet/comet/blob/main/packages/admin/blocks-admin/src/form/createFinalFormBlock.tsx) helper for this:

```tsx
import { createFinalFormBlock } from "@comet/blocks-admin";

const FinalFormDamImageBlock = createFinalFormBlock(DamImageBlock);
```

Use the newly created component in the corresponding `Field` via the `component` prop:

```tsx
import isEqual from "lodash.isequal";

<Field
name="image"
isEqual={isEqual}
// highlight-next-line
component={FinalFormDamImageBlock}
/>;
```

:::note

A deep equality check using `isEqual` is necessary because the block state is an object.

:::

## Create the block state when initializing the form

The block state needs to be created when initializing the form.
If a product exists (i.e., in edit mode), transform the block input to the block state.
When creating a new product, use the block's default values:

```tsx
import { BlockState } from "@comet/blocks-admin";
import isEqual from "lodash.isequal";

type FormValues = Omit<GQLProductFormFragment, "image"> & {
// highlight-next-line
image: BlockState<typeof DamImageBlock>;
};

const { data } = useQuery(productFormQuery, id ? { variables: { id } } : { skip: true });

const initialValues = useMemo<Partial<FormValues>>(
() =>
data?.product
? {
...filterByFragment<GQLProductFormFragment>(productFormFragment, data.product),
// highlight-next-line
image: DamImageBlock.input2State(data.product.image),
}
: {
inStock: false,
// highlight-next-line
image: DamImageBlock.defaultValues(),
},
[data],
);

<FinalForm
// highlight-next-line
initialValues={initialValues}
initialValuesEqual={isEqual}
/>;
```

:::note

A deep equality check using `initialValuesEqual` is necessary when using blocks in a form.

:::

## Create the block output when submitting the form

Transform the block state to the block output before submitting the form:

```tsx
const handleSubmit = async (values: FormValues) => {
const input = {
...values,
// highlight-next-line
image: DamImageBlock.state2Output(values.image),
};

/* Create or update the product... */
};
```
2 changes: 1 addition & 1 deletion docs/docs/blocks/composition.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Composition
sidebar_position: 4
sidebar_position: 5
---

# Composing blocks
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/blocks/lifecycle.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Lifecycle
sidebar_position: 5
sidebar_position: 7
---

# Deep dive: A block's lifecycle
Expand Down
Loading