diff --git a/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.mock.tsx b/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.mock.tsx
index 2cb1e356..e26621bb 100644
--- a/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.mock.tsx
+++ b/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.mock.tsx
@@ -1,13 +1,8 @@
import type { IFormDynBlock, IFormField, IFormRegisterFunc } from '../../types';
import type { ReactElement } from 'react';
-import { Alien, Cube, Leaf, TreasureChest } from '@phosphor-icons/react';
-
-export const blockOptionsMock = [
- { id: 'default', label: 'Default', leftSection: },
- { id: 'other', label: 'Other', leftSection: },
- { id: 'stuff', label: 'Stuff', leftSection: },
-];
+import { Group } from '@mantine/core';
+import { Cube, Leaf } from '@phosphor-icons/react';
export const dynamicBlocksMock: IFormDynBlock[] = [
{
@@ -15,16 +10,16 @@ export const dynamicBlocksMock: IFormDynBlock[] = [
blockHeader: (
<>
- Example
+ Example A
>
),
- blockType: 'default',
+ blockType: 'exampleA',
opened: true,
- value: 'initial',
+ value: '',
},
button: {
- blockType: 'default',
- label: 'Example',
+ blockType: 'exampleA',
+ label: 'Example A',
leftSection: ,
},
renderFunc: (
@@ -34,10 +29,63 @@ export const dynamicBlocksMock: IFormDynBlock[] = [
registerName: string,
): ReactElement => {
return (
+
+
+
+
+ );
+ },
+ },
+ {
+ block: {
+ blockHeader: (
<>
- works
-
+
+ Example B
>
+ ),
+ blockType: 'exampleB',
+ opened: true,
+ value: '',
+ },
+ button: {
+ blockType: 'exampleB',
+ label: 'Example B',
+ leftSection: ,
+ },
+ renderFunc: (
+ b: IFormField,
+ _i: number,
+ register: IFormRegisterFunc,
+ registerName: string,
+ ): ReactElement => {
+ return (
+
);
},
},
diff --git a/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.stories.tsx b/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.stories.tsx
index c0a2d56b..0a6cb153 100644
--- a/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.stories.tsx
+++ b/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.stories.tsx
@@ -2,6 +2,7 @@ import type { IFormDynamicZoneProps } from './FormDynamicZone';
import type { Meta, StoryObj } from '@storybook/react';
import type { ReactElement } from 'react';
+import { action } from '@storybook/addon-actions';
import { FormProvider, useForm } from 'react-hook-form';
import { FormDynamicZone as Cmp } from './FormDynamicZone';
@@ -30,6 +31,10 @@ function render() {
}
export const FormDynamicZone: IStory = {
- args: { dynamicBlocks: dynamicBlocksMock, dynamicZoneName: 'dynTest' },
+ args: {
+ dynamicBlocks: dynamicBlocksMock,
+ dynamicZoneName: 'dynTest',
+ onFormSubmit: action('results'),
+ },
render: render(),
};
diff --git a/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.test.tsx b/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.test.tsx
index 193e3a5a..f5f2f9d5 100644
--- a/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.test.tsx
+++ b/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.test.tsx
@@ -1,6 +1,7 @@
import type { ReactElement } from 'react';
import { renderWithProviders } from '@smile/haring-react-shared/test-utils';
+import { action } from '@storybook/addon-actions';
import { FormProvider, useForm } from 'react-hook-form';
import { FormDynamicZone } from './FormDynamicZone';
@@ -15,6 +16,7 @@ describe('FormDynamicZone', () => {
);
diff --git a/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.tsx b/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.tsx
index 19ddef54..0b88028f 100644
--- a/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.tsx
+++ b/packages/haring-react-hook-form/src/Components/FormDynamicZone/FormDynamicZone.tsx
@@ -1,6 +1,7 @@
import type {
IFormDynBlock,
IFormDynSubmit,
+ IFormDynSubmitResults,
IFormField,
IFormFieldWithoutId,
} from '../../types';
@@ -30,6 +31,7 @@ export interface IFormDynamicZoneProps {
actionLabels?: IFormDynamicZoneActionLabels;
dynamicBlocks: IFormDynBlock[];
dynamicZoneName: string;
+ onFormSubmit: (data: IFormDynSubmitResults) => void;
}
export function FormDynamicZone(props: IFormDynamicZoneProps): ReactElement {
@@ -37,9 +39,10 @@ export function FormDynamicZone(props: IFormDynamicZoneProps): ReactElement {
dynamicBlocks,
dynamicZoneName,
actionLabels = defaultActionLabels,
+ onFormSubmit,
} = props;
- const { control, register, handleSubmit } =
+ const { control, register, handleSubmit, getValues } =
useFormContext>();
const { fields, append, remove, swap, update } = useFieldArray({
control,
@@ -78,9 +81,9 @@ export function FormDynamicZone(props: IFormDynamicZoneProps): ReactElement {
}
}
- function onToggle(block: IFormField, index: number, opened: boolean): void {
- const { id, ...blockWithoutId } = block;
- update(index, { ...blockWithoutId, opened });
+ function onToggle(_block: IFormField, index: number, opened: boolean): void {
+ const updatedBlock = getValues(dynamicZoneName)[index];
+ update(index, { ...updatedBlock, opened });
}
function isMoveDisabled(
@@ -131,7 +134,11 @@ export function FormDynamicZone(props: IFormDynamicZoneProps): ReactElement {
}
function onSubmit(data: IFormDynSubmit): void {
- console.log(data);
+ onFormSubmit(
+ data[dynamicZoneName].map(
+ ({ blockActions, blockHeader, blockFooter, ...block }) => block,
+ ),
+ );
}
return (
@@ -147,6 +154,11 @@ export function FormDynamicZone(props: IFormDynamicZoneProps): ReactElement {
onRenderBlockContent={renderBlock}
onToggleBlock={onToggle}
/>
+ {/* TODO: Move this out, should be in the story/text not part of this component since it's just a field */}
+ {/* TODO: then decide how to send errors/messages upwards, where they can go (everything should be doable with props) */}
+ {/* TODO: build mock example of error messages and where they can go (at the form level, somewhere inside this component, in blocks... */}
+ {/* TODO: then focus and nested focus, multiple errors, auto-opening a block if it wants to focus inside, auto-scroll the page */}
+ {/* TODO: then animations */}
diff --git a/packages/haring-react-hook-form/src/Components/FormDynamicZone/__snapshots__/FormDynamicZone.test.tsx.snap b/packages/haring-react-hook-form/src/Components/FormDynamicZone/__snapshots__/FormDynamicZone.test.tsx.snap
index ec2bf540..9a52dfb1 100644
--- a/packages/haring-react-hook-form/src/Components/FormDynamicZone/__snapshots__/FormDynamicZone.test.tsx.snap
+++ b/packages/haring-react-hook-form/src/Components/FormDynamicZone/__snapshots__/FormDynamicZone.test.tsx.snap
@@ -43,7 +43,7 @@ exports[`FormDynamicZone matches snapshot 1`] = `
data-size="md"
data-variant="default"
data-with-left-section="true"
- label="Example"
+ label="Example A"
style="--button-height: var(--button-height-md); --button-padding-x: var(--button-padding-x-md); --button-fz: var(--mantine-font-size-md); --button-radius: var(--mantine-radius-md); --button-bg: var(--mantine-color-default); --button-hover: var(--mantine-color-default-hover); --button-color: var(--mantine-color-default-color); --button-bd: calc(0.0625rem * var(--mantine-scale)) solid var(--mantine-color-default-border);"
type="button"
>
@@ -69,7 +69,42 @@ exports[`FormDynamicZone matches snapshot 1`] = `
- Example
+ Example A
+
+
+
+
diff --git a/packages/haring-react-hook-form/src/types/form-dynamic-zone.ts b/packages/haring-react-hook-form/src/types/form-dynamic-zone.ts
index 1c801af8..5a0a69f7 100644
--- a/packages/haring-react-hook-form/src/types/form-dynamic-zone.ts
+++ b/packages/haring-react-hook-form/src/types/form-dynamic-zone.ts
@@ -29,3 +29,7 @@ export interface IFormDynBlock {
}
export type IFormDynSubmit = Record;
+export type IFormDynSubmitResults = IOmitRespectIndexSignature<
+ IFormFieldWithoutId,
+ 'blockActions' | 'blockFooter' | 'blockHeader'
+>[];