diff --git a/packages/snaps-sdk/src/jsx/components/SettingCell.test.tsx b/packages/snaps-sdk/src/jsx/components/SettingCell.test.tsx
new file mode 100644
index 0000000000..2312e059b7
--- /dev/null
+++ b/packages/snaps-sdk/src/jsx/components/SettingCell.test.tsx
@@ -0,0 +1,28 @@
+import { Input } from './form';
+import { SettingCell } from './SettingCell';
+
+describe('SettingCell', () => {
+ it('renders a setting cell', () => {
+ const result = (
+
+
+
+ );
+
+ expect(result).toStrictEqual({
+ type: 'SettingCell',
+ key: null,
+ props: {
+ title: 'Title',
+ description: 'Description',
+ children: {
+ type: 'Input',
+ key: null,
+ props: {
+ name: 'setting1',
+ },
+ },
+ },
+ });
+ });
+});
diff --git a/packages/snaps-sdk/src/jsx/components/SettingCell.ts b/packages/snaps-sdk/src/jsx/components/SettingCell.ts
new file mode 100644
index 0000000000..53c2f74960
--- /dev/null
+++ b/packages/snaps-sdk/src/jsx/components/SettingCell.ts
@@ -0,0 +1,44 @@
+import {
+ createSnapComponent,
+ type GenericSnapElement,
+ type SnapsChildren,
+} from '../component';
+
+/**
+ * The props of the {@link SettingCell} component.
+ *
+ * @property title - The title.
+ * @property description - The description.
+ * @property children - The children to show within the cell.
+ */
+export type SettingCellProps = {
+ title: string;
+ description: string;
+ children: SnapsChildren;
+};
+
+const TYPE = 'SettingCell';
+
+/**
+ * A setting cell component which can be used to display a setting control.
+ *
+ * @param props - The props of the component.
+ * @param props.title - The title.
+ * @param props.description - The description.
+ * @param props.children - The children to show within the cell.
+ * @returns A setting cell element.
+ * @example
+ *
+ *
+ *
+ */
+export const SettingCell = createSnapComponent(
+ TYPE,
+);
+
+/**
+ * A setting cell element.
+ *
+ * @see SettingCell
+ */
+export type SettingCellElement = ReturnType;
diff --git a/packages/snaps-sdk/src/jsx/components/index.ts b/packages/snaps-sdk/src/jsx/components/index.ts
index bc64836bb2..1a6051b110 100644
--- a/packages/snaps-sdk/src/jsx/components/index.ts
+++ b/packages/snaps-sdk/src/jsx/components/index.ts
@@ -14,6 +14,7 @@ import type { ImageElement } from './Image';
import type { LinkElement } from './Link';
import type { RowElement } from './Row';
import type { SectionElement } from './Section';
+import type { SettingCellElement } from './SettingCell';
import type { SpinnerElement } from './Spinner';
import type { TextElement } from './Text';
import type { TooltipElement } from './Tooltip';
@@ -39,6 +40,7 @@ export * from './Tooltip';
export * from './Footer';
export * from './Container';
export * from './Section';
+export * from './SettingCell';
/**
* A built-in JSX element, which can be used in a Snap user interface.
@@ -63,4 +65,5 @@ export type JSXElement =
| SectionElement
| SpinnerElement
| TextElement
- | TooltipElement;
+ | TooltipElement
+ | SettingCellElement;
diff --git a/packages/snaps-sdk/src/jsx/validation.test.tsx b/packages/snaps-sdk/src/jsx/validation.test.tsx
index f755a75d70..7fdbf97d31 100644
--- a/packages/snaps-sdk/src/jsx/validation.test.tsx
+++ b/packages/snaps-sdk/src/jsx/validation.test.tsx
@@ -33,6 +33,7 @@ import {
SelectorOption,
Section,
Avatar,
+ SettingCell,
} from './components';
import {
AddressStruct,
@@ -70,6 +71,7 @@ import {
SelectorStruct,
SectionStruct,
AvatarStruct,
+ SettingCellStruct,
} from './validation';
describe('KeyStruct', () => {
@@ -1414,6 +1416,51 @@ describe('SectionStruct', () => {
});
});
+describe('SettingCellStruct', () => {
+ it.each([
+
+
+ ,
+
+
+
+
+ ,
+
+
+ ,
+ ])('validates a setting cell element', (value) => {
+ expect(is(value, SettingCellStruct)).toBe(true);
+ });
+
+ it.each([
+ 'foo',
+ 42,
+ null,
+ undefined,
+ {},
+ [],
+ // @ts-expect-error - Invalid props.
+ ,
+ // @ts-expect-error - Invalid props.
+
+
+ ,
+
+
+ ,
+
+
+
,
+ // @ts-expect-error - Invalid props.
+ ,
+ ])('does not validate "%p"', (value) => {
+ expect(is(value, SettingCellStruct)).toBe(false);
+ });
+});
+
describe('isJSXElement', () => {
it.each([
foo,
diff --git a/packages/snaps-sdk/src/jsx/validation.ts b/packages/snaps-sdk/src/jsx/validation.ts
index be3702912b..77f0e7e633 100644
--- a/packages/snaps-sdk/src/jsx/validation.ts
+++ b/packages/snaps-sdk/src/jsx/validation.ts
@@ -84,6 +84,7 @@ import {
type SelectorOptionElement,
IconName,
} from './components';
+import type { SettingCellElement } from './components/SettingCell';
/**
* A struct for the {@link Key} type.
@@ -633,6 +634,18 @@ export const SectionStruct: Describe = element('Section', {
),
});
+/**
+ * A struct for the {@link SettingCellElement} type.
+ */
+export const SettingCellStruct: Describe = element(
+ 'SettingCell',
+ {
+ children: BoxChildrenStruct,
+ title: string(),
+ description: string(),
+ },
+);
+
/**
* A subset of JSX elements that are allowed as children of the Footer component.
* This set should include a single button or a tuple of two buttons.
@@ -821,6 +834,7 @@ export const BoxChildStruct = typedUnion([
SelectorStruct,
SectionStruct,
AvatarStruct,
+ SettingCellStruct,
]);
/**
@@ -886,6 +900,7 @@ export const JSXElementStruct: Describe = typedUnion([
SelectorOptionStruct,
SectionStruct,
AvatarStruct,
+ SettingCellStruct,
]);
/**