diff --git a/packages/snaps-sdk/src/jsx/components/Row.ts b/packages/snaps-sdk/src/jsx/components/Row.ts
index b64511150f..44dc409f24 100644
--- a/packages/snaps-sdk/src/jsx/components/Row.ts
+++ b/packages/snaps-sdk/src/jsx/components/Row.ts
@@ -2,6 +2,7 @@ import { createSnapComponent } from '../component';
import type { AddressElement } from './Address';
import type { ImageElement } from './Image';
import type { LinkElement } from './Link';
+import type { SkeletonElement } from './Skeleton';
import type { TextElement } from './Text';
import type { ValueElement } from './Value';
@@ -13,7 +14,8 @@ export type RowChildren =
| ImageElement
| TextElement
| ValueElement
- | LinkElement;
+ | LinkElement
+ | SkeletonElement;
/**
* The props of the {@link Row} component.
diff --git a/packages/snaps-sdk/src/jsx/components/Skeleton.test.tsx b/packages/snaps-sdk/src/jsx/components/Skeleton.test.tsx
new file mode 100644
index 0000000000..6869203534
--- /dev/null
+++ b/packages/snaps-sdk/src/jsx/components/Skeleton.test.tsx
@@ -0,0 +1,17 @@
+import { Skeleton } from './Skeleton';
+
+describe('Skeleton', () => {
+ it('renders a skeleton component', () => {
+ const result = ;
+
+ expect(result).toStrictEqual({
+ type: 'Skeleton',
+ key: null,
+ props: {
+ width: 320,
+ height: 32,
+ borderRadius: 'medium',
+ },
+ });
+ });
+});
diff --git a/packages/snaps-sdk/src/jsx/components/Skeleton.ts b/packages/snaps-sdk/src/jsx/components/Skeleton.ts
new file mode 100644
index 0000000000..d45e821851
--- /dev/null
+++ b/packages/snaps-sdk/src/jsx/components/Skeleton.ts
@@ -0,0 +1,40 @@
+import { createSnapComponent } from '../component';
+
+/**
+ * Definition of Skeleton border radius.
+ */
+export type SkeletonBorderRadius = 'none' | 'medium' | 'full' | undefined;
+
+/**
+ * The props of the {@link Skeleton} component.
+ *
+ * @param width - Width of the Skeleton.
+ * @param width - Height of the Skeleton.
+ * @param borderRadius - Border radius of the Skeleton.
+ */
+export type SkeletonProps = {
+ width: number | string;
+ height: number | string;
+ borderRadius?: SkeletonBorderRadius | undefined;
+};
+
+const TYPE = 'Skeleton';
+
+/**
+ * A Skeleton component, which is used to display skeleton of loading content.
+ *
+ * @param props - The props of the component.
+ * @param props.width - Width of the Skeleton.
+ * @param props.width - Height of the Skeleton.
+ * @param props.borderRadius - Border radius of the Skeleton.
+ * @example
+ *
+ */
+export const Skeleton = createSnapComponent(TYPE);
+
+/**
+ * A Skeleton element.
+ *
+ * @see Skeleton
+ */
+export type SkeletonElement = ReturnType;
diff --git a/packages/snaps-sdk/src/jsx/components/index.ts b/packages/snaps-sdk/src/jsx/components/index.ts
index d26cbcd338..132faee1f1 100644
--- a/packages/snaps-sdk/src/jsx/components/index.ts
+++ b/packages/snaps-sdk/src/jsx/components/index.ts
@@ -15,6 +15,7 @@ import type { ImageElement } from './Image';
import type { LinkElement } from './Link';
import type { RowElement } from './Row';
import type { SectionElement } from './Section';
+import type { SkeletonElement } from './Skeleton';
import type { SpinnerElement } from './Spinner';
import type { TextElement } from './Text';
import type { TooltipElement } from './Tooltip';
@@ -41,6 +42,7 @@ export * from './Footer';
export * from './Container';
export * from './Section';
export * from './Banner';
+export * from './Skeleton';
/**
* A built-in JSX element, which can be used in a Snap user interface.
@@ -66,4 +68,5 @@ export type JSXElement =
| SpinnerElement
| TextElement
| TooltipElement
- | BannerElement;
+ | BannerElement
+ | SkeletonElement;
diff --git a/packages/snaps-sdk/src/jsx/validation.test.tsx b/packages/snaps-sdk/src/jsx/validation.test.tsx
index c656ac598f..ac927cb01b 100644
--- a/packages/snaps-sdk/src/jsx/validation.test.tsx
+++ b/packages/snaps-sdk/src/jsx/validation.test.tsx
@@ -34,6 +34,7 @@ import {
Section,
Avatar,
Banner,
+ Skeleton,
} from './components';
import {
AddressStruct,
@@ -72,6 +73,7 @@ import {
SectionStruct,
AvatarStruct,
BannerStruct,
+ SkeletonStruct,
} from './validation';
describe('KeyStruct', () => {
@@ -1618,3 +1620,35 @@ describe('BannerStruct', () => {
expect(is(value, BannerStruct)).toBe(false);
});
});
+
+describe('SkeletonStruct', () => {
+ it.each([
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ])(`validates a Skeleton element`, (value) => {
+ expect(is(value, SkeletonStruct)).toBe(true);
+ });
+
+ it.each([
+ 'foo',
+ 42,
+ null,
+ undefined,
+ {},
+ [],
+ // @ts-expect-error - Invalid props.
+ ,
+ // @ts-expect-error - Invalid props.
+ foo,
+ // @ts-expect-error - Invalid props.
+ } severity="info">
+ foo
+ ,
+ ])('does not validate "%p"', (value) => {
+ expect(is(value, SkeletonStruct)).toBe(false);
+ });
+});
diff --git a/packages/snaps-sdk/src/jsx/validation.ts b/packages/snaps-sdk/src/jsx/validation.ts
index 5b6c03a5e1..a6366da1c9 100644
--- a/packages/snaps-sdk/src/jsx/validation.ts
+++ b/packages/snaps-sdk/src/jsx/validation.ts
@@ -48,7 +48,7 @@ import type {
SnapsChildren,
StringElement,
} from './component';
-import type { AvatarElement } from './components';
+import type { AvatarElement, SkeletonElement } from './components';
import {
type AddressElement,
type BoldElement,
@@ -807,6 +807,17 @@ export const BannerStruct: Describe = element('Banner', {
]),
});
+/**
+ * A struct for the {@link SkeletonElement} type.
+ */
+export const SkeletonStruct: Describe = element('Skeleton', {
+ width: union([number(), string()]),
+ height: union([number(), string()]),
+ borderRadius: optional(
+ nullUnion([literal('none'), literal('medium'), literal('full')]),
+ ),
+});
+
/**
* A struct for the {@link RowElement} type.
*/
@@ -818,6 +829,7 @@ export const RowStruct: Describe = element('Row', {
TextStruct,
ValueStruct,
LinkStruct,
+ SkeletonStruct,
]),
variant: optional(
nullUnion([literal('default'), literal('warning'), literal('critical')]),
@@ -863,6 +875,7 @@ export const BoxChildStruct = typedUnion([
SectionStruct,
AvatarStruct,
BannerStruct,
+ SkeletonStruct,
]);
/**
@@ -932,6 +945,7 @@ export const JSXElementStruct: Describe = typedUnion([
SectionStruct,
AvatarStruct,
BannerStruct,
+ SkeletonStruct,
]);
/**