Skip to content

Commit

Permalink
Allow Field in Box (#2926)
Browse files Browse the repository at this point in the history
This PR allows the usage of `Field` in `Box` to be able to put two field
in a row.
  • Loading branch information
GuillaumeRx authored Dec 4, 2024
1 parent 6bd6fd8 commit 9c826e9
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/snaps.git"
},
"source": {
"shasum": "4yLB19XYAdGgHBPFlVOzCkb/JUZCjSajPRSQWs+a3uE=",
"shasum": "d1js9Y4zJwk7n/e47V5fdMreo1FBtVKl4GtPhfckZrs=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/examples/packages/browserify/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/snaps.git"
},
"source": {
"shasum": "+0hxp1uhfCqe9KR+4RPDSPGHFTgRyGULKLn9XWwCmsY=",
"shasum": "VvMm+Zet1+q467UNweIuLLtYVoHoJdTeNjZn0xnEwO8=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
15 changes: 15 additions & 0 deletions packages/snaps-controllers/src/interface/utils.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,21 @@ describe('constructState', () => {
});
});

it('handles root level Field', () => {
const element = (
<Box>
<Field label="foo">
<Input name="foo" type="text" value="bar" />
</Field>
</Box>
);

const result = constructState({}, element);
expect(result).toStrictEqual({
foo: 'bar',
});
});

it('handles root level inputs with value', () => {
const element = (
<Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Form,
Container,
Footer,
Copyable,
} from '@metamask/snaps-sdk/jsx';
import type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';

Expand Down Expand Up @@ -140,7 +141,7 @@ describe('snap_createInterface', () => {
error: {
code: -32602,
message:
'Invalid params: At path: ui -- Expected type to be one of: "Address", "Bold", "Box", "Button", "Copyable", "Divider", "Dropdown", "RadioGroup", "FileInput", "Form", "Heading", "Input", "Image", "Italic", "Link", "Row", "Spinner", "Text", "Tooltip", "Checkbox", "Card", "Icon", "Selector", "Section", "Avatar", "Container", but received: undefined.',
'Invalid params: At path: ui -- Expected type to be one of: "Address", "Bold", "Box", "Button", "Copyable", "Divider", "Dropdown", "RadioGroup", "Field", "FileInput", "Form", "Heading", "Input", "Image", "Italic", "Link", "Row", "Spinner", "Text", "Tooltip", "Checkbox", "Card", "Icon", "Selector", "Section", "Avatar", "Container", but received: undefined.',
stack: expect.any(String),
},
id: 1,
Expand Down Expand Up @@ -179,7 +180,7 @@ describe('snap_createInterface', () => {
ui: (
<Box>
<Field label="Input">
<Input name="input" />
<Copyable value="foo" />
</Field>
</Box>
) as JSXElement,
Expand All @@ -190,7 +191,7 @@ describe('snap_createInterface', () => {
error: {
code: -32602,
message:
'Invalid params: At path: ui.props.children -- Expected type to be one of: "Address", "Bold", "Box", "Button", "Copyable", "Divider", "Dropdown", "RadioGroup", "FileInput", "Form", "Heading", "Input", "Image", "Italic", "Link", "Row", "Spinner", "Text", "Tooltip", "Checkbox", "Card", "Icon", "Selector", "Section", "Avatar", but received: "Field".',
'Invalid params: At path: ui.props.children.props.children -- Expected the value to satisfy a union of `tuple | tuple | tuple | object | object | object | object | object | object`, but received: [object Object].',
stack: expect.any(String),
},
id: 1,
Expand Down
3 changes: 1 addition & 2 deletions packages/snaps-sdk/src/jsx/components/form/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ export type FieldProps = {
const TYPE = 'Field';

/**
* A field component, which is used to create a form field. This component can
* only be used as a child of the {@link Form} component.
* A field component, which is used to create a form field.
*
* @param props - The props of the component.
* @param props.label - The label of the field.
Expand Down
10 changes: 5 additions & 5 deletions packages/snaps-sdk/src/jsx/validation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,11 @@ describe('BoxStruct', () => {
<Text>foo</Text>
<Text>bar</Text>
</Box>,
<Box>
<Field label="foo">
<Input name="foo" />
</Field>
</Box>,
<Box>
<Text>foo</Text>
<Row label="label">
Expand Down Expand Up @@ -620,11 +625,6 @@ describe('BoxStruct', () => {
<Image src="<svg />" alt="alt" />
</Row>
</Box>,
<Box>
<Field label="foo">
<Input name="foo" />
</Field>
</Box>,
<Box>
<Value extra="foo" value="bar" />
</Box>,
Expand Down
30 changes: 14 additions & 16 deletions packages/snaps-sdk/src/jsx/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,22 +507,6 @@ export const FieldStruct: Describe<FieldElement> = element('Field', {
children: FieldChildStruct,
});

/**
* A subset of JSX elements that are allowed as children of the Form component.
*/
export const FormChildStruct = children(
// eslint-disable-next-line @typescript-eslint/no-use-before-define
[FieldStruct, lazy(() => BoxChildStruct)],
) as unknown as Struct<SnapsChildren<GenericSnapElement>, null>;

/**
* A struct for the {@link FormElement} type.
*/
export const FormStruct: Describe<FormElement> = element('Form', {
children: FormChildStruct,
name: string(),
});

/**
* A struct for the {@link BoldElement} type.
*/
Expand Down Expand Up @@ -584,6 +568,19 @@ export const BoxStruct: Describe<BoxElement> = element('Box', {
center: optional(boolean()),
});

/**
* A subset of JSX elements that are allowed as children of the Form component.
*/
export const FormChildStruct = BoxChildrenStruct;

/**
* A struct for the {@link FormElement} type.
*/
export const FormStruct: Describe<FormElement> = element('Form', {
children: FormChildStruct,
name: string(),
});

const FooterButtonStruct = refine(ButtonStruct, 'FooterButton', (value) => {
if (
typeof value.props.children === 'string' ||
Expand Down Expand Up @@ -796,6 +793,7 @@ export const BoxChildStruct = typedUnion([
DividerStruct,
DropdownStruct,
RadioGroupStruct,
FieldStruct,
FileInputStruct,
FormStruct,
HeadingStruct,
Expand Down
5 changes: 3 additions & 2 deletions packages/snaps-simulator/src/features/builder/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Copyable,
Heading,
Option,
Container,
} from '@metamask/snaps-sdk/jsx';
import type { NodeModel } from '@minoru/react-dnd-treeview';

Expand All @@ -30,7 +31,7 @@ describe('isValidBoxChild', () => {
});

it('returns false for invalid box children', () => {
const child = Field({ children: Input({ name: 'input' }) });
const child = Container({ children: Input({ name: 'input' }) });
expect(isValidBoxChild(child)).toBe(false);
});
});
Expand Down Expand Up @@ -80,7 +81,7 @@ describe('setElementChildren', () => {
const element = Box({
children: [Text({ children: 'foo' }), Heading({ children: 'baz' })],
});
const children = Field({ children: Input({ name: 'input' }) });
const children = Container({ children: Input({ name: 'input' }) });

const result = setElementChildren(element, children, isValidBoxChild);
expect(result).toStrictEqual(element.props.children);
Expand Down

0 comments on commit 9c826e9

Please sign in to comment.