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 1 Feature 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({ Checkbox UI example

+### `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 }) => { File input UI example

+### `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({ Selector UI example

+### `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({ Tooltip UI example

+### `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.