Skip to content

Commit 068789b

Browse files
Merge branch 'main' into feat-multi-api
2 parents d3e107e + 7e966fa commit 068789b

File tree

4 files changed

+119
-3
lines changed

4 files changed

+119
-3
lines changed

docs/whats-new.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ of the [MetaMask developer page](https://metamask.io/developer/).
1919
([#1494](https://github.com/MetaMask/metamask-docs/pull/1494))
2020
- Documented [`snap_getPreferences`](/snaps/reference/snaps-api/#snap_getpreferences).
2121
([#1681](https://github.com/MetaMask/metamask-docs/pull/1681))
22+
- Documented [Snaps custom UI dialogs](/snaps/features/custom-ui/dialogs).
23+
([#1682](https://github.com/MetaMask/metamask-docs/pull/1682))
2224

2325
## September 2024
2426

snaps/assets/custom-dialog.png

64.9 KB
Loading

snaps/features/custom-ui/dialogs.md

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ You can display a dialog in the MetaMask UI using the
99
[`snap_dialog`](../../reference/snaps-api.md#snap_dialog) API method.
1010
Dialogs can contain [custom UI](index.md) and [interactive UI](interactive-ui.md) components.
1111

12-
There are three types of dialogs: [alerts](#display-an-alert-dialog),
13-
[confirmations](#display-a-confirmation-dialog), and [prompts](#display-a-prompt-dialog).
12+
There are four types of dialogs: [alerts](#display-an-alert-dialog),
13+
[confirmations](#display-a-confirmation-dialog), [prompts](#display-a-prompt-dialog), and
14+
[custom dialogs](#display-a-custom-dialog).
1415

1516
:::caution
1617
Dialogs do not work when MetaMask is locked.
@@ -122,6 +123,103 @@ const walletAddress = await snap.request({
122123
<img src={require("../../assets/prompt-dialog.png").default} alt="Prompt dialog example" width="360px" style={{border: "1px solid #DCDCDC"}} />
123124
</p>
124125

126+
## Display a custom dialog
127+
128+
To display a custom dialog, call [`snap_dialog`](../../reference/snaps-api.md#snap_dialog)
129+
without providing a `type`. Custom dialogs can be resolved by calling [`snap_resolveInterface`](../../reference/snaps-api.md#snap_resolveinterface). The UI passed to a custom dialog should contain a `Footer` element. Its buttons will be displayed at the bottom of the dialog. Here is a complete example:
130+
131+
```tsx title="index.tsx"
132+
import {
133+
UserInputEventType,
134+
type OnRpcRequestHandler,
135+
type OnUserInputHandler,
136+
} from "@metamask/snaps-sdk";
137+
import {
138+
Box,
139+
Text,
140+
Heading,
141+
Container,
142+
Footer,
143+
Button,
144+
} from "@metamask/snaps-sdk/jsx";
145+
146+
/**
147+
* Handle incoming JSON-RPC requests, sent through wallet_invokeSnap.
148+
*
149+
* @param args - The request handler args as object.
150+
* @param args.origin - The origin of the request, e.g., the website that
151+
* invoked the snap.
152+
* @param args.request - A validated JSON-RPC request object.
153+
* @returns The result of snap_dialog.
154+
* @throws If the request method is not valid for this snap.
155+
*/
156+
export const onRpcRequest: OnRpcRequestHandler = async () => {
157+
const result = await snap.request({
158+
method: "snap_dialog",
159+
params: {
160+
content: (
161+
<Container>
162+
<Box>
163+
<Heading>Custom Dialog</Heading>
164+
<Text>
165+
This is a custom dialog reproducing a confirmation dialog.
166+
<br />
167+
Do you accept?
168+
</Text>
169+
</Box>
170+
<Footer>
171+
<Button name="no">No</Button>
172+
<Button name="yes">Yes</Button>
173+
</Footer>
174+
</Container>
175+
),
176+
},
177+
});
178+
179+
console.log("result", result); // Result will be true or false.
180+
181+
return result;
182+
};
183+
184+
export const onUserInput: OnUserInputHandler = async ({ id, event }) => {
185+
if (event.type === UserInputEventType.ButtonClickEvent) {
186+
switch (event.name) {
187+
case "no": // User selected "No" in the footer.
188+
await snap.request({
189+
method: "snap_resolveInterface",
190+
params: {
191+
id,
192+
value: false,
193+
},
194+
});
195+
break;
196+
197+
case "yes": {
198+
// User selected "Yes" in the footer
199+
await snap.request({
200+
method: "snap_resolveInterface",
201+
params: {
202+
id,
203+
value: true,
204+
},
205+
});
206+
break;
207+
}
208+
209+
default:
210+
break;
211+
}
212+
}
213+
};
214+
```
215+
216+
This code outputs a custom dialog with two buttons: **Yes** and **No**.
217+
When the user selects one of the buttons, `onUserInput` is called with the button's name. From there, `snap_resolveInterface` is called. This resolves the dialog, and returns the value passed to `snap_resolveInterface` as the result of the dialog.
218+
219+
<p align="center">
220+
<img src={require("../../assets/custom-dialog.png").default} alt="Custom dialog example" width="360px" style={{border: "1px solid #DCDCDC"}} />
221+
</p>
222+
125223
## Example
126224

127225
See the [`@metamask/dialog-example-snap`](https://github.com/MetaMask/snaps/tree/main/packages/examples/packages/dialogs)

snaps/reference/snaps-api.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Displays a [dialog](../features/custom-ui/dialogs.md) in the MetaMask UI.
2525

2626
An object containing the contents of the dialog:
2727

28-
- `type` - The type of dialog.
28+
- `type` - (Optional) The type of dialog. Not providing a type will create a fully [custom dialog](../features/custom-ui/dialogs.md#display-a-custom-dialog).
2929
Possible values are:
3030
- `"alert"` - An alert that can only be acknowledged.
3131
- `"confirmation"` - A confirmation that can be accepted or rejected.
@@ -997,6 +997,22 @@ console.log(state)
997997
*/
998998
```
999999

1000+
### `snap_resolveInterface`
1001+
1002+
Resolves an interactive interface.
1003+
For use in [custom dialogs](../features/custom-ui/dialogs.md#display-a-custom-dialog).
1004+
1005+
#### Parameters
1006+
1007+
An object containing:
1008+
1009+
- `id` - The ID of the interface to be resolved.
1010+
- `result` - The result to return to the interface's caller.
1011+
1012+
#### Example
1013+
1014+
For a full example of how to use `snap_resolveInterface`, see the [custom dialogs](../features/custom-ui/dialogs.md#display-a-custom-dialog) documentation.
1015+
10001016
### `snap_updateInterface`
10011017

10021018
Updates an interactive interface.

0 commit comments

Comments
 (0)