diff --git a/docs/whats-new.md b/docs/whats-new.md
index a79f4eec3f5..c08ce17629c 100644
--- a/docs/whats-new.md
+++ b/docs/whats-new.md
@@ -9,6 +9,11 @@ The latest major MetaMask documentation updates are listed by the month they wer
For a comprehensive list of recent product changes, visit the "Release Notes" section at the bottom
of the [MetaMask developer page](https://metamask.io/developer/).
+## January 2025
+
+- Documented Snaps [`Banner`](/snaps/features/custom-ui/#banner), [`Container`](/snaps/features/custom-ui/#container), [`Footer`](/snaps/features/custom-ui/#footer), [`Skeleton`](/snaps/features/custom-ui/#skeleton), and [`Value`](/snaps/features/custom-ui/#value) UI components.
+ ([#1835](https://github.com/MetaMask/metamask-docs/pull/1835))
+
## December 2024
- Documented [Swellchain](/services/reference/swellchain) support. ([#1776](https://github.com/MetaMask/metamask-docs/pull/1776))
diff --git a/snaps/features/custom-ui/index.md b/snaps/features/custom-ui/index.md
index 232bdf2f234..6ae90aa7d2f 100644
--- a/snaps/features/custom-ui/index.md
+++ b/snaps/features/custom-ui/index.md
@@ -65,13 +65,16 @@ The following custom UI components are available:
Outputs a formatted text field for a blockchain address.
The address is automatically displayed with a [Jazzicon](https://www.npmjs.com/package/@metamask/jazzicon)
-and truncated value.
-Hovering over the address shows the full value in a tooltip.
+and truncated value.
#### Props
- `address`: `string` - A valid Ethereum address, starting with `0x`, or a valid
[CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) address.
+- `truncate`: `boolean` - (Optional) Whether to truncate the address. The default is `true`.
+- `displayName`: `boolean` - (Optional) Whether to display the internally saved account label in place of the address.
+ The default is `true`.
+- `avatar`: `boolean` - (Optional) Whether to show the address Jazzicon. The default is `true`.
#### Example
@@ -133,15 +136,16 @@ await snap.request({
Outputs a [Jazzicon](https://www.npmjs.com/package/@metamask/jazzicon) for an address.
+#### Props
+
+- `address`: `string` - A valid [CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) address.
+- `size`: `string` - (Optional) The size of the avatar. Possible values are `"sm"`, `"md"`, and `"lg"`. The default is `"md"`.
+
:::note
MetaMask automatically calculates checksums for EVM addresses (`eip155:`).
Addresses for other namespaces are not validated; you should validate them in your Snap.
:::
-#### Props
-
-- `address`: `string` - A valid [CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) address.
-
#### Example
```js
@@ -149,7 +153,7 @@ export const onHomePage: OnHomePageHandler = async () => {
return {
content: (
-
+
),
@@ -157,6 +161,51 @@ export const onHomePage: OnHomePageHandler = async () => {
};
```
+### `Banner`
+
+Outputs a banner that can be used to display important messages with different severity levels.
+
+#### Props
+
+- `title`: `string` - The title of the banner.
+- `severity` - The severity level of the banner.
+ Possible values are `"danger"`, `"info"`, `"success"`, and `"warning"`.
+- `children` - The content to display in the banner.
+ This can include [`Text`](#text), [`Link`](#link) [`Icon`](#icon), [`Button`](#button), and [`Skeleton`](#skeleton) components.
+
+#### Example
+
+```javascript title="index.jsx"
+import { Box, Banner, Text, Link } from "@metamask/snaps-sdk/jsx";
+
+await snap.request({
+ method: "snap_dialog",
+ params: {
+ type: "alert",
+ content: (
+
+
+ A new version is available!
+ Learn more
+
+
+
+ Please review transaction details carefully.
+
+
+
+ Transaction completed successfully.
+
+
+
+ Unable to process transaction.
+
+
+ ),
+ },
+});
+```
+
### `Bold`
Outputs bold text.
@@ -194,6 +243,8 @@ Outputs a box, which can be used as a container for other components.
- `alignment` - (Optional) The alignment of the elements inside the box.
Possible values are `"start"`, `"center"`, `"end"`, `"space-between"`, and `"space-around"`.
The default is `"start"`.
+- `center`: `boolean` - (Optional) Whether to center the children within the box.
+ The default is `false`.
#### Example
@@ -208,6 +259,7 @@ module.exports.onHomePage = async () => {
Feature 1Feature 2
@@ -343,8 +395,7 @@ Outputs a checkbox for use in [interactive UI](interactive-ui.md).
- `name`: `string` - The name sent to [`onUserInput`](../../reference/entry-points.md#onuserinput).
- `checked`: `boolean` - (Optional) Whether the checkbox is checked.
- `label`: `string` - (Optional) The label for the checkbox.
-- `variant` - (Optional) The variant of the checkbox.
- Possible values are `"default"` and `"toggle"`.
+- `variant` - (Optional) The variant of the checkbox. Possible values are `"default"` and `"toggle"`.
The default is `"default"`.
#### Example
@@ -369,6 +420,56 @@ const interfaceId = await snap.request({
+### `Container`
+
+Outputs a container component that can hold a box of content and an optional footer. This is useful for creating structured layouts with action buttons at the bottom in [custom dialogs](dialogs.md#display-a-custom-dialog).
+
+#### Props
+
+- `backgroundColor` - (Optional) The background color of the container.
+ Possible values are `"default"` and `"alternative"`.
+ The default is `"default"`.
+- `children`: The contents of the container.
+ This can be a single [`Box`](#box) component, or an array containing a [`Box`](#box) component and a [`Footer`](#footer) component.
+
+#### Example
+
+```javascript title="index.jsx"
+import { Container, Box, Footer, Text, Button } from "@metamask/snaps-sdk/jsx";
+
+await snap.request({
+ method: "snap_dialog",
+ params: {
+ content: (
+
+
+ Are you sure you want to proceed with this transaction?
+ Gas fees: 0.005 ETH
+
+
+
+ ),
+ },
+});
+
+// Example without footer
+await snap.request({
+ method: "snap_dialog",
+ params: {
+ content: (
+
+
+ Simple container without footer
+
+
+ ),
+ },
+});
+```
+
### `Copyable`
Outputs a read-only text field with a copy-to-clipboard shortcut.
@@ -576,6 +677,56 @@ export const onUserInput = async ({ id, event }) => {
+### `Footer`
+
+Outputs a footer that can contain one or two buttons. This component is typically used within a [`Container`](#container) to create action buttons at the bottom of a dialog or panel.
+
+#### Props
+
+- `children` - The contents of the footer.
+ This can be one or two [`Button`](#button) components.
+
+#### Example
+
+```javascript title="index.jsx"
+import { Container, Box, Footer, Text, Button } from "@metamask/snaps-sdk/jsx";
+
+// Example with two buttons
+await snap.request({
+ method: "snap_dialog",
+ params: {
+ content: (
+
+
+ Delete this item?
+
+
+
+ ),
+ },
+});
+
+// Example with single button
+await snap.request({
+ method: "snap_dialog",
+ params: {
+ content: (
+
+
+ Operation completed successfully.
+
+
+
+ ),
+ },
+});
+```
+
### `Form`
Outputs a form for use in [interactive UI](interactive-ui.md).
@@ -925,7 +1076,7 @@ Outputs a row with a label and value, which can be used for key-value data.
Possible values are `"default"`, `"error"`, and `"warning"`.
The default is `"default"`.
- `children` - The value of the row, which can be a [`Text`](#text), [`Image`](#image),
- [`Address`](#address), or [`Link`](#link) component.
+ [`Address`](#address), [`Link`](#link), or [`Value`](#value) component.
#### Example
@@ -1025,9 +1176,39 @@ const interfaceId = await snap.request({
+### `Skeleton`
+
+Outputs an animated loading container.
+
+#### Props
+
+- `width`: `Array` - (Optional) The width of the skeleton. The default is `"100%"`.
+- `height`: `Array` - (Optional) The height of the skeleton. The default is `22`.
+- `borderRadius`: `string` - (Optional) The radius of the corners. Possible values are `"none"`, `"medium"` or `"full"`.
+ The default is `"medium"`.
+
+#### Example
+
+```javascript title="index.jsx"
+import { Box, Heading, Skeleton } from "@metamask/snaps-sdk/jsx";
+
+await snap.request({
+ method: "snap_dialog",
+ params: {
+ type: "alert",
+ content: (
+
+ Please wait...
+
+
+ ),
+ },
+});
+```
+
### `Spinner`
-Outputs a loading indicator.
+Outputs an animated loading indicator.
#### Example
@@ -1064,6 +1245,8 @@ Outputs text.
- `alignment` - (Optional) The alignment of the text.
Possible values are `"start"`, `"center"`, and `"end"`.
The default is `"start"`.
+- `children` - The content to display.
+ This can include strings, and [`Bold`](#bold), [`Italic`](#italic), [`Icon`](#icon), [`Link`](#link), and [`Skeleton`](#skeleton) components.
#### Example
@@ -1126,6 +1309,53 @@ await snap.request({
+### `Value`
+
+Outputs a component that displays two text values side by side. This component can only be used as a child of the [`Row`](#row) component.
+
+#### Props
+
+- `value` - The value shown on the right side.
+ This can be a string or a [`Text`](#text) component.
+- `extra` - The extra text shown on the left side.
+ This can be a string or a [`Text`](#text) component.
+
+#### Example
+
+```javascript title="index.jsx"
+import { Box, Row, Text, Value } from "@metamask/snaps-sdk/jsx";
+
+await snap.request({
+ method: "snap_dialog",
+ params: {
+ type: "alert",
+ content: (
+
+
+
+
+
+ {/* Example with styled text */}
+
+ 0.003 ETH}
+ extra={$12}
+ />
+
+
+ {/* Example with different text colors */}
+
+ 1.25 ETH}
+ extra={$2,500}
+ />
+
+
+ ),
+ },
+});
+```
+
## Emojis
Text-based components (such as [`Heading`](#heading) and [`Text`](#text)) accept emojis.