From ba22ec8497fc24a8c41171af985602282b262b0d Mon Sep 17 00:00:00 2001 From: david0xd Date: Wed, 4 Sep 2024 16:12:03 +0200 Subject: [PATCH] Add support for more customizable input Add support for Box on both sides --- .../src/jsx/components/form/Field.test.tsx | 144 ++++++++++++++++++ .../src/jsx/components/form/Field.ts | 4 + .../snaps-sdk/src/jsx/validation.test.tsx | 25 +++ packages/snaps-sdk/src/jsx/validation.ts | 28 ++++ 4 files changed, 201 insertions(+) diff --git a/packages/snaps-sdk/src/jsx/components/form/Field.test.tsx b/packages/snaps-sdk/src/jsx/components/form/Field.test.tsx index d4ce9a8852..a5186c286a 100644 --- a/packages/snaps-sdk/src/jsx/components/form/Field.test.tsx +++ b/packages/snaps-sdk/src/jsx/components/form/Field.test.tsx @@ -1,3 +1,5 @@ +import { Box } from '../Box'; +import { Text } from '../Text'; import { Button } from './Button'; import { Dropdown } from './Dropdown'; import { Field } from './Field'; @@ -91,6 +93,148 @@ describe('Field', () => { }); }); + it('renders a field element with an input and box on the left', () => { + const result = ( + + + Hello + + + + ); + + expect(result).toStrictEqual({ + type: 'Field', + key: null, + props: { + label: 'Label', + children: [ + { + type: 'Box', + key: null, + props: { + children: { + type: 'Text', + key: null, + props: { + children: 'Hello', + }, + }, + }, + }, + { + type: 'Input', + key: null, + props: { + name: 'foo', + type: 'text', + }, + }, + ], + }, + }); + }); + + it('renders a field element with an input and box on the right', () => { + const result = ( + + + + Hello + + + ); + + expect(result).toStrictEqual({ + type: 'Field', + key: null, + props: { + label: 'Label', + children: [ + { + type: 'Input', + key: null, + props: { + name: 'foo', + type: 'text', + }, + }, + { + type: 'Box', + key: null, + props: { + children: { + type: 'Text', + key: null, + props: { + children: 'Hello', + }, + }, + }, + }, + ], + }, + }); + }); + + it('renders a field element with an input and box on both sides', () => { + const result = ( + + + Hello + + + + Hello + + + ); + + expect(result).toStrictEqual({ + type: 'Field', + key: null, + props: { + label: 'Label', + children: [ + { + type: 'Box', + key: null, + props: { + children: { + type: 'Text', + key: null, + props: { + children: 'Hello', + }, + }, + }, + }, + { + type: 'Input', + key: null, + props: { + name: 'foo', + type: 'text', + }, + }, + { + type: 'Box', + key: null, + props: { + children: { + type: 'Text', + key: null, + props: { + children: 'Hello', + }, + }, + }, + }, + ], + }, + }); + }); + it('renders a dropdown element', () => { const result = ( diff --git a/packages/snaps-sdk/src/jsx/components/form/Field.ts b/packages/snaps-sdk/src/jsx/components/form/Field.ts index 933e27d0cb..4916428517 100644 --- a/packages/snaps-sdk/src/jsx/components/form/Field.ts +++ b/packages/snaps-sdk/src/jsx/components/form/Field.ts @@ -1,4 +1,5 @@ import { createSnapComponent } from '../../component'; +import type { BoxElement } from '../Box'; import type { ButtonElement } from './Button'; import type { CheckboxElement } from './Checkbox'; import type { DropdownElement } from './Dropdown'; @@ -19,6 +20,9 @@ export type FieldProps = { error?: string | undefined; children: | [InputElement, ButtonElement] + | [BoxElement, InputElement] + | [InputElement, BoxElement] + | [BoxElement, InputElement, BoxElement] | DropdownElement | RadioGroupElement | FileInputElement diff --git a/packages/snaps-sdk/src/jsx/validation.test.tsx b/packages/snaps-sdk/src/jsx/validation.test.tsx index d470b6ee0f..ca8c6ed83d 100644 --- a/packages/snaps-sdk/src/jsx/validation.test.tsx +++ b/packages/snaps-sdk/src/jsx/validation.test.tsx @@ -235,6 +235,31 @@ describe('FieldStruct', () => { , + + + Hello + + + , + + + + Hello + + , + + + Hello + + + + Hello + + , + + + + , , diff --git a/packages/snaps-sdk/src/jsx/validation.ts b/packages/snaps-sdk/src/jsx/validation.ts index 5e04481301..53159b1fc5 100644 --- a/packages/snaps-sdk/src/jsx/validation.ts +++ b/packages/snaps-sdk/src/jsx/validation.ts @@ -293,6 +293,31 @@ const BUTTON_INPUT = [InputStruct, ButtonStruct] as [ typeof ButtonStruct, ]; +/** + * A subset of JSX elements that represent the tuple Box + Input of the Field children. + */ +const BOX_INPUT_LEFT = [BoxStruct, InputStruct] as [ + typeof BoxStruct, + typeof InputStruct, +]; + +/** + * A subset of JSX elements that represent the tuple Input + Box of the Field children. + */ +const BOX_INPUT_RIGHT = [InputStruct, BoxStruct] as [ + typeof InputStruct, + typeof BoxStruct, +]; + +/** + * A subset of JSX elements that represent the tuple Box + Input + Box of the Field children. + */ +const BOX_INPUT_BOTH = [BoxStruct, InputStruct, BoxStruct] as [ + typeof BoxStruct, + typeof InputStruct, + typeof BoxStruct, +]; + /** * A subset of JSX elements that are allowed as single children of the Field component. */ @@ -326,6 +351,9 @@ export const FieldChildUnionStruct = typedUnion([ */ const FieldChildStruct = nullUnion([ tuple(BUTTON_INPUT), + tuple(BOX_INPUT_LEFT), + tuple(BOX_INPUT_RIGHT), + tuple(BOX_INPUT_BOTH), ...FIELD_CHILDREN_ARRAY, ]);