@@ -65,13 +65,16 @@ The following custom UI components are available:
65
65
66
66
Outputs a formatted text field for a blockchain address.
67
67
The address is automatically displayed with a [ Jazzicon] ( https://www.npmjs.com/package/@metamask/jazzicon )
68
- and truncated value.
69
- Hovering over the address shows the full value in a tooltip.
68
+ and truncated value.
70
69
71
70
#### Props
72
71
73
72
- ` address ` : ` string ` - A valid Ethereum address, starting with ` 0x ` , or a valid
74
73
[ CAIP-10] ( https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md ) address.
74
+ - ` truncate ` : ` boolean ` - (Optional) Whether to truncate the address. The default is ` true ` .
75
+ - ` displayName ` : ` boolean ` - (Optional) Whether to display the internally saved account label in place of the address.
76
+ The default is ` true ` .
77
+ - ` avatar ` : ` boolean ` - (Optional) Whether to show the address Jazzicon. The default is ` true ` .
75
78
76
79
#### Example
77
80
@@ -133,30 +136,76 @@ await snap.request({
133
136
134
137
Outputs a [Jazzicon](https://www.npmjs.com/package/@metamask/jazzicon) for an address.
135
138
139
+ #### Props
140
+
141
+ - ` address` : ` string` - A valid [CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) address.
142
+ - ` size` : ` string` - (Optional) The size of the avatar. Possible values are ` " sm" ` , ` " md" ` , and ` " lg" ` . The default is ` " md" ` .
143
+
136
144
:::note
137
145
MetaMask automatically calculates checksums for EVM addresses (` eip155: ` ).
138
146
Addresses for other namespaces are not validated; you should validate them in your Snap.
139
147
:::
140
148
141
- #### Props
142
-
143
- - ` address` : ` string` - A valid [CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) address.
144
-
145
149
#### Example
146
150
147
151
` ` ` js
148
152
export const onHomePage: OnHomePageHandler = async () => {
149
153
return {
150
154
content: (
151
155
< Box>
152
- < Avatar address= " eip155:1:0x1234567890123456789012345678901234567890" / >
156
+ < Avatar address= " eip155:1:0x1234567890123456789012345678901234567890" size = " lg " / >
153
157
< Avatar address= " bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6" / >
154
158
< / Box>
155
159
),
156
160
};
157
161
};
158
162
` ` `
159
163
164
+ ### ` Banner`
165
+
166
+ Outputs a banner that can be used to display important messages with different severity levels.
167
+
168
+ #### Props
169
+
170
+ - ` title` : ` string` - The title of the banner.
171
+ - ` severity` - The severity level of the banner.
172
+ Possible values are ` " danger" ` , ` " info" ` , ` " success" ` , and ` " warning" ` .
173
+ - ` children` - The content to display in the banner.
174
+ This can include [` Text ` ](#text), [` Link` ](#link) [` Icon` ](#icon), [` Button` ](#button), and [` Skeleton` ](#skeleton) components.
175
+
176
+ #### Example
177
+
178
+ ` ` ` javascript title= " index.jsx"
179
+ import { Box , Banner , Text , Link } from " @metamask/snaps-sdk/jsx" ;
180
+
181
+ await snap .request ({
182
+ method: " snap_dialog" ,
183
+ params: {
184
+ type: " alert" ,
185
+ content: (
186
+ < Box>
187
+ < Banner title= " Important Update" severity= " info" >
188
+ < Text > A new version is available! < / Text >
189
+ < Link href= " https://docs.metamask.io" > Learn more< / Link>
190
+ < / Banner>
191
+
192
+ < Banner title= " Warning" severity= " warning" >
193
+ < Text > Please review transaction details carefully.< / Text >
194
+ < / Banner>
195
+
196
+ < Banner title= " Success" severity= " success" >
197
+ < Text > Transaction completed successfully.< / Text >
198
+ < / Banner>
199
+
200
+ < Banner title= " Error" severity= " danger" >
201
+ < Text > Unable to process transaction.< / Text >
202
+ < / Banner>
203
+ < / Box>
204
+ ),
205
+ },
206
+ });
207
+ ` ` `
208
+
160
209
### ` Bold`
161
210
162
211
Outputs bold text.
@@ -194,6 +243,8 @@ Outputs a box, which can be used as a container for other components.
194
243
- ` alignment` - (Optional) The alignment of the elements inside the box.
195
244
Possible values are ` " start" ` , ` " center" ` , ` " end" ` , ` " space-between" ` , and ` " space-around" ` .
196
245
The default is ` " start" ` .
246
+ - ` center` : ` boolean` - (Optional) Whether to center the children within the box.
247
+ The default is ` false ` .
197
248
198
249
#### Example
199
250
@@ -208,6 +259,7 @@ module.exports.onHomePage = async () => {
208
259
< Box
209
260
direction= " horizontal"
210
261
alignment= " space-around"
262
+ center= " true"
211
263
>
212
264
< Text > Feature 1 < / Text >
213
265
< Text > Feature 2 < / Text >
@@ -343,8 +395,7 @@ Outputs a checkbox for use in [interactive UI](interactive-ui.md).
343
395
- ` name` : ` string` - The name sent to [` onUserInput` ](../../reference/entry-points.md#onuserinput).
344
396
- ` checked` : ` boolean` - (Optional) Whether the checkbox is checked.
345
397
- ` label` : ` string` - (Optional) The label for the checkbox.
346
- - ` variant` - (Optional) The variant of the checkbox.
347
- Possible values are ` " default" ` and ` " toggle" ` .
398
+ - ` variant` - (Optional) The variant of the checkbox. Possible values are ` " default" ` and ` " toggle" ` .
348
399
The default is ` " default" ` .
349
400
350
401
#### Example
@@ -369,6 +420,56 @@ const interfaceId = await snap.request({
369
420
<img src={require("../../assets/custom-ui-checkbox.png").default} alt="Checkbox UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
370
421
</p>
371
422
423
+ ### ` Container`
424
+
425
+ 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).
426
+
427
+ #### Props
428
+
429
+ - ` backgroundColor` - (Optional) The background color of the container.
430
+ Possible values are ` " default" ` and ` " alternative" ` .
431
+ The default is ` " default" ` .
432
+ - ` children` : The contents of the container.
433
+ This can be a single [` Box` ](#box) component, or an array containing a [` Box` ](#box) component and a [` Footer` ](#footer) component.
434
+
435
+ #### Example
436
+
437
+ ` ` ` javascript title= " index.jsx"
438
+ import { Container , Box , Footer , Text , Button } from " @metamask/snaps-sdk/jsx" ;
439
+
440
+ await snap .request ({
441
+ method: " snap_dialog" ,
442
+ params: {
443
+ content: (
444
+ < Container backgroundColor= " default" >
445
+ < Box>
446
+ < Text > Are you sure you want to proceed with this transaction? < / Text >
447
+ < Text > Gas fees: 0.005 ETH < / Text >
448
+ < / Box>
449
+ < Footer>
450
+ < Button name= " cancel" variant= " destructive" > Cancel< / Button>
451
+ < Button name= " confirm" > Confirm< / Button>
452
+ < / Footer>
453
+ < / Container>
454
+ ),
455
+ },
456
+ });
457
+
458
+ // Example without footer
459
+ await snap .request ({
460
+ method: " snap_dialog" ,
461
+ params: {
462
+ content: (
463
+ < Container backgroundColor= " alternative" >
464
+ < Box>
465
+ < Text > Simple container without footer< / Text >
466
+ < / Box>
467
+ < / Container>
468
+ ),
469
+ },
470
+ });
471
+ ` ` `
472
+
372
473
### ` Copyable`
373
474
374
475
Outputs a read-only text field with a copy-to-clipboard shortcut.
@@ -576,6 +677,56 @@ export const onUserInput = async ({ id, event }) => {
576
677
<img src={require("../../assets/custom-ui-file-input.png").default} alt="File input UI example" width="450px" style={{border: "1px solid #DCDCDC"}} />
577
678
</p>
578
679
680
+ ### ` Footer`
681
+
682
+ 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.
683
+
684
+ #### Props
685
+
686
+ - ` children` - The contents of the footer.
687
+ This can be one or two [` Button` ](#button) components.
688
+
689
+ #### Example
690
+
691
+ ` ` ` javascript title= " index.jsx"
692
+ import { Container , Box , Footer , Text , Button } from " @metamask/snaps-sdk/jsx" ;
693
+
694
+ // Example with two buttons
695
+ await snap .request ({
696
+ method: " snap_dialog" ,
697
+ params: {
698
+ content: (
699
+ < Container>
700
+ < Box>
701
+ < Text > Delete this item? < / Text >
702
+ < / Box>
703
+ < Footer>
704
+ < Button name= " cancel" > Cancel< / Button>
705
+ < Button name= " delete" variant= " destructive" > Delete< / Button>
706
+ < / Footer>
707
+ < / Container>
708
+ ),
709
+ },
710
+ });
711
+
712
+ // Example with single button
713
+ await snap .request ({
714
+ method: " snap_dialog" ,
715
+ params: {
716
+ content: (
717
+ < Container>
718
+ < Box>
719
+ < Text > Operation completed successfully.< / Text >
720
+ < / Box>
721
+ < Footer>
722
+ < Button name= " close" > Close< / Button>
723
+ < / Footer>
724
+ < / Container>
725
+ ),
726
+ },
727
+ });
728
+ ` ` `
729
+
579
730
### ` Form`
580
731
581
732
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.
925
1076
Possible values are ` "default"` , ` "error"` , and ` "warning"` .
926
1077
The default is ` "default"` .
927
1078
- ` children` - The value of the row, which can be a [` Text` ](#text), [` Image` ](#image),
928
- [` Address` ](#address), or [` Link` ](#link) component.
1079
+ [` Address` ](#address), [` Link` ](#link), or [ ` Value ` ](#value ) component.
929
1080
930
1081
#### Example
931
1082
@@ -1025,9 +1176,39 @@ const interfaceId = await snap.request({
1025
1176
< img src= {require (" ../../assets/custom-ui-selector.png" ).default } alt= " Selector UI example" width= " 450px" / >
1026
1177
< / p>
1027
1178
1179
+ ### ` Skeleton`
1180
+
1181
+ Outputs an animated loading container.
1182
+
1183
+ #### Props
1184
+
1185
+ - ` width` : ` Array<number | string>` - (Optional) The width of the skeleton . The default is ` "100%"` .
1186
+ - ` height` : ` Array<number | string>` - (Optional) The height of the skeleton . The default is ` 22` .
1187
+ - ` borderRadius` : ` string` - (Optional) The radius of the corners . Possible values are ` "none"` , ` "medium"` or ` "full"` .
1188
+ The default is ` "medium"` .
1189
+
1190
+ #### Example
1191
+
1192
+ ` ` ` javascript title="index.jsx"
1193
+ import { Box, Heading, Skeleton } from "@metamask/snaps-sdk/jsx";
1194
+
1195
+ await snap.request({
1196
+ method: "snap_dialog",
1197
+ params: {
1198
+ type: "alert",
1199
+ content: (
1200
+ <Box>
1201
+ <Heading>Please wait...</Heading>
1202
+ <Skeleton height={32} width="50%" borderRadius="full" />
1203
+ </Box>
1204
+ ),
1205
+ },
1206
+ });
1207
+ ` ` `
1208
+
1028
1209
### ` Spinner`
1029
1210
1030
- Outputs a loading indicator.
1211
+ Outputs an animated loading indicator.
1031
1212
1032
1213
#### Example
1033
1214
@@ -1064,6 +1245,8 @@ Outputs text.
1064
1245
- ` alignment` - (Optional) The alignment of the text.
1065
1246
Possible values are ` "start"` , ` "center"` , and ` "end"` .
1066
1247
The default is ` "start"` .
1248
+ - ` children` - The content to display.
1249
+ This can include strings, and [` Bold` ](#bold), [` Italic` ](#italic), [` Icon` ](#icon), [` Link` ](#link), and [` Skeleton` ](#skeleton) components.
1067
1250
1068
1251
1069
1252
#### Example
@@ -1126,6 +1309,53 @@ await snap.request({
1126
1309
< img src= {require (" ../../assets/custom-ui-tooltip.png" ).default } alt= " Tooltip UI example" width= " 450px" style= {{border: " 1px solid #DCDCDC" }} / >
1127
1310
< / p>
1128
1311
1312
+ ### ` Value`
1313
+
1314
+ 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.
1315
+
1316
+ #### Props
1317
+
1318
+ - ` value` - The value shown on the right side.
1319
+ This can be a string or a [` Text` ](#text) component.
1320
+ - ` extra` - The extra text shown on the left side.
1321
+ This can be a string or a [` Text` ](#text) component.
1322
+
1323
+ #### Example
1324
+
1325
+ ` ` ` javascript title="index.jsx"
1326
+ import { Box, Row, Text, Value } from "@metamask/snaps-sdk/jsx";
1327
+
1328
+ await snap.request({
1329
+ method: "snap_dialog",
1330
+ params: {
1331
+ type: "alert",
1332
+ content: (
1333
+ <Box>
1334
+ <Row label="Transaction Amount">
1335
+ <Value value="0.05 ETH" extra="$200" />
1336
+ </Row>
1337
+
1338
+ {/* Example with styled text */}
1339
+ <Row label="Gas Fee">
1340
+ <Value
1341
+ value={<Text color="error">0.003 ETH</Text>}
1342
+ extra={<Text color="error">$12</Text>}
1343
+ />
1344
+ </Row>
1345
+
1346
+ {/* Example with different text colors */}
1347
+ <Row label="Balance After">
1348
+ <Value
1349
+ value={<Text color="success">1.25 ETH</Text>}
1350
+ extra={<Text color="muted">$2,500</Text>}
1351
+ />
1352
+ </Row>
1353
+ </Box>
1354
+ ),
1355
+ },
1356
+ });
1357
+ ` ` `
1358
+
1129
1359
## Emojis
1130
1360
1131
1361
Text - based components (such as [` Heading` ](#heading) and [` Text` ](#text)) accept emojis.
0 commit comments